diff --git a/fpga/lib/eth/example/S10DX_DK/fpga_10g/rtl/fpga_core.v b/fpga/lib/eth/example/S10DX_DK/fpga_10g/rtl/fpga_core.v index e81686f15..459d456da 100644 --- a/fpga/lib/eth/example/S10DX_DK/fpga_10g/rtl/fpga_core.v +++ b/fpga/lib/eth/example/S10DX_DK/fpga_10g/rtl/fpga_core.v @@ -504,10 +504,9 @@ axis_async_fifo #( .DROP_WHEN_FULL(1) ) max_rx_fifo ( - .async_rst(rst | qsfp1_mac_1_rx_rst), - // AXI input .s_clk(qsfp1_mac_1_rx_clk), + .s_rst(qsfp1_mac_1_rx_rst), .s_axis_tdata(qsfp1_mac_1_rx_axis_tdata), .s_axis_tkeep(qsfp1_mac_1_rx_axis_tkeep), .s_axis_tvalid(qsfp1_mac_1_rx_axis_tvalid), @@ -519,6 +518,7 @@ max_rx_fifo ( // AXI output .m_clk(clk), + .m_rst(rst), .m_axis_tdata(rx_axis_tdata), .m_axis_tkeep(rx_axis_tkeep), .m_axis_tvalid(rx_axis_tvalid), @@ -554,10 +554,9 @@ axis_async_fifo #( .DROP_WHEN_FULL(0) ) max_tx_fifo ( - .async_rst(rst | qsfp1_mac_1_tx_rst), - // AXI input .s_clk(clk), + .s_rst(rst), .s_axis_tdata(tx_axis_tdata), .s_axis_tkeep(tx_axis_tkeep), .s_axis_tvalid(tx_axis_tvalid), @@ -569,6 +568,7 @@ max_tx_fifo ( // AXI output .m_clk(qsfp1_mac_1_tx_clk), + .m_rst(qsfp1_mac_1_tx_rst), .m_axis_tdata(qsfp1_mac_1_tx_axis_tdata), .m_axis_tkeep(qsfp1_mac_1_tx_axis_tkeep), .m_axis_tvalid(qsfp1_mac_1_tx_axis_tvalid), diff --git a/fpga/lib/eth/example/S10MX_DK/fpga_10g/fpga.sdc b/fpga/lib/eth/example/S10MX_DK/fpga_10g/fpga.sdc index 162d219bc..13a74bd9b 100644 --- a/fpga/lib/eth/example/S10MX_DK/fpga_10g/fpga.sdc +++ b/fpga/lib/eth/example/S10MX_DK/fpga_10g/fpga.sdc @@ -94,6 +94,6 @@ constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_tx_rst_res constrain_sync_reset_inst "qsfp1_eth_xcvr_phy_quad|eth_xcvr_phy_4|phy_rx_rst_reset_sync_inst" # 10G MAC -constrain_eth_mac_fifo_inst "core_inst|eth_mac_10g_inst" +constrain_eth_mac_fifo_inst "core_inst|eth_mac_10g_fifo_inst" constrain_axis_async_fifo_inst "core_inst|eth_mac_10g_fifo_inst|rx_fifo|fifo_inst" constrain_axis_async_fifo_inst "core_inst|eth_mac_10g_fifo_inst|tx_fifo|fifo_inst" diff --git a/fpga/lib/eth/lib/axis/rtl/axis_async_fifo.v b/fpga/lib/eth/lib/axis/rtl/axis_async_fifo.v index 44e1ebb2b..e7e8aa270 100644 --- a/fpga/lib/eth/lib/axis/rtl/axis_async_fifo.v +++ b/fpga/lib/eth/lib/axis/rtl/axis_async_fifo.v @@ -78,15 +78,11 @@ module axis_async_fifo # parameter DROP_WHEN_FULL = 0 ) ( - /* - * Common asynchronous reset - */ - input wire async_rst, - /* * AXI input */ input wire s_clk, + input wire s_rst, input wire [DATA_WIDTH-1:0] s_axis_tdata, input wire [KEEP_WIDTH-1:0] s_axis_tkeep, input wire s_axis_tvalid, @@ -100,6 +96,7 @@ module axis_async_fifo # * AXI output */ input wire m_clk, + input wire m_rst, output wire [DATA_WIDTH-1:0] m_axis_tdata, output wire [KEEP_WIDTH-1:0] m_axis_tkeep, output wire m_axis_tvalid, @@ -214,9 +211,7 @@ reg mem_read_data_valid_reg = 1'b0; wire [WIDTH-1:0] s_axis; -(* SHREG_EXTRACT = "NO" *) reg [WIDTH-1:0] m_axis_pipe_reg[PIPELINE_OUTPUT-1:0]; -(* SHREG_EXTRACT = "NO" *) reg [PIPELINE_OUTPUT-1:0] m_axis_tvalid_pipe_reg = 1'b0; // full when first TWO MSBs do NOT match, but rest matches @@ -233,12 +228,18 @@ reg write; reg read; reg store_output; +reg s_frame_reg = 1'b0; +reg m_frame_reg = 1'b0; + reg drop_frame_reg = 1'b0; reg send_frame_reg = 1'b0; reg overflow_reg = 1'b0; reg bad_frame_reg = 1'b0; reg good_frame_reg = 1'b0; +reg m_drop_frame_reg = 1'b0; +reg m_terminate_frame_reg = 1'b0; + reg overflow_sync1_reg = 1'b0; reg overflow_sync2_reg = 1'b0; reg overflow_sync3_reg = 1'b0; @@ -263,14 +264,23 @@ generate if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -assign m_axis_tvalid = m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1]; +wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1]; -assign m_axis_tdata = m_axis_pipe_reg[PIPELINE_OUTPUT-1][DATA_WIDTH-1:0]; -assign m_axis_tkeep = KEEP_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -assign m_axis_tlast = LAST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][LAST_OFFSET] : 1'b1; -assign m_axis_tid = ID_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -assign m_axis_tdest = DEST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -assign m_axis_tuser = USER_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; +wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis_pipe_reg[PIPELINE_OUTPUT-1][DATA_WIDTH-1:0]; +wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][LAST_OFFSET] : 1'b1; +wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? m_axis_pipe_reg[PIPELINE_OUTPUT-1][USER_OFFSET +: USER_WIDTH] : {USER_WIDTH{1'b0}}; + +assign m_axis_tvalid = m_axis_tvalid_pipe; + +assign m_axis_tdata = m_axis_tdata_pipe; +assign m_axis_tkeep = m_axis_tkeep_pipe; +assign m_axis_tlast = (m_terminate_frame_reg ? 1'b1 : m_axis_tlast_pipe); +assign m_axis_tid = m_axis_tid_pipe; +assign m_axis_tdest = m_axis_tdest_pipe; +assign m_axis_tuser = (m_terminate_frame_reg ? USER_BAD_FRAME_VALUE : m_axis_tuser_pipe); assign s_status_overflow = overflow_reg; assign s_status_bad_frame = bad_frame_reg; @@ -281,30 +291,32 @@ assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; assign m_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; // reset synchronization -always @(posedge s_clk or posedge async_rst) begin - if (async_rst) begin +always @(posedge m_clk or posedge m_rst) begin + if (m_rst) begin s_rst_sync1_reg <= 1'b1; - s_rst_sync2_reg <= 1'b1; - s_rst_sync3_reg <= 1'b1; end else begin s_rst_sync1_reg <= 1'b0; - s_rst_sync2_reg <= s_rst_sync1_reg || m_rst_sync1_reg; - s_rst_sync3_reg <= s_rst_sync2_reg; end end -always @(posedge m_clk or posedge async_rst) begin - if (async_rst) begin +always @(posedge s_clk) begin + s_rst_sync2_reg <= s_rst_sync1_reg; + s_rst_sync3_reg <= s_rst_sync2_reg; +end + +always @(posedge s_clk or posedge s_rst) begin + if (s_rst) begin m_rst_sync1_reg <= 1'b1; - m_rst_sync2_reg <= 1'b1; - m_rst_sync3_reg <= 1'b1; end else begin m_rst_sync1_reg <= 1'b0; - m_rst_sync2_reg <= s_rst_sync1_reg || m_rst_sync1_reg; - m_rst_sync3_reg <= m_rst_sync2_reg; end end +always @(posedge m_clk) begin + m_rst_sync2_reg <= m_rst_sync1_reg; + m_rst_sync3_reg <= m_rst_sync2_reg; +end + // Write logic always @(posedge s_clk) begin overflow_reg <= 1'b0; @@ -321,14 +333,39 @@ always @(posedge s_clk) begin end end + if (s_axis_tready && s_axis_tvalid && LAST_ENABLE) begin + // track input frame status + s_frame_reg <= !s_axis_tlast; + end + + if (s_rst_sync3_reg && LAST_ENABLE) begin + // if sink side is reset during transfer, drop partial frame + if (s_frame_reg && !(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin + drop_frame_reg <= 1'b1; + end + if (s_axis_tready && s_axis_tvalid && !s_axis_tlast) begin + drop_frame_reg <= 1'b1; + end + end + if (s_axis_tready && s_axis_tvalid) begin // transfer in if (!FRAME_FIFO) begin // normal FIFO mode mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1); + if (drop_frame_reg && LAST_ENABLE) begin + // currently dropping frame + // (only for frame transfers interrupted by sink reset) + if (s_axis_tlast) begin + // end of frame, clear drop flag + drop_frame_reg <= 1'b0; + end + end else begin + // update pointers + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= wr_ptr_temp ^ (wr_ptr_temp >> 1); + end end else if ((full_cur && DROP_WHEN_FULL) || (full_wr && DROP_OVERSIZE_FRAME) || drop_frame_reg) begin // full, packet overflow, or currently dropping frame // drop frame @@ -403,6 +440,19 @@ always @(posedge s_clk) begin wr_ptr_update_valid_reg <= 1'b0; wr_ptr_update_reg <= 1'b0; + end + + if (s_rst) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_sync_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_cur_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_update_reg <= 1'b0; + + s_frame_reg <= 1'b0; drop_frame_reg <= 1'b0; send_frame_reg <= 1'b0; @@ -419,7 +469,7 @@ always @(posedge s_clk) begin wr_ptr_update_ack_sync1_reg <= wr_ptr_update_sync3_reg; wr_ptr_update_ack_sync2_reg <= wr_ptr_update_ack_sync1_reg; - if (s_rst_sync3_reg) begin + if (s_rst) begin rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_update_ack_sync1_reg <= 1'b0; @@ -438,7 +488,7 @@ always @(posedge m_clk) begin wr_ptr_update_sync2_reg <= wr_ptr_update_sync1_reg; wr_ptr_update_sync3_reg <= wr_ptr_update_sync2_reg; - if (m_rst_sync3_reg) begin + if (m_rst) begin wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; wr_ptr_update_sync1_reg <= 1'b0; @@ -453,7 +503,7 @@ always @(posedge s_clk) begin bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; - if (s_rst_sync3_reg) begin + if (s_rst) begin overflow_sync1_reg <= 1'b0; bad_frame_sync1_reg <= 1'b0; good_frame_sync1_reg <= 1'b0; @@ -471,7 +521,7 @@ always @(posedge m_clk) begin good_frame_sync3_reg <= good_frame_sync2_reg; good_frame_sync4_reg <= good_frame_sync3_reg; - if (m_rst_sync3_reg) begin + if (m_rst) begin overflow_sync2_reg <= 1'b0; overflow_sync3_reg <= 1'b0; overflow_sync4_reg <= 1'b0; @@ -491,6 +541,7 @@ always @(posedge m_clk) begin if (m_axis_tready) begin // output ready; invalidate stage m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1] <= 1'b0; + m_terminate_frame_reg <= 1'b0; end for (j = PIPELINE_OUTPUT-1; j > 0; j = j - 1) begin @@ -506,7 +557,7 @@ always @(posedge m_clk) begin // output ready or bubble in pipeline; read new data from FIFO m_axis_tvalid_pipe_reg[0] <= 1'b0; m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; - if (!empty) begin + if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg) begin // not empty, increment pointer m_axis_tvalid_pipe_reg[0] <= 1'b1; rd_ptr_temp = rd_ptr_reg + 1; @@ -515,10 +566,50 @@ always @(posedge m_clk) begin end end + if (m_axis_tvalid && LAST_ENABLE) begin + // track output frame status + if (m_axis_tlast && m_axis_tready) begin + m_frame_reg <= 1'b0; + end else begin + m_frame_reg <= 1'b1; + end + end + + if (m_drop_frame_reg && (m_axis_tready || !m_axis_tvalid_pipe) && LAST_ENABLE) begin + // terminate frame + // (only for frame transfers interrupted by source reset) + m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-1] <= 1'b1; + m_terminate_frame_reg <= 1'b1; + m_drop_frame_reg <= 1'b0; + end + + if (m_rst_sync3_reg && LAST_ENABLE) begin + // if source side is reset during transfer, drop partial frame + + // empty output pipeline, except for last stage + if (PIPELINE_OUTPUT > 1) begin + m_axis_tvalid_pipe_reg[PIPELINE_OUTPUT-2:0] <= 0; + end + + if (m_frame_reg && (!m_axis_tvalid || (m_axis_tvalid && !m_axis_tlast)) && + !(m_drop_frame_reg || m_terminate_frame_reg)) begin + // terminate frame + m_drop_frame_reg <= 1'b1; + end + end + if (m_rst_sync3_reg) begin rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + end + + if (m_rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; m_axis_tvalid_pipe_reg <= {PIPELINE_OUTPUT{1'b0}}; + m_frame_reg <= 1'b0; + m_drop_frame_reg <= 1'b0; + m_terminate_frame_reg <= 1'b0; end end diff --git a/fpga/lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v b/fpga/lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v index f4c8c8677..5fbce1bc2 100644 --- a/fpga/lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +++ b/fpga/lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v @@ -321,10 +321,9 @@ axis_async_fifo #( .DROP_WHEN_FULL(DROP_WHEN_FULL) ) fifo_inst ( - // Common reset - .async_rst(s_rst | m_rst), // AXI input .s_clk(s_clk), + .s_rst(s_rst), .s_axis_tdata(pre_fifo_axis_tdata), .s_axis_tkeep(pre_fifo_axis_tkeep), .s_axis_tvalid(pre_fifo_axis_tvalid), @@ -335,6 +334,7 @@ fifo_inst ( .s_axis_tuser(pre_fifo_axis_tuser), // AXI output .m_clk(m_clk), + .m_rst(m_rst), .m_axis_tdata(post_fifo_axis_tdata), .m_axis_tkeep(post_fifo_axis_tkeep), .m_axis_tvalid(post_fifo_axis_tvalid), diff --git a/fpga/lib/eth/lib/axis/rtl/axis_pipeline_fifo.v b/fpga/lib/eth/lib/axis/rtl/axis_pipeline_fifo.v index 46f958a50..c293f9bc9 100644 --- a/fpga/lib/eth/lib/axis/rtl/axis_pipeline_fifo.v +++ b/fpga/lib/eth/lib/axis/rtl/axis_pipeline_fifo.v @@ -83,7 +83,7 @@ module axis_pipeline_fifo # output wire [USER_WIDTH-1:0] m_axis_tuser ); -parameter FIFO_ADDR_WIDTH = LENGTH < 2 ? 3 : $clog2(LENGTH*4); +parameter FIFO_ADDR_WIDTH = LENGTH < 2 ? 3 : $clog2(LENGTH*4+1); generate diff --git a/fpga/lib/eth/lib/axis/syn/quartus/axis_async_fifo.sdc b/fpga/lib/eth/lib/axis/syn/quartus/axis_async_fifo.sdc index e3a569a4f..9de844537 100644 --- a/fpga/lib/eth/lib/axis/syn/quartus/axis_async_fifo.sdc +++ b/fpga/lib/eth/lib/axis/syn/quartus/axis_async_fifo.sdc @@ -26,12 +26,12 @@ proc constrain_axis_async_fifo_inst { inst } { # reset synchronization set_false_path -from * -to [get_registers "$inst|s_rst_sync*_reg $inst|m_rst_sync*_reg"] - if {[get_collection_size [get_registers -nowarn "$inst|s_rst_sync2_reg"]]} { - set_max_delay -from [get_registers "$inst|s_rst_sync2_reg"] -to [get_registers "$inst|s_rst_sync3_reg"] 8.000 + if {[get_collection_size [get_registers -nowarn "$inst|s_rst_sync1_reg"]]} { + set_max_delay -from [get_registers "$inst|s_rst_sync1_reg"] -to [get_registers "$inst|s_rst_sync2_reg"] 8.000 } - if {[get_collection_size [get_registers -nowarn "$inst|m_rst_sync2_reg"]]} { - set_max_delay -from [get_registers "$inst|m_rst_sync2_reg"] -to [get_registers "$inst|m_rst_sync3_reg"] 8.000 + if {[get_collection_size [get_registers -nowarn "$inst|m_rst_sync1_reg"]]} { + set_max_delay -from [get_registers "$inst|m_rst_sync1_reg"] -to [get_registers "$inst|m_rst_sync2_reg"] 8.000 } # pointer synchronization diff --git a/fpga/lib/eth/lib/axis/syn/quartus_pro/axis_async_fifo.sdc b/fpga/lib/eth/lib/axis/syn/quartus_pro/axis_async_fifo.sdc index a4aa8fb15..e718d7005 100644 --- a/fpga/lib/eth/lib/axis/syn/quartus_pro/axis_async_fifo.sdc +++ b/fpga/lib/eth/lib/axis/syn/quartus_pro/axis_async_fifo.sdc @@ -26,12 +26,12 @@ proc constrain_axis_async_fifo_inst { inst } { # reset synchronization set_false_path -from * -to [get_registers "$inst|s_rst_sync*_reg $inst|m_rst_sync*_reg"] - if {[get_collection_size [get_registers -nowarn "$inst|s_rst_sync2_reg"]]} { - set_data_delay -from [get_registers "$inst|s_rst_sync2_reg"] -to [get_registers "$inst|s_rst_sync3_reg"] -override -get_value_from_clock_period min_clock_period -value_multiplier 0.8 + if {[get_collection_size [get_registers -nowarn "$inst|s_rst_sync1_reg"]]} { + set_data_delay -from [get_registers "$inst|s_rst_sync1_reg"] -to [get_registers "$inst|s_rst_sync2_reg"] -override -get_value_from_clock_period min_clock_period -value_multiplier 0.8 } - if {[get_collection_size [get_registers -nowarn "$inst|m_rst_sync2_reg"]]} { - set_data_delay -from [get_registers "$inst|m_rst_sync2_reg"] -to [get_registers "$inst|m_rst_sync3_reg"] -override -get_value_from_clock_period min_clock_period -value_multiplier 0.8 + if {[get_collection_size [get_registers -nowarn "$inst|m_rst_sync1_reg"]]} { + set_data_delay -from [get_registers "$inst|m_rst_sync1_reg"] -to [get_registers "$inst|m_rst_sync2_reg"] -override -get_value_from_clock_period min_clock_period -value_multiplier 0.8 } # pointer synchronization diff --git a/fpga/lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl b/fpga/lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl index f6eb52e76..5e655f060 100644 --- a/fpga/lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl +++ b/fpga/lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl @@ -33,21 +33,34 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || set min_clk_period [expr $read_clk_period < $write_clk_period ? $read_clk_period : $write_clk_period] # reset synchronization - set reset_ffs [get_cells -quiet -hier -regexp ".*/(s|m)_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] + set reset_ffs [get_cells -quiet -hier -regexp ".*/s_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] if {[llength $reset_ffs]} { set_property ASYNC_REG TRUE $reset_ffs - set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}] + + # hunt down source + set dest [get_cells $fifo_inst/s_rst_sync2_reg_reg] + set dest_pins [get_pins -of_objects $dest -filter {REF_PIN_NAME == D}] + set net [get_nets -segments -of_objects $dest_pins] + set source_pins [get_pins -of_objects $net -filter {IS_LEAF && DIRECTION == OUT}] + set source [get_cells -of_objects $source_pins] + + set_max_delay -from $source -to $dest -datapath_only $read_clk_period } - if {[llength [get_cells -quiet $fifo_inst/s_rst_sync2_reg_reg]]} { - set_false_path -to [get_pins $fifo_inst/s_rst_sync2_reg_reg/D] - set_max_delay -from [get_cells $fifo_inst/s_rst_sync2_reg_reg] -to [get_cells $fifo_inst/s_rst_sync3_reg_reg] $min_clk_period - } + set reset_ffs [get_cells -quiet -hier -regexp ".*/m_rst_sync\[123\]_reg_reg" -filter "PARENT == $fifo_inst"] - if {[llength [get_cells -quiet $fifo_inst/m_rst_sync2_reg_reg]]} { - set_false_path -to [get_pins $fifo_inst/m_rst_sync2_reg_reg/D] - set_max_delay -from [get_cells $fifo_inst/m_rst_sync2_reg_reg] -to [get_cells $fifo_inst/m_rst_sync3_reg_reg] $min_clk_period + if {[llength $reset_ffs]} { + set_property ASYNC_REG TRUE $reset_ffs + + # hunt down source + set dest [get_cells $fifo_inst/m_rst_sync2_reg_reg] + set dest_pins [get_pins -of_objects $dest -filter {REF_PIN_NAME == D}] + set net [get_nets -segments -of_objects $dest_pins] + set source_pins [get_pins -of_objects $net -filter {IS_LEAF && DIRECTION == OUT}] + set source [get_cells -of_objects $source_pins] + + set_max_delay -from $source -to $dest -datapath_only $write_clk_period } # pointer synchronization diff --git a/fpga/lib/eth/lib/axis/tb/axis_async_fifo/test_axis_async_fifo.py b/fpga/lib/eth/lib/axis/tb/axis_async_fifo/test_axis_async_fifo.py index 847a7fa1a..a159eb38f 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_async_fifo/test_axis_async_fifo.py +++ b/fpga/lib/eth/lib/axis/tb/axis_async_fifo/test_axis_async_fifo.py @@ -46,11 +46,14 @@ class TB(object): self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) - cocotb.fork(Clock(dut.s_clk, 10, units="ns").start()) - cocotb.fork(Clock(dut.m_clk, 11, units="ns").start()) + s_clk = int(os.getenv("S_CLK", "10")) + m_clk = int(os.getenv("M_CLK", "11")) - self.source = AxiStreamSource(AxiStreamBus.from_prefix(dut, "s_axis"), dut.s_clk, dut.async_rst) - self.sink = AxiStreamSink(AxiStreamBus.from_prefix(dut, "m_axis"), dut.m_clk, dut.async_rst) + cocotb.fork(Clock(dut.s_clk, s_clk, units="ns").start()) + cocotb.fork(Clock(dut.m_clk, m_clk, units="ns").start()) + + self.source = AxiStreamSource(AxiStreamBus.from_prefix(dut, "s_axis"), dut.s_clk, dut.s_rst) + self.sink = AxiStreamSink(AxiStreamBus.from_prefix(dut, "m_axis"), dut.m_clk, dut.m_rst) def set_idle_generator(self, generator=None): if generator: @@ -61,16 +64,41 @@ class TB(object): self.sink.set_pause_generator(generator()) async def reset(self): - self.dut.async_rst.setimmediatevalue(0) + self.dut.m_rst.setimmediatevalue(0) + self.dut.s_rst.setimmediatevalue(0) for k in range(10): await RisingEdge(self.dut.s_clk) - self.dut.async_rst <= 1 + self.dut.m_rst <= 1 + self.dut.s_rst <= 1 for k in range(10): await RisingEdge(self.dut.s_clk) - self.dut.async_rst <= 0 + self.dut.m_rst <= 0 + self.dut.s_rst <= 0 for k in range(10): await RisingEdge(self.dut.s_clk) + async def reset_source(self): + self.dut.s_rst.setimmediatevalue(0) + for k in range(10): + await RisingEdge(self.dut.s_clk) + self.dut.s_rst <= 1 + for k in range(10): + await RisingEdge(self.dut.s_clk) + self.dut.s_rst <= 0 + for k in range(10): + await RisingEdge(self.dut.s_clk) + + async def reset_sink(self): + self.dut.m_rst.setimmediatevalue(0) + for k in range(10): + await RisingEdge(self.dut.m_clk) + self.dut.m_rst <= 1 + for k in range(10): + await RisingEdge(self.dut.m_clk) + self.dut.m_rst <= 0 + for k in range(10): + await RisingEdge(self.dut.m_clk) + async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, backpressure_inserter=None): @@ -187,7 +215,179 @@ async def run_test_init_sink_pause_reset(dut): for k in range(64): await RisingEdge(dut.s_clk) - assert tb.sink.empty() + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_init_sink_pause_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + tb.sink.pause = False + + for k in range(64): + await RisingEdge(dut.s_clk) + + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_init_sink_pause_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + tb.sink.pause = False + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_in_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + for k in range(64): + await RisingEdge(dut.s_clk) + + if int(os.getenv("PARAM_FRAME_FIFO")): + assert tb.sink.empty() + else: + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.empty() + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_in_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_out_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + await RisingEdge(dut.m_axis_tvalid) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + for k in range(64): + await RisingEdge(dut.s_clk) + + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_out_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + await RisingEdge(dut.m_axis_tvalid) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() await RisingEdge(dut.s_clk) await RisingEdge(dut.s_clk) @@ -291,7 +491,19 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_init_sink_pause_source_reset, + run_test_init_sink_pause_sink_reset, + run_test_shift_in_source_reset, + run_test_shift_in_sink_reset, + run_test_shift_out_source_reset, + run_test_shift_out_sink_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() @@ -307,10 +519,13 @@ tests_dir = os.path.dirname(__file__) rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +@pytest.mark.parametrize(("s_clk", "m_clk"), [(10, 10), (10, 11), (11, 10)]) @pytest.mark.parametrize(("frame_fifo", "drop_oversize_frame", "drop_bad_frame", "drop_when_full"), [(0, 0, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0), (1, 1, 1, 0)]) @pytest.mark.parametrize("data_width", [8, 16, 32, 64]) -def test_axis_async_fifo(request, data_width, frame_fifo, drop_oversize_frame, drop_bad_frame, drop_when_full): +def test_axis_async_fifo(request, data_width, frame_fifo, drop_oversize_frame, drop_bad_frame, + drop_when_full, s_clk, m_clk): + dut = "axis_async_fifo" module = os.path.splitext(os.path.basename(__file__))[0] toplevel = dut @@ -342,6 +557,9 @@ def test_axis_async_fifo(request, data_width, frame_fifo, drop_oversize_frame, d extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + extra_env['S_CLK'] = str(s_clk) + extra_env['M_CLK'] = str(m_clk) + sim_build = os.path.join(tests_dir, "sim_build", request.node.name.replace('[', '-').replace(']', '')) diff --git a/fpga/lib/eth/lib/axis/tb/axis_async_fifo_adapter/test_axis_async_fifo_adapter.py b/fpga/lib/eth/lib/axis/tb/axis_async_fifo_adapter/test_axis_async_fifo_adapter.py index 44c095360..521e86e84 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_async_fifo_adapter/test_axis_async_fifo_adapter.py +++ b/fpga/lib/eth/lib/axis/tb/axis_async_fifo_adapter/test_axis_async_fifo_adapter.py @@ -74,6 +74,28 @@ class TB(object): for k in range(10): await RisingEdge(self.dut.s_clk) + async def reset_source(self): + self.dut.s_rst.setimmediatevalue(0) + for k in range(10): + await RisingEdge(self.dut.s_clk) + self.dut.s_rst <= 1 + for k in range(10): + await RisingEdge(self.dut.s_clk) + self.dut.s_rst <= 0 + for k in range(10): + await RisingEdge(self.dut.s_clk) + + async def reset_sink(self): + self.dut.m_rst.setimmediatevalue(0) + for k in range(10): + await RisingEdge(self.dut.m_clk) + self.dut.m_rst <= 1 + for k in range(10): + await RisingEdge(self.dut.m_clk) + self.dut.m_rst <= 0 + for k in range(10): + await RisingEdge(self.dut.m_clk) + async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, backpressure_inserter=None): @@ -190,7 +212,179 @@ async def run_test_init_sink_pause_reset(dut): for k in range(64): await RisingEdge(dut.s_clk) - assert tb.sink.empty() + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_init_sink_pause_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + tb.sink.pause = False + + for k in range(64): + await RisingEdge(dut.s_clk) + + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_init_sink_pause_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + tb.sink.pause = False + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_in_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + for k in range(64): + await RisingEdge(dut.s_clk) + + if int(os.getenv("PARAM_FRAME_FIFO")): + assert tb.sink.empty() + else: + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.empty() + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_in_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_out_source_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + await RisingEdge(dut.m_axis_tvalid) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_source() + + for k in range(64): + await RisingEdge(dut.s_clk) + + rx_frame = await tb.sink.recv() + + assert rx_frame.tuser + + assert tb.sink.idle() + + await RisingEdge(dut.s_clk) + await RisingEdge(dut.s_clk) + + +async def run_test_shift_out_sink_reset(dut): + + tb = TB(dut) + + await tb.reset() + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 256)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + await RisingEdge(dut.m_axis_tvalid) + + for k in range(8): + await RisingEdge(dut.s_clk) + + await tb.reset_sink() + + for k in range(64): + await RisingEdge(dut.s_clk) + + assert tb.sink.idle() await RisingEdge(dut.s_clk) await RisingEdge(dut.s_clk) @@ -294,7 +488,19 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_init_sink_pause_source_reset, + run_test_init_sink_pause_sink_reset, + run_test_shift_in_source_reset, + run_test_shift_in_sink_reset, + run_test_shift_out_source_reset, + run_test_shift_out_sink_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/lib/axis/tb/axis_fifo/test_axis_fifo.py b/fpga/lib/eth/lib/axis/tb/axis_fifo/test_axis_fifo.py index 8dbc5f24f..88367b071 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_fifo/test_axis_fifo.py +++ b/fpga/lib/eth/lib/axis/tb/axis_fifo/test_axis_fifo.py @@ -290,7 +290,13 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/lib/axis/tb/axis_fifo_adapter/test_axis_fifo_adapter.py b/fpga/lib/eth/lib/axis/tb/axis_fifo_adapter/test_axis_fifo_adapter.py index a54bbcbb5..f69b502dc 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_fifo_adapter/test_axis_fifo_adapter.py +++ b/fpga/lib/eth/lib/axis/tb/axis_fifo_adapter/test_axis_fifo_adapter.py @@ -290,7 +290,13 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/lib/axis/tb/axis_frame_length_adjust_fifo/test_axis_frame_length_adjust_fifo.py b/fpga/lib/eth/lib/axis/tb/axis_frame_length_adjust_fifo/test_axis_frame_length_adjust_fifo.py index d497018b3..021ddf321 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_frame_length_adjust_fifo/test_axis_frame_length_adjust_fifo.py +++ b/fpga/lib/eth/lib/axis/tb/axis_frame_length_adjust_fifo/test_axis_frame_length_adjust_fifo.py @@ -273,7 +273,13 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/lib/axis/tb/axis_pipeline_fifo/test_axis_pipeline_fifo.py b/fpga/lib/eth/lib/axis/tb/axis_pipeline_fifo/test_axis_pipeline_fifo.py index bd088acec..080b07556 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_pipeline_fifo/test_axis_pipeline_fifo.py +++ b/fpga/lib/eth/lib/axis/tb/axis_pipeline_fifo/test_axis_pipeline_fifo.py @@ -131,6 +131,90 @@ async def run_test_tuser_assert(dut): await RisingEdge(dut.clk) +async def run_test_init_sink_pause(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.clk) + + tb.sink.pause = False + + rx_frame = await tb.sink.recv() + + assert rx_frame.tdata == test_data + assert not rx_frame.tuser + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_init_sink_pause_reset(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 32)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(64): + await RisingEdge(dut.clk) + + await tb.reset() + + tb.sink.pause = False + + for k in range(64): + await RisingEdge(dut.clk) + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_overflow(dut): + + tb = TB(dut) + + await tb.reset() + + tb.sink.pause = True + + test_data = bytearray(itertools.islice(itertools.cycle(range(256)), 2048)) + test_frame = AxiStreamFrame(test_data) + await tb.source.send(test_frame) + + for k in range(2048): + await RisingEdge(dut.clk) + + tb.sink.pause = False + + rx_frame = await tb.sink.recv() + + assert rx_frame.tdata == test_data + assert not rx_frame.tuser + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None): tb = TB(dut) @@ -196,7 +280,13 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/lib/axis/tb/axis_srl_fifo/test_axis_srl_fifo.py b/fpga/lib/eth/lib/axis/tb/axis_srl_fifo/test_axis_srl_fifo.py index 8bdc70671..dc03f2572 100644 --- a/fpga/lib/eth/lib/axis/tb/axis_srl_fifo/test_axis_srl_fifo.py +++ b/fpga/lib/eth/lib/axis/tb/axis_srl_fifo/test_axis_srl_fifo.py @@ -280,7 +280,13 @@ if cocotb.SIM_NAME: factory.add_option("backpressure_inserter", [None, cycle_pause]) factory.generate_tests() - for test in [run_test_tuser_assert, run_test_init_sink_pause, run_test_init_sink_pause_reset, run_test_overflow]: + for test in [ + run_test_tuser_assert, + run_test_init_sink_pause, + run_test_init_sink_pause_reset, + run_test_overflow + ]: + factory = TestFactory(test) factory.generate_tests() diff --git a/fpga/lib/eth/rtl/eth_mac_10g.v b/fpga/lib/eth/rtl/eth_mac_10g.v index 187389bce..800731c8e 100644 --- a/fpga/lib/eth/rtl/eth_mac_10g.v +++ b/fpga/lib/eth/rtl/eth_mac_10g.v @@ -45,7 +45,7 @@ module eth_mac_10g # parameter TX_PTP_TAG_WIDTH = 16, parameter RX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_WIDTH = 96, - parameter TX_USER_WIDTH = (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1, parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1 ) ( diff --git a/fpga/lib/eth/rtl/eth_mac_10g_fifo.v b/fpga/lib/eth/rtl/eth_mac_10g_fifo.v index 966a2a73b..c61b47622 100644 --- a/fpga/lib/eth/rtl/eth_mac_10g_fifo.v +++ b/fpga/lib/eth/rtl/eth_mac_10g_fifo.v @@ -57,10 +57,11 @@ module eth_mac_10g_fifo # parameter TX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_ENABLE = 0, parameter TX_PTP_TS_FIFO_DEPTH = 64, - parameter RX_PTP_TS_FIFO_DEPTH = 64, parameter PTP_TS_WIDTH = 96, parameter TX_PTP_TAG_ENABLE = 0, - parameter PTP_TAG_WIDTH = 16 + parameter PTP_TAG_WIDTH = 16, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 ) ( input wire rx_clk, @@ -79,14 +80,7 @@ module eth_mac_10g_fifo # input wire tx_axis_tvalid, output wire tx_axis_tready, input wire tx_axis_tlast, - input wire tx_axis_tuser, - - /* - * Transmit timestamp tag input - */ - input wire [PTP_TAG_WIDTH-1:0] s_axis_tx_ptp_ts_tag, - input wire s_axis_tx_ptp_ts_valid, - output wire s_axis_tx_ptp_ts_ready, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * Transmit timestamp output @@ -104,14 +98,7 @@ module eth_mac_10g_fifo # output wire rx_axis_tvalid, input wire rx_axis_tready, output wire rx_axis_tlast, - output wire rx_axis_tuser, - - /* - * Receive timestamp output - */ - output wire [PTP_TS_WIDTH-1:0] m_axis_rx_ptp_ts_96, - output wire m_axis_rx_ptp_ts_valid, - input wire m_axis_rx_ptp_ts_ready, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * XGMII interface @@ -148,9 +135,6 @@ module eth_mac_10g_fifo # parameter KEEP_WIDTH = DATA_WIDTH/8; -localparam TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; -localparam RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; - wire [DATA_WIDTH-1:0] tx_fifo_axis_tdata; wire [KEEP_WIDTH-1:0] tx_fifo_axis_tkeep; wire tx_fifo_axis_tvalid; @@ -158,21 +142,12 @@ wire tx_fifo_axis_tready; wire tx_fifo_axis_tlast; wire [TX_USER_WIDTH-1:0] tx_fifo_axis_tuser; -wire [AXIS_DATA_WIDTH-1:0] tx_axis_tdata_int; -wire [AXIS_KEEP_WIDTH-1:0] tx_axis_tkeep_int; -wire tx_axis_tvalid_int; -wire tx_axis_tready_int; -wire tx_axis_tlast_int; -wire [TX_USER_WIDTH-1:0] tx_axis_tuser_int; - wire [DATA_WIDTH-1:0] rx_fifo_axis_tdata; wire [KEEP_WIDTH-1:0] rx_fifo_axis_tkeep; wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire [RX_USER_WIDTH-1:0] rx_fifo_axis_tuser; -wire [RX_USER_WIDTH-1:0] rx_axis_tuser_int; - wire [PTP_TS_WIDTH-1:0] tx_ptp_ts_96; wire [PTP_TS_WIDTH-1:0] rx_ptp_ts_96; @@ -180,9 +155,6 @@ wire [PTP_TS_WIDTH-1:0] tx_axis_ptp_ts_96; wire [PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; wire tx_axis_ptp_ts_valid; -wire [PTP_TS_WIDTH-1:0] rx_axis_ptp_ts_96; -wire rx_axis_ptp_ts_valid; - // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; @@ -269,146 +241,52 @@ if (TX_PTP_TS_ENABLE) begin .locked() ); - if (TX_PTP_TAG_ENABLE) begin + axis_async_fifo #( + .DEPTH(TX_PTP_TS_FIFO_DEPTH), + .DATA_WIDTH(PTP_TS_WIDTH), + .KEEP_ENABLE(0), + .LAST_ENABLE(0), + .ID_ENABLE(TX_PTP_TAG_ENABLE), + .ID_WIDTH(PTP_TAG_WIDTH), + .DEST_ENABLE(0), + .USER_ENABLE(0), + .FRAME_FIFO(0) + ) + tx_ptp_ts_fifo ( + .async_rst(logic_rst | tx_rst), - ptp_tag_insert #( - .DATA_WIDTH(AXIS_DATA_WIDTH), - .KEEP_WIDTH(AXIS_KEEP_WIDTH), - .TAG_WIDTH(PTP_TAG_WIDTH), - .TAG_OFFSET(1), - .USER_WIDTH(TX_USER_WIDTH) - ) - tx_ptp_tag_insert ( - .clk(logic_clk), - .rst(logic_rst), + // AXI input + .s_clk(tx_clk), + .s_axis_tdata(tx_axis_ptp_ts_96), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_ptp_ts_valid), + .s_axis_tready(), + .s_axis_tlast(0), + .s_axis_tid(tx_axis_ptp_ts_tag), + .s_axis_tdest(0), + .s_axis_tuser(0), - // AXI stream input - .s_axis_tdata(tx_axis_tdata), - .s_axis_tkeep(tx_axis_tkeep), - .s_axis_tvalid(tx_axis_tvalid), - .s_axis_tready(tx_axis_tready), - .s_axis_tlast(tx_axis_tlast), - .s_axis_tuser(tx_axis_tuser), + // AXI output + .m_clk(logic_clk), + .m_axis_tdata(m_axis_tx_ptp_ts_96), + .m_axis_tkeep(), + .m_axis_tvalid(m_axis_tx_ptp_ts_valid), + .m_axis_tready(m_axis_tx_ptp_ts_ready), + .m_axis_tlast(), + .m_axis_tid(m_axis_tx_ptp_ts_tag), + .m_axis_tdest(), + .m_axis_tuser(), - // AXI stream input - .m_axis_tdata(tx_axis_tdata_int), - .m_axis_tkeep(tx_axis_tkeep_int), - .m_axis_tvalid(tx_axis_tvalid_int), - .m_axis_tready(tx_axis_tready_int), - .m_axis_tlast(tx_axis_tlast_int), - .m_axis_tuser(tx_axis_tuser_int), - - // Tag input - .s_axis_tag(s_axis_tx_ptp_ts_tag), - .s_axis_tag_valid(s_axis_tx_ptp_ts_valid), - .s_axis_tag_ready(s_axis_tx_ptp_ts_ready) - ); - - axis_async_fifo #( - .DEPTH(TX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TAG_WIDTH+PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - tx_ptp_ts_fifo ( - .async_rst(logic_rst | tx_rst), - - // AXI input - .s_clk(tx_clk), - .s_axis_tdata({tx_axis_ptp_ts_tag, tx_axis_ptp_ts_96}), - .s_axis_tkeep(0), - .s_axis_tvalid(tx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_clk(logic_clk), - .m_axis_tdata({m_axis_tx_ptp_ts_tag, m_axis_tx_ptp_ts_96}), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_tx_ptp_ts_valid), - .m_axis_tready(m_axis_tx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() - ); - - end else begin - - assign tx_axis_tdata_int = tx_axis_tdata; - assign tx_axis_tkeep_int = tx_axis_tkeep; - assign tx_axis_tvalid_int = tx_axis_tvalid; - assign tx_axis_tready = tx_axis_tready_int; - assign tx_axis_tlast_int = tx_axis_tlast; - assign tx_axis_tuser_int = tx_axis_tuser; - - axis_async_fifo #( - .DEPTH(TX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - tx_ptp_ts_fifo ( - .async_rst(logic_rst | tx_rst), - - // AXI input - .s_clk(tx_clk), - .s_axis_tdata(tx_axis_ptp_ts_96), - .s_axis_tkeep(0), - .s_axis_tvalid(tx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_clk(logic_clk), - .m_axis_tdata(m_axis_tx_ptp_ts_96), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_tx_ptp_ts_valid), - .m_axis_tready(m_axis_tx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() - ); - - assign s_axis_tx_ptp_ts_ready = 1'b0; - assign m_axis_tx_ptp_ts_tag = {PTP_TAG_WIDTH{1'b0}}; - - end + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() + ); end else begin - - assign s_axis_tx_ptp_ts_ready = 1'b0; assign m_axis_tx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; assign m_axis_tx_ptp_ts_tag = {PTP_TAG_WIDTH{1'b0}}; @@ -416,13 +294,6 @@ end else begin assign tx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; - assign tx_axis_tdata_int = tx_axis_tdata; - assign tx_axis_tkeep_int = tx_axis_tkeep; - assign tx_axis_tvalid_int = tx_axis_tvalid; - assign tx_axis_tready = tx_axis_tready_int; - assign tx_axis_tlast_int = tx_axis_tlast; - assign tx_axis_tuser_int = tx_axis_tuser; - end if (RX_PTP_TS_ENABLE) begin @@ -447,76 +318,12 @@ if (RX_PTP_TS_ENABLE) begin .locked() ); - axis_fifo #( - .DEPTH(RX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - rx_ptp_ts_fifo ( - .clk(logic_clk), - .rst(logic_rst), - - // AXI input - .s_axis_tdata(rx_axis_ptp_ts_96), - .s_axis_tkeep(0), - .s_axis_tvalid(rx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_axis_tdata(m_axis_rx_ptp_ts_96), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_rx_ptp_ts_valid), - .m_axis_tready(m_axis_rx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .status_overflow(), - .status_bad_frame(), - .status_good_frame() - ); - - ptp_ts_extract #( - .TS_WIDTH(PTP_TS_WIDTH), - .TS_OFFSET(1), - .USER_WIDTH(RX_USER_WIDTH) - ) - rx_ptp_ts_extract ( - .clk(logic_clk), - .rst(logic_rst), - - // AXI stream input - .s_axis_tvalid(rx_axis_tvalid && rx_axis_tready), - .s_axis_tlast(rx_axis_tlast), - .s_axis_tuser(rx_axis_tuser_int), - - // Timestamp output - .m_axis_ts(rx_axis_ptp_ts_96), - .m_axis_ts_valid(rx_axis_ptp_ts_valid) - ); - end else begin - assign m_axis_rx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; - assign m_axis_rx_ptp_ts_valid = 1'b0; - assign rx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; end -assign rx_axis_tuser = rx_axis_tuser_int[0]; - endgenerate eth_mac_10g #( @@ -585,8 +392,8 @@ axis_async_fifo_adapter #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .PIPELINE_OUTPUT(TX_FIFO_PIPELINE_OUTPUT), .USER_WIDTH(TX_USER_WIDTH), + .PIPELINE_OUTPUT(TX_FIFO_PIPELINE_OUTPUT), .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), @@ -598,14 +405,14 @@ tx_fifo ( // AXI input .s_clk(logic_clk), .s_rst(logic_rst), - .s_axis_tdata(tx_axis_tdata_int), - .s_axis_tkeep(tx_axis_tkeep_int), - .s_axis_tvalid(tx_axis_tvalid_int), - .s_axis_tready(tx_axis_tready_int), - .s_axis_tlast(tx_axis_tlast_int), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(tx_axis_tuser_int), + .s_axis_tuser(tx_axis_tuser), // AXI output .m_clk(tx_clk), .m_rst(tx_rst), @@ -637,8 +444,8 @@ axis_async_fifo_adapter #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .PIPELINE_OUTPUT(RX_FIFO_PIPELINE_OUTPUT), .USER_WIDTH(RX_USER_WIDTH), + .PIPELINE_OUTPUT(RX_FIFO_PIPELINE_OUTPUT), .FRAME_FIFO(RX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), @@ -668,7 +475,7 @@ rx_fifo ( .m_axis_tlast(rx_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(rx_axis_tuser_int), + .m_axis_tuser(rx_axis_tuser), // Status .s_status_overflow(), .s_status_bad_frame(), diff --git a/fpga/lib/eth/rtl/eth_mac_phy_10g_fifo.v b/fpga/lib/eth/rtl/eth_mac_phy_10g_fifo.v index b2e874d83..66182d888 100644 --- a/fpga/lib/eth/rtl/eth_mac_phy_10g_fifo.v +++ b/fpga/lib/eth/rtl/eth_mac_phy_10g_fifo.v @@ -65,10 +65,11 @@ module eth_mac_phy_10g_fifo # parameter TX_PTP_TS_ENABLE = 0, parameter RX_PTP_TS_ENABLE = 0, parameter TX_PTP_TS_FIFO_DEPTH = 64, - parameter RX_PTP_TS_FIFO_DEPTH = 64, parameter PTP_TS_WIDTH = 96, parameter TX_PTP_TAG_ENABLE = 0, - parameter PTP_TAG_WIDTH = 16 + parameter PTP_TAG_WIDTH = 16, + parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1, + parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 ) ( input wire rx_clk, @@ -87,14 +88,7 @@ module eth_mac_phy_10g_fifo # input wire tx_axis_tvalid, output wire tx_axis_tready, input wire tx_axis_tlast, - input wire tx_axis_tuser, - - /* - * Transmit timestamp tag input - */ - input wire [PTP_TAG_WIDTH-1:0] s_axis_tx_ptp_ts_tag, - input wire s_axis_tx_ptp_ts_valid, - output wire s_axis_tx_ptp_ts_ready, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, /* * Transmit timestamp output @@ -112,14 +106,7 @@ module eth_mac_phy_10g_fifo # output wire rx_axis_tvalid, input wire rx_axis_tready, output wire rx_axis_tlast, - output wire rx_axis_tuser, - - /* - * Receive timestamp output - */ - output wire [PTP_TS_WIDTH-1:0] m_axis_rx_ptp_ts_96, - output wire m_axis_rx_ptp_ts_valid, - input wire m_axis_rx_ptp_ts_ready, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, /* * SERDES interface @@ -162,9 +149,6 @@ module eth_mac_phy_10g_fifo # parameter KEEP_WIDTH = DATA_WIDTH/8; -localparam TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1; -localparam RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; - wire [DATA_WIDTH-1:0] tx_fifo_axis_tdata; wire [KEEP_WIDTH-1:0] tx_fifo_axis_tkeep; wire tx_fifo_axis_tvalid; @@ -172,21 +156,12 @@ wire tx_fifo_axis_tready; wire tx_fifo_axis_tlast; wire [TX_USER_WIDTH-1:0] tx_fifo_axis_tuser; -wire [AXIS_DATA_WIDTH-1:0] tx_axis_tdata_int; -wire [AXIS_KEEP_WIDTH-1:0] tx_axis_tkeep_int; -wire tx_axis_tvalid_int; -wire tx_axis_tready_int; -wire tx_axis_tlast_int; -wire [TX_USER_WIDTH-1:0] tx_axis_tuser_int; - wire [DATA_WIDTH-1:0] rx_fifo_axis_tdata; wire [KEEP_WIDTH-1:0] rx_fifo_axis_tkeep; wire rx_fifo_axis_tvalid; wire rx_fifo_axis_tlast; wire [RX_USER_WIDTH-1:0] rx_fifo_axis_tuser; -wire [RX_USER_WIDTH-1:0] rx_axis_tuser_int; - wire [PTP_TS_WIDTH-1:0] tx_ptp_ts_96; wire [PTP_TS_WIDTH-1:0] rx_ptp_ts_96; @@ -194,9 +169,6 @@ wire [PTP_TS_WIDTH-1:0] tx_axis_ptp_ts_96; wire [PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag; wire tx_axis_ptp_ts_valid; -wire [PTP_TS_WIDTH-1:0] rx_axis_ptp_ts_96; -wire rx_axis_ptp_ts_valid; - // synchronize MAC status signals into logic clock domain wire tx_error_underflow_int; @@ -286,146 +258,52 @@ if (TX_PTP_TS_ENABLE) begin .locked() ); - if (TX_PTP_TAG_ENABLE) begin + axis_async_fifo #( + .DEPTH(TX_PTP_TS_FIFO_DEPTH), + .DATA_WIDTH(PTP_TS_WIDTH), + .KEEP_ENABLE(0), + .LAST_ENABLE(0), + .ID_ENABLE(TX_PTP_TAG_ENABLE), + .ID_WIDTH(PTP_TAG_WIDTH), + .DEST_ENABLE(0), + .USER_ENABLE(0), + .FRAME_FIFO(0) + ) + tx_ptp_ts_fifo ( + .async_rst(logic_rst | tx_rst), - ptp_tag_insert #( - .DATA_WIDTH(AXIS_DATA_WIDTH), - .KEEP_WIDTH(AXIS_KEEP_WIDTH), - .TAG_WIDTH(PTP_TAG_WIDTH), - .TAG_OFFSET(1), - .USER_WIDTH(TX_USER_WIDTH) - ) - tx_ptp_tag_insert ( - .clk(logic_clk), - .rst(logic_rst), + // AXI input + .s_clk(tx_clk), + .s_axis_tdata(tx_axis_ptp_ts_96), + .s_axis_tkeep(0), + .s_axis_tvalid(tx_axis_ptp_ts_valid), + .s_axis_tready(), + .s_axis_tlast(0), + .s_axis_tid(tx_axis_ptp_ts_tag), + .s_axis_tdest(0), + .s_axis_tuser(0), - // AXI stream input - .s_axis_tdata(tx_axis_tdata), - .s_axis_tkeep(tx_axis_tkeep), - .s_axis_tvalid(tx_axis_tvalid), - .s_axis_tready(tx_axis_tready), - .s_axis_tlast(tx_axis_tlast), - .s_axis_tuser(tx_axis_tuser), + // AXI output + .m_clk(logic_clk), + .m_axis_tdata(m_axis_tx_ptp_ts_96), + .m_axis_tkeep(), + .m_axis_tvalid(m_axis_tx_ptp_ts_valid), + .m_axis_tready(m_axis_tx_ptp_ts_ready), + .m_axis_tlast(), + .m_axis_tid(m_axis_tx_ptp_ts_tag), + .m_axis_tdest(), + .m_axis_tuser(), - // AXI stream input - .m_axis_tdata(tx_axis_tdata_int), - .m_axis_tkeep(tx_axis_tkeep_int), - .m_axis_tvalid(tx_axis_tvalid_int), - .m_axis_tready(tx_axis_tready_int), - .m_axis_tlast(tx_axis_tlast_int), - .m_axis_tuser(tx_axis_tuser_int), - - // Tag input - .s_axis_tag(s_axis_tx_ptp_ts_tag), - .s_axis_tag_valid(s_axis_tx_ptp_ts_valid), - .s_axis_tag_ready(s_axis_tx_ptp_ts_ready) - ); - - axis_async_fifo #( - .DEPTH(TX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TAG_WIDTH+PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - tx_ptp_ts_fifo ( - .async_rst(logic_rst | tx_rst), - - // AXI input - .s_clk(tx_clk), - .s_axis_tdata({tx_axis_ptp_ts_tag, tx_axis_ptp_ts_96}), - .s_axis_tkeep(0), - .s_axis_tvalid(tx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_clk(logic_clk), - .m_axis_tdata({m_axis_tx_ptp_ts_tag, m_axis_tx_ptp_ts_96}), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_tx_ptp_ts_valid), - .m_axis_tready(m_axis_tx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() - ); - - end else begin - - assign tx_axis_tdata_int = tx_axis_tdata; - assign tx_axis_tkeep_int = tx_axis_tkeep; - assign tx_axis_tvalid_int = tx_axis_tvalid; - assign tx_axis_tready = tx_axis_tready_int; - assign tx_axis_tlast_int = tx_axis_tlast; - assign tx_axis_tuser_int = tx_axis_tuser; - - axis_async_fifo #( - .DEPTH(TX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - tx_ptp_ts_fifo ( - .async_rst(logic_rst | tx_rst), - - // AXI input - .s_clk(tx_clk), - .s_axis_tdata(tx_axis_ptp_ts_96), - .s_axis_tkeep(0), - .s_axis_tvalid(tx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_clk(logic_clk), - .m_axis_tdata(m_axis_tx_ptp_ts_96), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_tx_ptp_ts_valid), - .m_axis_tready(m_axis_tx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() - ); - - assign s_axis_tx_ptp_ts_ready = 1'b0; - assign m_axis_tx_ptp_ts_tag = {PTP_TAG_WIDTH{1'b0}}; - - end + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() + ); end else begin - - assign s_axis_tx_ptp_ts_ready = 1'b0; assign m_axis_tx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; assign m_axis_tx_ptp_ts_tag = {PTP_TAG_WIDTH{1'b0}}; @@ -433,13 +311,6 @@ end else begin assign tx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; - assign tx_axis_tdata_int = tx_axis_tdata; - assign tx_axis_tkeep_int = tx_axis_tkeep; - assign tx_axis_tvalid_int = tx_axis_tvalid; - assign tx_axis_tready = tx_axis_tready_int; - assign tx_axis_tlast_int = tx_axis_tlast; - assign tx_axis_tuser_int = tx_axis_tuser; - end if (RX_PTP_TS_ENABLE) begin @@ -464,76 +335,12 @@ if (RX_PTP_TS_ENABLE) begin .locked() ); - axis_fifo #( - .DEPTH(RX_PTP_TS_FIFO_DEPTH), - .DATA_WIDTH(PTP_TS_WIDTH), - .KEEP_ENABLE(0), - .LAST_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(0), - .FRAME_FIFO(0) - ) - rx_ptp_ts_fifo ( - .clk(logic_clk), - .rst(logic_rst), - - // AXI input - .s_axis_tdata(rx_axis_ptp_ts_96), - .s_axis_tkeep(0), - .s_axis_tvalid(rx_axis_ptp_ts_valid), - .s_axis_tready(), - .s_axis_tlast(0), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(0), - - // AXI output - .m_axis_tdata(m_axis_rx_ptp_ts_96), - .m_axis_tkeep(), - .m_axis_tvalid(m_axis_rx_ptp_ts_valid), - .m_axis_tready(m_axis_rx_ptp_ts_ready), - .m_axis_tlast(), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(), - - // Status - .status_overflow(), - .status_bad_frame(), - .status_good_frame() - ); - - ptp_ts_extract #( - .TS_WIDTH(PTP_TS_WIDTH), - .TS_OFFSET(1), - .USER_WIDTH(RX_USER_WIDTH) - ) - rx_ptp_ts_extract ( - .clk(logic_clk), - .rst(logic_rst), - - // AXI stream input - .s_axis_tvalid(rx_axis_tvalid && rx_axis_tready), - .s_axis_tlast(rx_axis_tlast), - .s_axis_tuser(rx_axis_tuser_int), - - // Timestamp output - .m_axis_ts(rx_axis_ptp_ts_96), - .m_axis_ts_valid(rx_axis_ptp_ts_valid) - ); - end else begin - assign m_axis_rx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; - assign m_axis_rx_ptp_ts_valid = 1'b0; - assign rx_ptp_ts_96 = {PTP_TS_WIDTH{1'b0}}; end -assign rx_axis_tuser = rx_axis_tuser_int[0]; - endgenerate eth_mac_phy_10g #( @@ -617,8 +424,8 @@ axis_async_fifo_adapter #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .PIPELINE_OUTPUT(TX_FIFO_PIPELINE_OUTPUT), .USER_WIDTH(TX_USER_WIDTH), + .PIPELINE_OUTPUT(TX_FIFO_PIPELINE_OUTPUT), .FRAME_FIFO(TX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), @@ -630,14 +437,14 @@ tx_fifo ( // AXI input .s_clk(logic_clk), .s_rst(logic_rst), - .s_axis_tdata(tx_axis_tdata_int), - .s_axis_tkeep(tx_axis_tkeep_int), - .s_axis_tvalid(tx_axis_tvalid_int), - .s_axis_tready(tx_axis_tready_int), - .s_axis_tlast(tx_axis_tlast_int), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), .s_axis_tid(0), .s_axis_tdest(0), - .s_axis_tuser(tx_axis_tuser_int), + .s_axis_tuser(tx_axis_tuser), // AXI output .m_clk(tx_clk), .m_rst(tx_rst), @@ -669,8 +476,8 @@ axis_async_fifo_adapter #( .ID_ENABLE(0), .DEST_ENABLE(0), .USER_ENABLE(1), - .PIPELINE_OUTPUT(RX_FIFO_PIPELINE_OUTPUT), .USER_WIDTH(RX_USER_WIDTH), + .PIPELINE_OUTPUT(RX_FIFO_PIPELINE_OUTPUT), .FRAME_FIFO(RX_FRAME_FIFO), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), @@ -700,7 +507,7 @@ rx_fifo ( .m_axis_tlast(rx_axis_tlast), .m_axis_tid(), .m_axis_tdest(), - .m_axis_tuser(rx_axis_tuser_int), + .m_axis_tuser(rx_axis_tuser), // Status .s_status_overflow(), .s_status_bad_frame(), diff --git a/fpga/lib/eth/tb/eth_mac_10g/test_eth_mac_10g.py b/fpga/lib/eth/tb/eth_mac_10g/test_eth_mac_10g.py index 1e0d043bb..208965013 100644 --- a/fpga/lib/eth/tb/eth_mac_10g/test_eth_mac_10g.py +++ b/fpga/lib/eth/tb/eth_mac_10g/test_eth_mac_10g.py @@ -268,7 +268,7 @@ def test_eth_mac_10g(request, data_width, enable_dic): parameters['TX_PTP_TAG_WIDTH'] = 16 parameters['RX_PTP_TS_ENABLE'] = 0 parameters['RX_PTP_TS_WIDTH'] = 96 - parameters['TX_USER_WIDTH'] = (parameters['TX_PTP_TAG_WIDTH'] if parameters['TX_PTP_TAG_ENABLE'] else 0) + 1 + parameters['TX_USER_WIDTH'] = (parameters['TX_PTP_TAG_WIDTH'] if parameters['TX_PTP_TS_ENABLE'] and parameters['TX_PTP_TAG_ENABLE'] else 0) + 1 parameters['RX_USER_WIDTH'] = (parameters['RX_PTP_TS_WIDTH'] if parameters['RX_PTP_TS_ENABLE'] else 0) + 1 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} diff --git a/fpga/lib/eth/tb/eth_mac_10g_fifo/Makefile b/fpga/lib/eth/tb/eth_mac_10g_fifo/Makefile index 9f6d2eb37..0e074f9f7 100644 --- a/fpga/lib/eth/tb/eth_mac_10g_fifo/Makefile +++ b/fpga/lib/eth/tb/eth_mac_10g_fifo/Makefile @@ -67,10 +67,13 @@ export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 export PARAM_TX_PTP_TS_ENABLE ?= 0 export PARAM_RX_PTP_TS_ENABLE ?= 0 export PARAM_TX_PTP_TS_FIFO_DEPTH ?= 64 -export PARAM_RX_PTP_TS_FIFO_DEPTH ?= 64 export PARAM_PTP_TS_WIDTH ?= 96 export PARAM_TX_PTP_TAG_ENABLE ?= 0 export PARAM_PTP_TAG_WIDTH ?= 16 +# export PARAM_TX_USER_WIDTH ?= (parameters['TX_PTP_TAG_WIDTH'] if parameters['TX_PTP_TAG_ENABLE'] else 0) + 1 +export PARAM_TX_USER_WIDTH ?= 1 +# export PARAM_RX_USER_WIDTH ?= (parameters['RX_PTP_TS_WIDTH'] if parameters['RX_PTP_TS_ENABLE'] else 0) + 1 +export PARAM_RX_USER_WIDTH ?= 1 ifeq ($(SIM), icarus) PLUSARGS += -fst @@ -101,10 +104,11 @@ ifeq ($(SIM), icarus) COMPILE_ARGS += -P $(TOPLEVEL).TX_PTP_TS_ENABLE=$(PARAM_TX_PTP_TS_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).RX_PTP_TS_ENABLE=$(PARAM_RX_PTP_TS_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).TX_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) - COMPILE_ARGS += -P $(TOPLEVEL).RX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_FIFO_DEPTH) COMPILE_ARGS += -P $(TOPLEVEL).PTP_TS_WIDTH=$(PARAM_PTP_TS_WIDTH) COMPILE_ARGS += -P $(TOPLEVEL).TX_PTP_TAG_ENABLE=$(PARAM_TX_PTP_TAG_ENABLE) COMPILE_ARGS += -P $(TOPLEVEL).PTP_TAG_WIDTH=$(PARAM_PTP_TAG_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).TX_USER_WIDTH=$(PARAM_TX_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RX_USER_WIDTH=$(PARAM_RX_USER_WIDTH) ifeq ($(WAVES), 1) VERILOG_SOURCES += iverilog_dump.v @@ -139,10 +143,11 @@ else ifeq ($(SIM), verilator) COMPILE_ARGS += -GTX_PTP_TS_ENABLE=$(PARAM_TX_PTP_TS_ENABLE) COMPILE_ARGS += -GRX_PTP_TS_ENABLE=$(PARAM_RX_PTP_TS_ENABLE) COMPILE_ARGS += -GTX_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) - COMPILE_ARGS += -GRX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_FIFO_DEPTH) COMPILE_ARGS += -GPTP_TS_WIDTH=$(PARAM_PTP_TS_WIDTH) COMPILE_ARGS += -GTX_PTP_TAG_ENABLE=$(PARAM_TX_PTP_TAG_ENABLE) COMPILE_ARGS += -GPTP_TAG_WIDTH=$(PARAM_PTP_TAG_WIDTH) + COMPILE_ARGS += -GTX_USER_WIDTH=$(PARAM_TX_USER_WIDTH) + COMPILE_ARGS += -GRX_USER_WIDTH=$(PARAM_RX_USER_WIDTH) ifeq ($(WAVES), 1) COMPILE_ARGS += --trace-fst diff --git a/fpga/lib/eth/tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py b/fpga/lib/eth/tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py index 52f23caf6..234f018ad 100644 --- a/fpga/lib/eth/tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py +++ b/fpga/lib/eth/tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py @@ -290,10 +290,11 @@ def test_eth_mac_10g_fifo(request, data_width, enable_dic): parameters['TX_PTP_TS_ENABLE'] = 0 parameters['RX_PTP_TS_ENABLE'] = 0 parameters['TX_PTP_TS_FIFO_DEPTH'] = 64 - parameters['RX_PTP_TS_FIFO_DEPTH'] = 64 parameters['PTP_TS_WIDTH'] = 96 parameters['TX_PTP_TAG_ENABLE'] = 0 parameters['PTP_TAG_WIDTH'] = 16 + parameters['TX_USER_WIDTH'] = (parameters['TX_PTP_TAG_WIDTH'] if parameters['TX_PTP_TS_ENABLE'] and parameters['TX_PTP_TAG_ENABLE'] else 0) + 1 + parameters['RX_USER_WIDTH'] = (parameters['RX_PTP_TS_WIDTH'] if parameters['RX_PTP_TS_ENABLE'] else 0) + 1 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} diff --git a/fpga/lib/eth/tox.ini b/fpga/lib/eth/tox.ini index 26cce4851..d60284378 100644 --- a/fpga/lib/eth/tox.ini +++ b/fpga/lib/eth/tox.ini @@ -27,7 +27,8 @@ commands = testpaths = tb example +norecursedirs = + lib addopts = --ignore-glob=tb/test_*.py - --ignore-glob=*lib* --import-mode importlib