diff --git a/library/data_offload/data_offload.v b/library/data_offload/data_offload.v index 9dbd45707..01d3816c5 100644 --- a/library/data_offload/data_offload.v +++ b/library/data_offload/data_offload.v @@ -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), diff --git a/library/data_offload/data_offload_constr.ttcl b/library/data_offload/data_offload_constr.ttcl index 7fcc807bc..47c5f717a 100644 --- a/library/data_offload/data_offload_constr.ttcl +++ b/library/data_offload/data_offload_constr.ttcl @@ -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,9 +15,23 @@ set_property ASYNC_REG TRUE \ ## For RX in case of BRAMs <: if { $tx_enable == 0 } { :> +<: if { $internal_cdc } { :> + set_false_path \ + -to [get_pins -hierarchical * -filter {NAME=~*/i_sync_wr_sync/cdc_sync_stage1_reg[*]/D}] +<: } :> + set_false_path \ - -to [get_pins -hierarchical * -filter {NAME=~*/i_sync_wr_sync/cdc_sync_stage1_reg[*]/D}] - + -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 } { :> set_false_path \ @@ -34,9 +49,12 @@ 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 } { :> set_false_path \ @@ -52,21 +70,9 @@ set_false_path \ <: } :> ## For external DDRx memory - + <: 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}] diff --git a/library/data_offload/data_offload_fsm.v b/library/data_offload/data_offload_fsm.v index 814ebfad7..adb241751 100644 --- a/library/data_offload/data_offload_fsm.v +++ b/library/data_offload/data_offload_fsm.v @@ -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 @@ -256,7 +257,7 @@ module data_offload_fsm #( end end end - + always @(posedge wr_clk) begin wr_ready_d <= wr_ready; 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 diff --git a/library/data_offload/data_offload_ip.tcl b/library/data_offload/data_offload_ip.tcl index ffa0048f0..661b5bace 100644 --- a/library/data_offload/data_offload_ip.tcl +++ b/library/data_offload/data_offload_ip.tcl @@ -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 diff --git a/projects/common/xilinx/data_offload_bd.tcl b/projects/common/xilinx/data_offload_bd.tcl index 052f34132..4b5519b4f 100644 --- a/projects/common/xilinx/data_offload_bd.tcl +++ b/projects/common/xilinx/data_offload_bd.tcl @@ -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} {