data_offload: Improve external synchronization
This commit adds a new synthesis option to the design, that controls whether an internal clock domain crossing will be generated. Disabling this option allows you to use a synchronization signal that is synchronized to the write clock domain externally, and possibly shared between multiple devices. The default value retains the old behavior. Signed-off-by: David Winter <david.winter@analog.com>main
parent
0372ce1821
commit
7423ecae14
|
@ -55,7 +55,8 @@ module data_offload #(
|
|||
parameter DST_RAW_DATA_EN = 1'b0, // TBD
|
||||
parameter DST_CYCLIC_EN = 1'b0, // 1'b1 - CYCLIC mode enabled; 1'b0 - CYCLIC mode disabled
|
||||
|
||||
parameter AUTO_BRINGUP = 1) (
|
||||
parameter AUTO_BRINGUP = 1,
|
||||
parameter SYNC_EXT_ADD_INTERNAL_CDC = 1) (
|
||||
|
||||
// AXI4 Slave for configuration
|
||||
|
||||
|
@ -215,8 +216,10 @@ module data_offload #(
|
|||
.WR_ADDRESS_WIDTH (SRC_ADDR_WIDTH),
|
||||
.WR_DATA_WIDTH (SRC_DATA_WIDTH),
|
||||
.RD_ADDRESS_WIDTH (DST_ADDR_WIDTH),
|
||||
.RD_DATA_WIDTH (DST_DATA_WIDTH))
|
||||
.RD_DATA_WIDTH (DST_DATA_WIDTH),
|
||||
.SYNC_EXT_ADD_INTERNAL_CDC (SYNC_EXT_ADD_INTERNAL_CDC ))
|
||||
i_data_offload_fsm (
|
||||
.up_clk (up_clk),
|
||||
.wr_clk (src_clk),
|
||||
.wr_resetn_in (src_rstn),
|
||||
.wr_resetn_out (fifo_src_resetn),
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<: setFileProcessingOrder late :>
|
||||
<: set mem_type [getBooleanValue "MEM_TYPE"] :>
|
||||
<: set tx_enable [getBooleanValue "TX_OR_RXN_PATH"] :>
|
||||
<: set internal_cdc [getBooleanValue "SYNC_EXT_ADD_INTERNAL_CDC"] :>
|
||||
|
||||
## for all synchronization registers from util_cdc modules
|
||||
set_property ASYNC_REG TRUE \
|
||||
|
@ -14,8 +15,22 @@ set_property ASYNC_REG TRUE \
|
|||
## For RX in case of BRAMs
|
||||
<: if { $tx_enable == 0 } { :>
|
||||
|
||||
set_false_path \
|
||||
<: if { $internal_cdc } { :>
|
||||
set_false_path \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_wr_sync/cdc_sync_stage1_reg[*]/D}]
|
||||
<: } :>
|
||||
|
||||
set_false_path \
|
||||
-from [get_cells -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/cdc_hold_reg[*]}] \
|
||||
-to [get_cells -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/out_data_reg[*]}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/in_toggle_d1_reg/C}] \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/i_sync_out/cdc_sync_stage1_reg[*]/D}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/out_toggle_d1_reg/C}] \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/i_sync_in/cdc_sync_stage1_reg[*]/D}]
|
||||
|
||||
<: if { !$mem_type } { :>
|
||||
|
||||
|
@ -34,8 +49,11 @@ set_false_path \
|
|||
## For TX in case of BRAMs
|
||||
<: if { $tx_enable == 1 } { :>
|
||||
|
||||
<: if { $internal_cdc } { :>
|
||||
set_false_path \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_rd_sync/cdc_sync_stage1_reg[*]/D}]
|
||||
<: } :>
|
||||
|
||||
|
||||
<: if { !$mem_type } { :>
|
||||
|
||||
|
@ -55,18 +73,6 @@ set_false_path \
|
|||
|
||||
<: if { $mem_type == 1 } { :>
|
||||
|
||||
set_false_path \
|
||||
-from [get_cells -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/cdc_hold_reg[*]}] \
|
||||
-to [get_cells -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/out_data_reg[*]}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/in_toggle_d1_reg/C}] \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/i_sync_out/cdc_sync_stage1_reg[*]/D}]
|
||||
|
||||
set_false_path \
|
||||
-from [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/out_toggle_d1_reg/C}] \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*/i_sync_src_transfer_length/i_sync_in/cdc_sync_stage1_reg[*]/D}]
|
||||
|
||||
set_false_path \
|
||||
-to [get_pins -hierarchical * -filter {NAME=~*i_ddr_calib_done_sync/cdc_sync_stage1_reg[0]/D}]
|
||||
|
||||
|
|
|
@ -44,7 +44,10 @@ module data_offload_fsm #(
|
|||
parameter WR_ADDRESS_WIDTH = 4,
|
||||
parameter WR_DATA_WIDTH = 128,
|
||||
parameter RD_ADDRESS_WIDTH = 4,
|
||||
parameter RD_DATA_WIDTH = 128)(
|
||||
parameter RD_DATA_WIDTH = 128,
|
||||
parameter SYNC_EXT_ADD_INTERNAL_CDC = 1) (
|
||||
|
||||
input up_clk,
|
||||
|
||||
// write control interface
|
||||
input wr_clk,
|
||||
|
@ -132,8 +135,6 @@ module data_offload_fsm #(
|
|||
wire rd_init_ack_s;
|
||||
wire [WR_ADDRESS_WIDTH-1:0] rd_wr_last_addr_s;
|
||||
wire [WR_DATA_WIDTH/8-1:0] rd_wr_last_tkeep_s;
|
||||
wire wr_sync_internal_s;
|
||||
wire rd_sync_internal_s;
|
||||
wire wr_sync_external_s;
|
||||
wire rd_sync_external_s;
|
||||
wire wr_oneshot;
|
||||
|
@ -171,7 +172,7 @@ module data_offload_fsm #(
|
|||
end
|
||||
end
|
||||
SOFTWARE: begin
|
||||
if (wr_sync_internal_s) begin
|
||||
if (sync_internal) begin
|
||||
wr_fsm_state <= WR_WRITE_TO_MEM;
|
||||
end
|
||||
end
|
||||
|
@ -315,7 +316,7 @@ module data_offload_fsm #(
|
|||
end
|
||||
end
|
||||
SOFTWARE: begin
|
||||
if (rd_sync_internal_s) begin
|
||||
if (sync_internal) begin
|
||||
rd_fsm_state <= RD_READ_FROM_MEM;
|
||||
end
|
||||
end
|
||||
|
@ -555,24 +556,27 @@ module data_offload_fsm #(
|
|||
end
|
||||
end
|
||||
|
||||
// When SYNC_EXT_ADD_INTERNAL_CDC is deasserted, one of these signals will end
|
||||
// up being synchronized to the "wrong" clock domain. This shouldn't matter
|
||||
// because the incorrectly synchronized signal is guarded by a synthesis constant.
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (2),
|
||||
.ASYNC_CLK (1))
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (SYNC_EXT_ADD_INTERNAL_CDC))
|
||||
i_sync_wr_sync (
|
||||
.in_bits ({ sync_internal, sync_external }),
|
||||
.in_bits ({ sync_external }),
|
||||
.out_clk (wr_clk),
|
||||
.out_resetn (1'b1),
|
||||
.out_bits ({ wr_sync_internal_s, wr_sync_external_s })
|
||||
.out_bits ({ wr_sync_external_s })
|
||||
);
|
||||
|
||||
sync_bits #(
|
||||
.NUM_OF_BITS (2),
|
||||
.ASYNC_CLK (1))
|
||||
.NUM_OF_BITS (1),
|
||||
.ASYNC_CLK (SYNC_EXT_ADD_INTERNAL_CDC))
|
||||
i_sync_rd_sync (
|
||||
.in_bits ({ sync_internal, sync_external }),
|
||||
.in_bits ({ sync_external }),
|
||||
.out_clk (rd_clk),
|
||||
.out_resetn (1'b1),
|
||||
.out_bits ({ rd_sync_internal_s, rd_sync_external_s })
|
||||
.out_bits ({ rd_sync_external_s })
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -105,6 +105,7 @@ foreach {k v} { \
|
|||
"SRC_RAW_DATA_EN" "false" \
|
||||
"DST_RAW_DATA_EN" "false" \
|
||||
"DST_CYCLIC_EN" "true" \
|
||||
"SYNC_EXT_ADD_INTERNAL_CDC" "true" \
|
||||
} { \
|
||||
set_property -dict [list \
|
||||
"value_format" "bool" \
|
||||
|
@ -229,6 +230,11 @@ set_property -dict [list \
|
|||
] [ipgui::get_guiparamspec -name "DST_CYCLIC_EN" -component $cc]
|
||||
set_property enablement_tcl_expr {$TX_OR_RXN_PATH == 1} [ipx::get_user_parameters DST_CYCLIC_EN -of_objects $cc]
|
||||
|
||||
ipgui::add_param -name "SYNC_EXT_ADD_INTERNAL_CDC" -component $cc -parent $features_group
|
||||
set_property -dict [list \
|
||||
"display_name" "Generate CDC Circuit for sync_ext" \
|
||||
] [ipgui::get_guiparamspec -name "SYNC_EXT_ADD_INTERNAL_CDC" -component $cc]
|
||||
|
||||
## Create and save the XGUI file
|
||||
ipx::create_xgui_files $cc
|
||||
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
|
||||
proc ad_data_offload_create {instance_name datapath_type mem_type mem_size source_dwidth destination_dwidth {ddr_data_width 0} {ddr_addr_width 0}} {
|
||||
proc ad_data_offload_create {instance_name
|
||||
datapath_type
|
||||
mem_type
|
||||
mem_size
|
||||
source_dwidth
|
||||
destination_dwidth
|
||||
{ddr_data_width 0}
|
||||
{ddr_addr_width 0}
|
||||
{shared_devclk 0}} {
|
||||
|
||||
global ad_hdl_dir
|
||||
global sys_cpu_resetn
|
||||
|
@ -44,6 +52,7 @@ proc ad_data_offload_create {instance_name datapath_type mem_type mem_size sourc
|
|||
DST_DATA_WIDTH $destination_dwidth \
|
||||
DST_ADDR_WIDTH $destination_awidth \
|
||||
DST_CYCLIC_EN $datapath_type \
|
||||
SYNC_EXT_ADD_INTERNAL_CDC [expr {!$shared_devclk}] \
|
||||
]
|
||||
|
||||
if {$mem_type == 0} {
|
||||
|
|
Loading…
Reference in New Issue