pluto_hdl_adi/library/axi_dmac/axi_dmac_constr.ttcl

198 lines
7.1 KiB
Plaintext
Raw Normal View History

<: set ComponentName [getComponentNameString] :>
<: setOutputDirectory "./" :>
<: setFileName [ttcl_add $ComponentName "_constr"] :>
<: setFileExtension ".xdc" :>
<: setFileProcessingOrder late :>
<: set async_dest_req [getBooleanValue "ASYNC_CLK_DEST_REQ"] :>
<: set async_req_src [getBooleanValue "ASYNC_CLK_REQ_SRC"] :>
<: set async_src_dest [getBooleanValue "ASYNC_CLK_SRC_DEST"] :>
<: set disable_debug_registers [getBooleanValue "DISABLE_DEBUG_REGISTERS"] :>
set req_clk [get_clocks -of_objects [get_ports s_axi_aclk]]
set src_clk [get_clocks -of_objects [get_ports -quiet {fifo_wr_clk s_axis_aclk m_src_axi_aclk}]]
set dest_clk [get_clocks -of_objects [get_ports -quiet {fifo_rd_clk m_axis_aclk m_dest_axi_aclk}]]
<: if {$async_req_src || $async_src_dest || $async_dest_req} { :>
set_property ASYNC_REG TRUE \
[get_cells -quiet -hier *cdc_sync_stage1_reg*] \
[get_cells -quiet -hier *cdc_sync_stage2_reg*]
<: } :>
<: if {$async_req_src} { :>
set_max_delay -quiet -datapath_only \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $req_clk]
set_false_path -quiet \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_status_src* && IS_SEQUENTIAL}]
set_false_path -quiet \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_control_src* && IS_SEQUENTIAL}]
set_max_delay -quiet -datapath_only \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_src_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $req_clk]
set_max_delay -quiet -datapath_only \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_src_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $src_clk]
set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_src_req_fifo* && IS_SEQUENTIAL}] \
-to $src_clk \
[get_property -min PERIOD $src_clk]
set_max_delay -quiet -datapath_only \
-from $req_clk \
-through [get_cells -quiet -hier DP \
-filter {NAME =~ *i_request_arb/eot_mem_reg*}] \
-to $src_clk \
[get_property -min PERIOD $src_clk]
<: } :>
<: if {$async_dest_req} { :>
set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_req_response_id* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]
set_false_path -quiet \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_status_dest* && IS_SEQUENTIAL}]
set_false_path -quiet \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_control_dest* && IS_SEQUENTIAL}]
set_max_delay -quiet -datapath_only \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $req_clk]
set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]
set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]
set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_response_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]
set_max_delay -quiet -datapath_only \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_response_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $req_clk]
set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_dest_response_fifo* && IS_SEQUENTIAL}] \
-to $req_clk \
[get_property -min PERIOD $req_clk]
set_max_delay -quiet -datapath_only \
-from $req_clk \
-through [get_cells -quiet -hier DP \
-filter {NAME =~ *i_request_arb/eot_mem_reg*}] \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]
<: } :>
<: if {$async_src_dest} { :>
set_max_delay -quiet -datapath_only \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_dest_request_id* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $src_clk]
set_max_delay -quiet -datapath_only \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_fifo/i_address_gray/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $src_clk]
set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_fifo/i_address_gray/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]
<: } :>
# Reset signals
set_false_path -quiet \
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
-from [get_cells -quiet -hier *do_reset_reg* \
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
-to [get_pins -quiet -hier *reset_async_reg*/PRE]
set_false_path -quiet \
-from [get_cells -quiet -hier *reset_async_reg[0] \
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *reset_async_reg[3]* \
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}]
set_false_path -quiet \
-from [get_cells -quiet -hier *reset_async_reg[0] \
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
-to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \
-filter {NAME =~ *i_reset_manager*}]
set_false_path -quiet \
-from [get_cells -quiet -hier *reset_sync_reg[0] \
-filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \
-to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \
-filter {NAME =~ *i_reset_manager*}]
set_property -dict { \
SHREG_EXTRACT NO \
ASYNC_REG TRUE \
} [get_cells -quiet -hier *reset_shift_reg*]
set_property -dict { \
SHREG_EXTRACT NO \
ASYNC_REG TRUE \
} [get_cells -quiet -hier *reset_sync_reg*]
# Ignore timing for debug signals to register map
<: if {!$disable_debug_registers} { :>
set_false_path -quiet \
-from [get_cells -quiet -hier *cdc_sync_stage2_reg* \
-filter {name =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
set_false_path -quiet \
-from [get_cells -quiet -hier *cdc_sync_stage2_reg* \
-filter {name =~ *i_sync_dest_request_id* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
set_false_path -quiet \
-from [get_cells -quiet -hier *id_reg* -filter {name =~ *i_request_arb* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
set_false_path -quiet \
-from [get_cells -quiet -hier *address_reg* -filter {name =~ *i_addr_gen* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
set_false_path -quiet \
-from [get_cells -quiet -hier *reset_sync_reg* -filter {name =~ *i_reset_manager* && IS_SEQUENTIAL}] \
-to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}]
<: } :>