diff --git a/src/eth/rtl/taxi_axis_baser_rx_32.sv b/src/eth/rtl/taxi_axis_baser_rx_32.sv index 64b6813..62ed2a7 100644 --- a/src/eth/rtl/taxi_axis_baser_rx_32.sv +++ b/src/eth/rtl/taxi_axis_baser_rx_32.sv @@ -20,69 +20,75 @@ module taxi_axis_baser_rx_32 # parameter DATA_W = 32, parameter HDR_W = 2, parameter logic GBX_IF_EN = 1'b0, + parameter GBX_CNT = 1, parameter logic USXGMII_EN = 1'b0, parameter logic PTP_TS_EN = 1'b0, - parameter PTP_TS_W = 96 + parameter PTP_TS_W = 96, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * 10GBASE-R encoded input */ - input wire logic [DATA_W-1:0] encoded_rx_data, - input wire logic encoded_rx_data_valid, - input wire logic [HDR_W-1:0] encoded_rx_hdr, - input wire logic encoded_rx_hdr_valid, + input wire logic [DATA_W-1:0] encoded_rx_data, + input wire logic encoded_rx_data_valid, + input wire logic [HDR_W-1:0] encoded_rx_hdr, + input wire logic encoded_rx_hdr_valid, + input wire logic [GBX_CNT-1:0] rx_gbx_sync = '0, /* * Receive interface (AXI stream) */ - taxi_axis_if.src m_axis_rx, + taxi_axis_if.src m_axis_rx, /* * Ordered sets */ - output wire logic [23:0] rx_os, - output wire logic rx_os_sig, - output wire logic rx_os_valid, - output wire logic rx_os_match, - output wire logic rx_idle_match, + output wire logic [23:0] rx_os, + output wire logic rx_os_sig, + output wire logic rx_os_valid, + output wire logic rx_os_match, + output wire logic rx_idle_match, /* * PTP */ - input wire logic [PTP_TS_W-1:0] ptp_ts, + input wire logic [PTP_TS_W-1:0] ptp_ts, + output wire logic [GBX_CNT-1:0] ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0, /* * Configuration */ - input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, - input wire logic cfg_rx_enable, - input wire logic cfg_rx_usxgmii_en = 1'b1, - input wire logic cfg_rx_usxgmii_5g = 1'b0, - input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011, + input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, + input wire logic cfg_rx_enable, + input wire logic cfg_rx_usxgmii_en = 1'b1, + input wire logic cfg_rx_usxgmii_5g = 1'b0, + input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011, /* * Status */ - output wire logic rx_start_packet, - output wire logic [2:0] stat_rx_byte, - output wire logic [15:0] stat_rx_pkt_len, - output wire logic stat_rx_pkt_fragment, - output wire logic stat_rx_pkt_jabber, - output wire logic stat_rx_pkt_ucast, - output wire logic stat_rx_pkt_mcast, - output wire logic stat_rx_pkt_bcast, - output wire logic stat_rx_pkt_vlan, - output wire logic stat_rx_pkt_good, - output wire logic stat_rx_pkt_bad, - output wire logic stat_rx_err_oversize, - output wire logic stat_rx_err_bad_fcs, - output wire logic stat_rx_err_bad_block, - output wire logic stat_rx_err_framing, - output wire logic stat_rx_err_preamble + output wire logic rx_start_packet, + output wire logic [2:0] stat_rx_byte, + output wire logic [15:0] stat_rx_pkt_len, + output wire logic stat_rx_pkt_fragment, + output wire logic stat_rx_pkt_jabber, + output wire logic stat_rx_pkt_ucast, + output wire logic stat_rx_pkt_mcast, + output wire logic stat_rx_pkt_bcast, + output wire logic stat_rx_pkt_vlan, + output wire logic stat_rx_pkt_good, + output wire logic stat_rx_pkt_bad, + output wire logic stat_rx_err_oversize, + output wire logic stat_rx_err_bad_fcs, + output wire logic stat_rx_err_bad_block, + output wire logic stat_rx_err_framing, + output wire logic stat_rx_err_preamble ); // extract parameters @@ -187,6 +193,8 @@ logic input_start_alt_reg = 1'b0; logic input_start_d0_reg = 1'b0; logic input_start_d1_reg = 1'b0; logic input_start_d2_reg = 1'b0; +logic input_start_int_reg = 1'b0; +logic input_start_lane_reg = 1'b0; logic [DATA_W-1:0] encoded_rx_data_reg = '0; logic [HDR_W-1:0] encoded_rx_hdr_reg = '0; @@ -250,6 +258,11 @@ assign crc_valid[2] = crc_state == ~32'hc622f71d; assign crc_valid[1] = crc_state == ~32'hb1c2a1a3; assign crc_valid[0] = crc_state == ~32'h9d6cdf7e; +logic [4+16-1:0] last_ts_reg = '0; +logic [4+16-1:0] ts_inc_reg = '0; +logic gbx_en_reg = 1'b0; +logic [GBX_CNT-1:0] rx_gbx_sync_reg = '0; + assign m_axis_rx.tdata = m_axis_rx_tdata_reg; assign m_axis_rx.tkeep = m_axis_rx_tkeep_reg; assign m_axis_rx.tstrb = m_axis_rx.tkeep; @@ -268,6 +281,8 @@ assign rx_os_valid = rx_os_valid_reg; assign rx_os_match = rx_os_match_reg[1]; assign rx_idle_match = rx_idle_match_reg[1]; +assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? rx_gbx_sync_reg : '0; + assign rx_start_packet = start_packet_reg; assign stat_rx_byte = stat_rx_byte_reg; @@ -610,6 +625,10 @@ always_ff @(posedge clk) begin input_valid_reg <= 1'b0; + if (start_packet_reg) begin + ptp_ts_out_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) + (GBX_IF_EN && gbx_en_reg && input_start_lane_reg ? PTP_TS_W'(ts_inc_reg >> 5) : '0) : '0); + end + if (!(GBX_IF_EN || USXGMII_EN) || input_valid_reg) begin term_lane_d0_reg <= term_lane_reg; @@ -648,17 +667,19 @@ always_ff @(posedge clk) begin input_valid_reg <= 1'b0; input_start_alt_reg <= 1'b0; + input_start_int_reg <= 1'b0; - if (input_start_d1_reg) begin - ptp_ts_out_reg <= ptp_ts; + if (input_start_int_reg) begin + input_start_lane_reg <= encoded_rx_hdr_valid_reg; if (!USXGMII_EN || !rep_en_reg) begin start_packet_reg <= 1'b1; end end - if (USXGMII_EN && rep_start_reg && !rep_stall_reg) begin - ptp_ts_out_reg <= ptp_ts; + if (USXGMII_EN && rep_start_reg && rep_cnt_reg == 0) begin + input_start_lane_reg <= encoded_rx_hdr_valid_reg; start_packet_reg <= 1'b1; + rep_start_reg <= 1'b0; end if (encoded_rx_hdr_valid_reg) begin @@ -721,6 +742,7 @@ always_ff @(posedge clk) begin input_data_d0_reg <= encoded_rx_data_reg; input_valid_reg <= 1'b1; input_start_d0_reg <= 1'b1; + input_start_int_reg <= 1'b1; framing_error_reg <= frame_reg; frame_reg <= 1'b1; end @@ -853,6 +875,7 @@ always_ff @(posedge clk) begin if (input_start_alt_reg) begin input_start_d0_reg <= 1'b1; + input_start_int_reg <= 1'b1; input_valid_reg <= 1'b1; end @@ -924,7 +947,7 @@ always_ff @(posedge clk) begin end end else if (rep_cnt_reg == 0) begin rep_en_reg <= 1'b1; - rep_start_reg <= input_start_d2_reg; + rep_start_reg <= input_start_d1_reg; if (cfg_rx_usxgmii_5g) begin case (cfg_rx_usxgmii_speed) 3'b000: rep_cnt_reg <= 499; // 10 Mbps @@ -932,7 +955,7 @@ always_ff @(posedge clk) begin 3'b010: rep_cnt_reg <= 4; // 1 Gbps 3'b100: begin rep_cnt_reg <= 1; // 2.5 Gbps - rep_start_reg <= input_start_d1_reg; + rep_start_reg <= input_start_int_reg; end default: begin // 5 Gbps @@ -949,7 +972,7 @@ always_ff @(posedge clk) begin 3'b100: rep_cnt_reg <= 3; // 2.5 Gbps 3'b101: begin rep_cnt_reg <= 1; // 5 Gbps - rep_start_reg <= input_start_d1_reg; + rep_start_reg <= input_start_int_reg; end default: begin // 10 Gbps @@ -973,6 +996,15 @@ always_ff @(posedge clk) begin end end + last_ts_reg <= (4+16)'(ptp_ts); + ts_inc_reg <= (4+16)'(ptp_ts) - last_ts_reg; + + if (rx_gbx_sync || !encoded_rx_data_valid) begin + gbx_en_reg <= 1'b1; + end + + rx_gbx_sync_reg <= rx_gbx_sync; + if (rst) begin state_reg <= STATE_IDLE; @@ -992,6 +1024,9 @@ always_ff @(posedge clk) begin start_packet_reg <= 1'b0; frame_reg <= 1'b0; + gbx_en_reg <= 1'b0; + rx_gbx_sync_reg <= '0; + stat_rx_byte_reg <= '0; stat_rx_pkt_len_reg <= '0; stat_rx_pkt_fragment_reg <= 1'b0; @@ -1012,6 +1047,8 @@ always_ff @(posedge clk) begin input_start_d0_reg <= 1'b0; input_start_d1_reg <= 1'b0; input_start_d2_reg <= 1'b0; + input_start_int_reg <= 1'b0; + input_start_lane_reg <= 1'b0; end end diff --git a/src/eth/rtl/taxi_axis_baser_rx_64.sv b/src/eth/rtl/taxi_axis_baser_rx_64.sv index 6a12d2e..6822577 100644 --- a/src/eth/rtl/taxi_axis_baser_rx_64.sv +++ b/src/eth/rtl/taxi_axis_baser_rx_64.sv @@ -20,70 +20,76 @@ module taxi_axis_baser_rx_64 # parameter DATA_W = 64, parameter HDR_W = 2, parameter logic GBX_IF_EN = 1'b0, + parameter GBX_CNT = 1, parameter logic USXGMII_EN = 1'b0, parameter logic PTP_TS_EN = 1'b0, parameter logic PTP_TS_FMT_TOD = 1'b1, - parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64 + parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * 10GBASE-R encoded input */ - input wire logic [DATA_W-1:0] encoded_rx_data, - input wire logic encoded_rx_data_valid, - input wire logic [HDR_W-1:0] encoded_rx_hdr, - input wire logic encoded_rx_hdr_valid, + input wire logic [DATA_W-1:0] encoded_rx_data, + input wire logic encoded_rx_data_valid, + input wire logic [HDR_W-1:0] encoded_rx_hdr, + input wire logic encoded_rx_hdr_valid, + input wire logic [GBX_CNT-1:0] rx_gbx_sync = '0, /* * Receive interface (AXI stream) */ - taxi_axis_if.src m_axis_rx, + taxi_axis_if.src m_axis_rx, /* * Ordered sets */ - output wire logic [23:0] rx_os, - output wire logic rx_os_sig, - output wire logic rx_os_valid, - output wire logic rx_os_match, - output wire logic rx_idle_match, + output wire logic [23:0] rx_os, + output wire logic rx_os_sig, + output wire logic rx_os_valid, + output wire logic rx_os_match, + output wire logic rx_idle_match, /* * PTP */ - input wire logic [PTP_TS_W-1:0] ptp_ts, + input wire logic [PTP_TS_W-1:0] ptp_ts, + output wire logic [GBX_CNT-1:0] ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0, /* * Configuration */ - input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, - input wire logic cfg_rx_enable, - input wire logic cfg_rx_usxgmii_en = 1'b1, - input wire logic cfg_rx_usxgmii_5g = 1'b0, - input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011, + input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, + input wire logic cfg_rx_enable, + input wire logic cfg_rx_usxgmii_en = 1'b1, + input wire logic cfg_rx_usxgmii_5g = 1'b0, + input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011, /* * Status */ - output wire logic [1:0] rx_start_packet, - output wire logic [3:0] stat_rx_byte, - output wire logic [15:0] stat_rx_pkt_len, - output wire logic stat_rx_pkt_fragment, - output wire logic stat_rx_pkt_jabber, - output wire logic stat_rx_pkt_ucast, - output wire logic stat_rx_pkt_mcast, - output wire logic stat_rx_pkt_bcast, - output wire logic stat_rx_pkt_vlan, - output wire logic stat_rx_pkt_good, - output wire logic stat_rx_pkt_bad, - output wire logic stat_rx_err_oversize, - output wire logic stat_rx_err_bad_fcs, - output wire logic stat_rx_err_bad_block, - output wire logic stat_rx_err_framing, - output wire logic stat_rx_err_preamble + output wire logic [1:0] rx_start_packet, + output wire logic [3:0] stat_rx_byte, + output wire logic [15:0] stat_rx_pkt_len, + output wire logic stat_rx_pkt_fragment, + output wire logic stat_rx_pkt_jabber, + output wire logic stat_rx_pkt_ucast, + output wire logic stat_rx_pkt_mcast, + output wire logic stat_rx_pkt_bcast, + output wire logic stat_rx_pkt_vlan, + output wire logic stat_rx_pkt_good, + output wire logic stat_rx_pkt_bad, + output wire logic stat_rx_err_oversize, + output wire logic stat_rx_err_bad_fcs, + output wire logic stat_rx_err_bad_block, + output wire logic stat_rx_err_framing, + output wire logic stat_rx_err_preamble ); // extract parameters @@ -179,6 +185,9 @@ logic input_start_swap_reg = 1'b0; logic input_start_d0_reg = 1'b0; logic input_start_d1_reg = 1'b0; +logic encoded_rx_data_valid_d0_reg = 1'b0; +logic [1:0] encoded_rx_start_remap_d0_reg = 2'b00; + logic frame_oversize_reg = 1'b0, frame_oversize_next; logic pre_ok_reg = 1'b0, pre_ok_next; logic [1:0] hdr_ptr_reg = '0, hdr_ptr_next; @@ -244,6 +253,8 @@ assign crc_valid[0] = crc_state_reg == ~32'h6b87b1ec; logic [4+16-1:0] last_ts_reg = '0; logic [4+16-1:0] ts_inc_reg = '0; +logic [4+16-1:0] ts_offs_reg = '0; +logic gbx_en_reg = 1'b0; assign m_axis_rx.tdata = m_axis_rx_tdata_reg; assign m_axis_rx.tkeep = m_axis_rx_tkeep_reg; @@ -320,6 +331,7 @@ if (USXGMII_EN) begin : usxgmii logic [3:0] encoded_rx_type_remap_reg = '0; logic encoded_rx_data_remap_valid_reg = 1'b0; logic [1:0] encoded_rx_start_remap_reg = '0; + logic [GBX_CNT-1:0] rx_gbx_sync_reg = '0; logic [8:0] rep_cnt_reg = '0; logic rep_stall_reg = 1'b0; @@ -333,8 +345,11 @@ if (USXGMII_EN) begin : usxgmii assign encoded_rx_data_remap_valid = encoded_rx_data_remap_valid_reg; assign encoded_rx_start_remap = encoded_rx_start_remap_reg; + assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? rx_gbx_sync_reg : '0; + always_ff @(posedge clk) begin encoded_rx_data_remap_valid_reg <= 1'b0; + rx_gbx_sync_reg <= rx_gbx_sync; if (!GBX_IF_EN || encoded_rx_data_valid) begin @@ -543,6 +558,8 @@ if (USXGMII_EN) begin : usxgmii encoded_rx_data_remap_valid_reg <= 1'b0; encoded_rx_start_remap_reg <= '0; + rx_gbx_sync_reg <= '0; + rep_cnt_reg <= '0; rep_stall_reg <= 1'b0; rep_en_reg <= 1'b0; @@ -559,6 +576,8 @@ end else begin assign encoded_rx_start_remap[0] = encoded_rx_hdr[0] == SYNC_CTRL[0] && encoded_rx_data[7:4] == BLOCK_TYPE_START_0[7:4]; assign encoded_rx_start_remap[1] = encoded_rx_hdr[0] == SYNC_CTRL[0] && (encoded_rx_data[7:4] == BLOCK_TYPE_START_4[7:4] || encoded_rx_data[7:4] == BLOCK_TYPE_OS_START[7:4]); + assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? rx_gbx_sync : '0; + end // FCS verification @@ -866,24 +885,27 @@ always_ff @(posedge clk) begin stat_rx_err_framing_reg <= stat_rx_err_framing_next; stat_rx_err_preamble_reg <= stat_rx_err_preamble_next; - if (!GBX_IF_EN || encoded_rx_data_valid) begin + encoded_rx_data_valid_d0_reg <= encoded_rx_data_valid; + encoded_rx_start_remap_d0_reg <= encoded_rx_start_remap; + + if (!GBX_IF_EN || encoded_rx_data_valid_d0_reg) begin // capture timestamps - if (encoded_rx_start_remap[1]) begin + if (encoded_rx_start_remap_d0_reg[1]) begin start_packet_reg <= 2'b10; if (PTP_TS_FMT_TOD) begin // workaround for verilator lint bug: unreachable by parameter value /* verilator lint_off SELRANGE */ - ptp_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1); + ptp_ts_reg[45:0] <= ptp_ts[45:0] + (GBX_IF_EN ? 46'(ts_offs_reg) : 46'(ts_inc_reg >> 1)) + (PTP_TS_COR_EN ? 46'(ptp_ts_cor_val) : '0); ptp_ts_reg[95:48] <= ptp_ts[95:48]; /* verilator lint_on SELRANGE */ end else begin - ptp_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1); + ptp_ts_reg <= ptp_ts + (GBX_IF_EN ? PTP_TS_W'(ts_offs_reg) : PTP_TS_W'(ts_inc_reg >> 1)) + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) : '0); end end - if (encoded_rx_start_remap[0]) begin + if (encoded_rx_start_remap_d0_reg[0]) begin start_packet_reg <= 2'b01; - ptp_ts_reg <= ptp_ts; + ptp_ts_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) : '0); end end @@ -1168,6 +1190,11 @@ always_ff @(posedge clk) begin last_ts_reg <= (4+16)'(ptp_ts); ts_inc_reg <= (4+16)'(ptp_ts) - last_ts_reg; + ts_offs_reg <= (ts_inc_reg >> 1) + (gbx_en_reg ? ts_inc_reg >> 6 : '0); + + if (rx_gbx_sync || !encoded_rx_data_valid) begin + gbx_en_reg <= 1'b1; + end if (rst) begin state_reg <= STATE_IDLE; @@ -1181,6 +1208,8 @@ always_ff @(posedge clk) begin start_packet_reg <= 2'b00; frame_reg <= 1'b0; + gbx_en_reg <= 1'b0; + stat_rx_byte_reg <= '0; stat_rx_pkt_len_reg <= '0; stat_rx_pkt_fragment_reg <= 1'b0; @@ -1201,6 +1230,9 @@ always_ff @(posedge clk) begin input_start_d0_reg <= 1'b0; input_start_d1_reg <= 1'b0; + encoded_rx_data_valid_d0_reg <= 1'b0; + encoded_rx_start_remap_d0_reg <= 2'b00; + lanes_swapped_reg <= 1'b0; lanes_swapped_d1_reg <= 1'b0; end diff --git a/src/eth/rtl/taxi_eth_mac_phy_10g.sv b/src/eth/rtl/taxi_eth_mac_phy_10g.sv index 7a3407d..66fbd16 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g.sv @@ -80,6 +80,7 @@ module taxi_eth_mac_phy_10g # input wire logic serdes_rx_data_valid = 1'b1, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid = 1'b1, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -559,6 +560,7 @@ eth_mac_phy_10g_rx_inst ( .serdes_rx_hdr_valid(serdes_rx_hdr_valid), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), /* * Ordered sets diff --git a/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv b/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv index 6bda8c1..13af4c1 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv @@ -93,6 +93,7 @@ module taxi_eth_mac_phy_10g_fifo # input wire logic serdes_rx_data_valid = 1'b1, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid = 1'b1, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -386,6 +387,7 @@ eth_mac_phy_10g_inst ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), diff --git a/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv b/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv index 9e77242..4abb602 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv @@ -50,6 +50,7 @@ module taxi_eth_mac_phy_10g_rx # input wire logic serdes_rx_data_valid = 1'b1, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid = 1'b1, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -109,6 +110,8 @@ wire encoded_rx_data_valid; wire [HDR_W-1:0] encoded_rx_hdr; wire encoded_rx_hdr_valid; +wire rx_gbx_sync; + taxi_eth_phy_10g_rx_if #( .DATA_W(DATA_W), .HDR_W(HDR_W), @@ -132,6 +135,7 @@ eth_phy_10g_rx_if_inst ( .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync), /* * SERDES interface @@ -140,6 +144,7 @@ eth_phy_10g_rx_if_inst ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), @@ -165,10 +170,13 @@ if (DATA_W == 64) begin .DATA_W(DATA_W), .HDR_W(HDR_W), .GBX_IF_EN(GBX_IF_EN), + .GBX_CNT(1), .USXGMII_EN(USXGMII_EN), .PTP_TS_EN(PTP_TS_EN), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), - .PTP_TS_W(PTP_TS_W) + .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W) ) axis_baser_rx_inst ( .clk(clk), @@ -181,6 +189,7 @@ if (DATA_W == 64) begin .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync), /* * Receive interface (AXI stream) @@ -200,6 +209,8 @@ if (DATA_W == 64) begin * PTP */ .ptp_ts(ptp_ts), + .ptp_ts_cor_sync(ptp_ts_cor_sync), + .ptp_ts_cor_val(ptp_ts_cor_val), /* * Configuration @@ -237,9 +248,12 @@ end else begin .DATA_W(DATA_W), .HDR_W(HDR_W), .GBX_IF_EN(GBX_IF_EN), + .GBX_CNT(1), .USXGMII_EN(USXGMII_EN), .PTP_TS_EN(PTP_TS_EN), - .PTP_TS_W(PTP_TS_W) + .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W) ) axis_baser_rx_inst ( .clk(clk), @@ -252,6 +266,7 @@ end else begin .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync), /* * Receive interface (AXI stream) @@ -271,6 +286,8 @@ end else begin * PTP */ .ptp_ts(ptp_ts), + .ptp_ts_cor_sync(ptp_ts_cor_sync), + .ptp_ts_cor_val(ptp_ts_cor_val), /* * Configuration diff --git a/src/eth/rtl/taxi_eth_phy_10g.sv b/src/eth/rtl/taxi_eth_phy_10g.sv index 3267406..582db7f 100644 --- a/src/eth/rtl/taxi_eth_phy_10g.sv +++ b/src/eth/rtl/taxi_eth_phy_10g.sv @@ -49,6 +49,7 @@ module taxi_eth_phy_10g # output wire logic tx_gbx_req_sync, output wire logic tx_gbx_req_stall, input wire logic tx_gbx_sync = 1'b0, + output wire logic rx_gbx_sync, /* * SERDES interface @@ -64,6 +65,7 @@ module taxi_eth_phy_10g # input wire logic serdes_rx_data_valid = 1'b1, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid = 1'b1, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -108,6 +110,7 @@ eth_phy_10g_rx_inst ( .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), .xgmii_rx_valid(xgmii_rx_valid), + .rx_gbx_sync(rx_gbx_sync), /* * SERDES interface @@ -116,6 +119,7 @@ eth_phy_10g_rx_inst ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), diff --git a/src/eth/rtl/taxi_eth_phy_10g_rx.sv b/src/eth/rtl/taxi_eth_phy_10g_rx.sv index 9fae271..170dd58 100644 --- a/src/eth/rtl/taxi_eth_phy_10g_rx.sv +++ b/src/eth/rtl/taxi_eth_phy_10g_rx.sv @@ -39,6 +39,7 @@ module taxi_eth_phy_10g_rx # output wire logic [DATA_W-1:0] xgmii_rxd, output wire logic [CTRL_W-1:0] xgmii_rxc, output wire logic xgmii_rx_valid, + output wire logic rx_gbx_sync, /* * SERDES interface @@ -47,6 +48,7 @@ module taxi_eth_phy_10g_rx # input wire logic serdes_rx_data_valid = 1'b1, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid = 1'b1, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -71,6 +73,8 @@ wire encoded_rx_data_valid; wire [HDR_W-1:0] encoded_rx_hdr; wire encoded_rx_hdr_valid; +wire rx_gbx_sync_int; + taxi_eth_phy_10g_rx_if #( .DATA_W(DATA_W), .HDR_W(HDR_W), @@ -94,6 +98,7 @@ eth_phy_10g_rx_if_inst ( .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync_int), /* * SERDES interface @@ -102,6 +107,7 @@ eth_phy_10g_rx_if_inst ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), @@ -138,6 +144,7 @@ xgmii_baser_dec_inst ( .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync_in(rx_gbx_sync_int), /* * XGMII interface @@ -145,6 +152,7 @@ xgmii_baser_dec_inst ( .xgmii_rxd(xgmii_rxd), .xgmii_rxc(xgmii_rxc), .xgmii_rx_valid(xgmii_rx_valid), + .rx_gbx_sync_out(rx_gbx_sync), /* * Ordered sets diff --git a/src/eth/rtl/taxi_eth_phy_10g_rx_if.sv b/src/eth/rtl/taxi_eth_phy_10g_rx_if.sv index a4cf644..826f556 100644 --- a/src/eth/rtl/taxi_eth_phy_10g_rx_if.sv +++ b/src/eth/rtl/taxi_eth_phy_10g_rx_if.sv @@ -39,6 +39,7 @@ module taxi_eth_phy_10g_rx_if # output wire logic encoded_rx_data_valid, output wire logic [HDR_W-1:0] encoded_rx_hdr, output wire logic encoded_rx_hdr_valid, + output wire logic rx_gbx_sync, /* * SERDES interface @@ -47,6 +48,7 @@ module taxi_eth_phy_10g_rx_if # input wire logic serdes_rx_data_valid, input wire logic [HDR_W-1:0] serdes_rx_hdr, input wire logic serdes_rx_hdr_valid, + input wire logic serdes_rx_gbx_sync = 1'b0, output wire logic serdes_rx_bitslip, output wire logic serdes_rx_reset_req, @@ -79,6 +81,7 @@ wire [DATA_W-1:0] serdes_rx_data_rev, serdes_rx_data_int; wire serdes_rx_data_valid_int; wire [HDR_W-1:0] serdes_rx_hdr_rev, serdes_rx_hdr_int; wire serdes_rx_hdr_valid_int; +wire serdes_rx_gbx_sync_int; if (BIT_REVERSE) begin for (genvar n = 0; n < DATA_W; n = n + 1) begin @@ -102,6 +105,8 @@ if (SERDES_PIPELINE > 0) begin logic [HDR_W-1:0] serdes_rx_hdr_pipe_reg[SERDES_PIPELINE-1:0] = '{default: '0}; (* srl_style = "register" *) logic serdes_rx_hdr_valid_pipe_reg[SERDES_PIPELINE-1:0] = '{default: '0}; + (* srl_style = "register" *) + logic serdes_rx_gbx_sync_pipe_reg[SERDES_PIPELINE-1:0] = '{default: '0}; for (genvar n = 0; n < SERDES_PIPELINE; n = n + 1) begin always_ff @(posedge clk) begin @@ -109,6 +114,7 @@ if (SERDES_PIPELINE > 0) begin serdes_rx_data_valid_pipe_reg[n] <= n == 0 ? serdes_rx_data_valid : serdes_rx_data_valid_pipe_reg[n-1]; serdes_rx_hdr_pipe_reg[n] <= n == 0 ? serdes_rx_hdr_rev : serdes_rx_hdr_pipe_reg[n-1]; serdes_rx_hdr_valid_pipe_reg[n] <= n == 0 ? serdes_rx_hdr_valid : serdes_rx_hdr_valid_pipe_reg[n-1]; + serdes_rx_gbx_sync_pipe_reg[n] <= n == 0 ? serdes_rx_gbx_sync : serdes_rx_gbx_sync_pipe_reg[n-1]; end end @@ -116,11 +122,13 @@ if (SERDES_PIPELINE > 0) begin assign serdes_rx_data_valid_int = GBX_IF_EN ? serdes_rx_data_valid_pipe_reg[SERDES_PIPELINE-1] : 1'b1; assign serdes_rx_hdr_int = serdes_rx_hdr_pipe_reg[SERDES_PIPELINE-1]; assign serdes_rx_hdr_valid_int = USE_HDR_VLD ? serdes_rx_hdr_valid_pipe_reg[SERDES_PIPELINE-1] : 1'b1; + assign serdes_rx_gbx_sync_int = GBX_IF_EN ? serdes_rx_gbx_sync_pipe_reg[SERDES_PIPELINE-1] : 1'b0; end else begin assign serdes_rx_data_int = serdes_rx_data_rev; assign serdes_rx_data_valid_int = GBX_IF_EN ? serdes_rx_data_valid : 1'b1; assign serdes_rx_hdr_int = serdes_rx_hdr_rev; assign serdes_rx_hdr_valid_int = USE_HDR_VLD ? serdes_rx_hdr_valid : 1'b1; + assign serdes_rx_gbx_sync_int = GBX_IF_EN ? serdes_rx_gbx_sync : 1'b0; end wire [DATA_W-1:0] descrambled_rx_data; @@ -129,6 +137,7 @@ logic [DATA_W-1:0] encoded_rx_data_reg = '0; logic encoded_rx_data_valid_reg = 1'b0; logic [HDR_W-1:0] encoded_rx_hdr_reg = '0; logic encoded_rx_hdr_valid_reg = 1'b0; +logic rx_gbx_sync_reg = 1'b0; logic [57:0] scrambler_state_reg = '1; wire [57:0] scrambler_state; @@ -201,6 +210,7 @@ always_ff @(posedge clk) begin encoded_rx_data_valid_reg <= serdes_rx_data_valid_int; encoded_rx_hdr_reg <= serdes_rx_hdr_int; encoded_rx_hdr_valid_reg <= serdes_rx_hdr_valid_int; + rx_gbx_sync_reg <= serdes_rx_gbx_sync_int; if (PRBS31_EN) begin if (cfg_rx_prbs31_enable && (!GBX_IF_EN || serdes_rx_data_valid_int)) begin @@ -222,6 +232,7 @@ assign encoded_rx_data = encoded_rx_data_reg; assign encoded_rx_data_valid = GBX_IF_EN ? encoded_rx_data_valid_reg : 1'b1; assign encoded_rx_hdr = encoded_rx_hdr_reg; assign encoded_rx_hdr_valid = USE_HDR_VLD ? encoded_rx_hdr_valid_reg : 1'b1; +assign rx_gbx_sync = GBX_IF_EN ? rx_gbx_sync_reg : 1'b1; assign rx_error_count = rx_error_count_reg; diff --git a/src/eth/rtl/taxi_xgmii_baser_dec.sv b/src/eth/rtl/taxi_xgmii_baser_dec.sv index 3405690..14e8f6d 100644 --- a/src/eth/rtl/taxi_xgmii_baser_dec.sv +++ b/src/eth/rtl/taxi_xgmii_baser_dec.sv @@ -20,7 +20,8 @@ module taxi_xgmii_baser_dec # parameter DATA_W = 64, parameter CTRL_W = (DATA_W/8), parameter HDR_W = 2, - parameter logic GBX_IF_EN = 1'b0 + parameter logic GBX_IF_EN = 1'b0, + parameter GBX_CNT = 1 ) ( input wire logic clk, @@ -29,32 +30,34 @@ module taxi_xgmii_baser_dec # /* * 10GBASE-R encoded input */ - input wire logic [DATA_W-1:0] encoded_rx_data, - input wire logic encoded_rx_data_valid = 1'b1, - input wire logic [HDR_W-1:0] encoded_rx_hdr, - input wire logic encoded_rx_hdr_valid = 1'b1, + input wire logic [DATA_W-1:0] encoded_rx_data, + input wire logic encoded_rx_data_valid = 1'b1, + input wire logic [HDR_W-1:0] encoded_rx_hdr, + input wire logic encoded_rx_hdr_valid = 1'b1, + input wire logic [GBX_CNT-1:0] rx_gbx_sync_in = '0, /* * XGMII interface */ - output wire logic [DATA_W-1:0] xgmii_rxd, - output wire logic [CTRL_W-1:0] xgmii_rxc, - output wire logic xgmii_rx_valid, + output wire logic [DATA_W-1:0] xgmii_rxd, + output wire logic [CTRL_W-1:0] xgmii_rxc, + output wire logic xgmii_rx_valid, + output wire logic rx_gbx_sync_out, /* * Ordered sets */ - output wire logic [23:0] rx_os, - output wire logic rx_os_sig, - output wire logic rx_os_valid, - output wire logic rx_os_match, - output wire logic rx_idle_match, + output wire logic [23:0] rx_os, + output wire logic rx_os_sig, + output wire logic rx_os_valid, + output wire logic rx_os_match, + output wire logic rx_idle_match, /* * Status */ - output wire logic rx_bad_block, - output wire logic rx_sequence_error + output wire logic rx_bad_block, + output wire logic rx_sequence_error ); localparam DATA_W_INT = 64; @@ -138,6 +141,7 @@ logic [CTRL_W_INT-1:0] decode_err; logic [DATA_W_INT-1:0] xgmii_rxd_reg = '0, xgmii_rxd_next; logic [CTRL_W_INT-1:0] xgmii_rxc_reg = '0, xgmii_rxc_next; logic [SEG_CNT-1:0] xgmii_rx_valid_reg = '0, xgmii_rx_valid_next; +logic [GBX_CNT-1:0] rx_gbx_sync_reg = '0, rx_gbx_sync_next; logic [23:0] rx_os_reg = '0, rx_os_next; logic rx_os_sig_reg = 1'b0, rx_os_sig_next; @@ -557,12 +561,15 @@ always_comb begin xgmii_rxc_next = '1; rx_bad_block_next = 1'b1; end + + rx_gbx_sync_next = rx_gbx_sync_in; end always_ff @(posedge clk) begin xgmii_rxd_reg <= xgmii_rxd_next; xgmii_rxc_reg <= xgmii_rxc_next; xgmii_rx_valid_reg <= xgmii_rx_valid_next; + rx_gbx_sync_reg <= rx_gbx_sync_next; rx_os_reg <= rx_os_next; rx_os_sig_reg <= rx_os_sig_next; @@ -576,6 +583,7 @@ always_ff @(posedge clk) begin if (rst) begin xgmii_rx_valid_reg <= '0; + rx_gbx_sync_reg <= '0; rx_os_valid_reg <= 1'b0; rx_os_match_reg <= '0; rx_idle_match_reg <= '0; diff --git a/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv b/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv index 287fd4a..1398d5a 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv @@ -338,6 +338,7 @@ wire [DATA_W-1:0] serdes_rx_data; wire serdes_rx_data_valid; wire [HDR_W-1:0] serdes_rx_hdr; wire serdes_rx_hdr_valid; +wire serdes_rx_gbx_sync; wire serdes_rx_bitslip; wire tx_ptp_ts_cor_sync; @@ -376,7 +377,9 @@ if (GT_7) begin : gt // MAC/PHY parameters .DATA_W(DATA_W), - .HDR_W(HDR_W) + .HDR_W(HDR_W), + .TS_FNS_W(PTP_TS_FNS_W), + .TS_COR_W(PTP_TS_COR_W) ) gt_inst ( .xcvr_ctrl_clk(xcvr_ctrl_clk), @@ -437,7 +440,18 @@ if (GT_7) begin : gt .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), - .serdes_rx_bitslip(serdes_rx_bitslip) + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), + .serdes_rx_bitslip(serdes_rx_bitslip), + + /* + * Timestamp correction + */ + .tx_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ts_inc(20'h31a60), // TODO + .tx_ts_cor_val(tx_ptp_ts_cor_val), + .rx_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ts_inc(20'h31a60), // TODO + .rx_ts_cor_val(rx_ptp_ts_cor_val) ); assign xcvr_gtpowergood_out = 1'b1; @@ -446,9 +460,6 @@ if (GT_7) begin : gt assign xcvr_qpll1clk_out = 1'b0; assign xcvr_qpll1refclk_out = 1'b0; - assign tx_ptp_ts_cor_val = '0; - assign rx_ptp_ts_cor_val = '0; - end else if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt taxi_eth_phy_25g_us_gt_ll #( @@ -562,6 +573,7 @@ end else if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), /* @@ -689,6 +701,7 @@ end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); + assign serdes_rx_gbx_sync = '0; assign tx_ptp_ts_cor_val = '0; assign rx_ptp_ts_cor_val = '0; @@ -805,6 +818,7 @@ end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), /* @@ -932,6 +946,7 @@ end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); + assign serdes_rx_gbx_sync = '0; assign tx_ptp_ts_cor_val = '0; assign rx_ptp_ts_cor_val = '0; @@ -1007,6 +1022,7 @@ if (COMBINED_MAC_PCS) begin : mac .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(rx_reset_req), @@ -1200,6 +1216,7 @@ end else begin : mac wire tx_gbx_req_sync; wire tx_gbx_req_stall; wire tx_gbx_sync; + wire rx_gbx_sync; taxi_eth_phy_10g #( .DATA_W(DATA_W), @@ -1234,6 +1251,7 @@ end else begin : mac .tx_gbx_req_sync(tx_gbx_req_sync), .tx_gbx_req_stall(tx_gbx_req_stall), .tx_gbx_sync(tx_gbx_sync), + .rx_gbx_sync(rx_gbx_sync), /* * SERDES interface @@ -1249,6 +1267,7 @@ end else begin : mac .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(rx_reset_req), diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_7_gt.sv b/src/eth/rtl/us/taxi_eth_phy_10g_7_gt.sv index ca9027a..54ca44f 100644 --- a/src/eth/rtl/us/taxi_eth_phy_10g_7_gt.sv +++ b/src/eth/rtl/us/taxi_eth_phy_10g_7_gt.sv @@ -45,68 +45,81 @@ module taxi_eth_phy_10g_7_gt # // MAC/PHY parameters parameter DATA_W = 32, - parameter HDR_W = 2 + parameter HDR_W = 2, + parameter TS_FNS_W = 16, + parameter TS_COR_W = TS_FNS_W+4 ) ( - input wire logic xcvr_ctrl_clk, - input wire logic xcvr_ctrl_rst, + input wire logic xcvr_ctrl_clk, + input wire logic xcvr_ctrl_rst, /* * Transceiver control */ - taxi_apb_if.slv s_apb_ctrl, + taxi_apb_if.slv s_apb_ctrl, /* * PLL out */ - input wire logic xcvr_gtrefclk0_in = 1'b0, - input wire logic xcvr_qpllpd_in = 1'b0, - input wire logic xcvr_qpllreset_in = 1'b0, - input wire logic [2:0] xcvr_qpllpcierate_in = 3'd0, - output wire logic xcvr_qplllock_out, - output wire logic xcvr_qpllclk_out, - output wire logic xcvr_qpllrefclk_out, + input wire logic xcvr_gtrefclk0_in = 1'b0, + input wire logic xcvr_qpllpd_in = 1'b0, + input wire logic xcvr_qpllreset_in = 1'b0, + input wire logic [2:0] xcvr_qpllpcierate_in = 3'd0, + output wire logic xcvr_qplllock_out, + output wire logic xcvr_qpllclk_out, + output wire logic xcvr_qpllrefclk_out, /* * PLL in */ - input wire logic xcvr_qplllock_in = 1'b0, - input wire logic xcvr_qpllclk_in = 1'b0, - input wire logic xcvr_qpllrefclk_in = 1'b0, + input wire logic xcvr_qplllock_in = 1'b0, + input wire logic xcvr_qpllclk_in = 1'b0, + input wire logic xcvr_qpllrefclk_in = 1'b0, /* * Serial data */ - output wire logic xcvr_txp, - output wire logic xcvr_txn, - input wire logic xcvr_rxp, - input wire logic xcvr_rxn, + output wire logic xcvr_txp, + output wire logic xcvr_txn, + input wire logic xcvr_rxp, + input wire logic xcvr_rxn, /* * GT user clocks */ - output wire logic rx_clk, - input wire logic rx_rst_in = 1'b0, - output wire logic rx_rst_out, - output wire logic tx_clk, - input wire logic tx_rst_in = 1'b0, - output wire logic tx_rst_out, + output wire logic rx_clk, + input wire logic rx_rst_in = 1'b0, + output wire logic rx_rst_out, + output wire logic tx_clk, + input wire logic tx_rst_in = 1'b0, + output wire logic tx_rst_out, /* * Serdes interface */ - input wire logic [DATA_W-1:0] serdes_tx_data, - input wire logic serdes_tx_data_valid, - input wire logic [HDR_W-1:0] serdes_tx_hdr, - input wire logic serdes_tx_hdr_valid, - output wire logic serdes_tx_gbx_req_sync, - output wire logic serdes_tx_gbx_req_stall, - input wire logic serdes_tx_gbx_sync, - output wire logic [DATA_W-1:0] serdes_rx_data, - output wire logic serdes_rx_data_valid, - output wire logic [HDR_W-1:0] serdes_rx_hdr, - output wire logic serdes_rx_hdr_valid, - input wire logic serdes_rx_bitslip + input wire logic [DATA_W-1:0] serdes_tx_data, + input wire logic serdes_tx_data_valid, + input wire logic [HDR_W-1:0] serdes_tx_hdr, + input wire logic serdes_tx_hdr_valid, + output wire logic serdes_tx_gbx_req_sync, + output wire logic serdes_tx_gbx_req_stall, + input wire logic serdes_tx_gbx_sync, + output wire logic [DATA_W-1:0] serdes_rx_data, + output wire logic serdes_rx_data_valid, + output wire logic [HDR_W-1:0] serdes_rx_hdr, + output wire logic serdes_rx_hdr_valid, + output wire logic serdes_rx_gbx_sync, + input wire logic serdes_rx_bitslip, + + /* + * Timestamp correction + */ + input wire logic tx_ts_cor_sync = 1'b0, + input wire logic [TS_COR_W-1:0] tx_ts_inc = 20'h31a60, + output wire logic [TS_COR_W-1:0] tx_ts_cor_val, + input wire logic rx_ts_cor_sync = 1'b0, + input wire logic [TS_COR_W-1:0] rx_ts_inc = 20'h31a60, + output wire logic [TS_COR_W-1:0] rx_ts_cor_val ); // check configuration @@ -519,6 +532,14 @@ if (!SIM) begin assign serdes_rx_hdr_valid = gt_rxheadervalid[0]; end +logic serdes_rx_data_valid_last_reg = 1'b0; + +assign serdes_rx_gbx_sync = serdes_rx_data_valid && !serdes_rx_data_valid_last_reg; + +always_ff @(posedge rx_clk) begin + serdes_rx_data_valid_last_reg <= serdes_rx_data_valid; +end + // 66 clock cycle sequence, with two stalls on cycles 64 and 65 // 32-bit internal, 32-bit external datapath width @@ -559,6 +580,46 @@ always_ff @(posedge tx_clk) begin end end +// Generate TX timestamp correction +logic [6:0] tx_ts_cor_seq_reg = '0; +logic [TS_COR_W-1:0] tx_ts_cor_val_reg = '0; + +assign tx_ts_cor_val = tx_ts_cor_val_reg; + +always_ff @(posedge tx_clk) begin + tx_ts_cor_seq_reg <= tx_ts_cor_seq_reg + 1; + if (tx_ts_cor_seq_reg[0]) begin + tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 4); + end + if (tx_ts_cor_seq_reg == 65) begin + tx_ts_cor_seq_reg <= '0; + tx_ts_cor_val_reg <= '0; + end + if (tx_ts_cor_sync) begin + tx_ts_cor_seq_reg <= 1; + end +end + +// Generate RX timestamp correction +logic [6:0] rx_ts_cor_seq_reg = '0; +logic [TS_COR_W-1:0] rx_ts_cor_val_reg = '0; + +assign rx_ts_cor_val = rx_ts_cor_val_reg; + +always_ff @(posedge rx_clk) begin + rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1; + if (rx_ts_cor_seq_reg[0]) begin + rx_ts_cor_val_reg <= rx_ts_cor_val_reg + (tx_ts_inc >> 4); + end + if (rx_ts_cor_seq_reg == 65) begin + rx_ts_cor_seq_reg <= '0; + rx_ts_cor_val_reg <= '0; // TODO odd offset + end + if (rx_ts_cor_sync) begin + rx_ts_cor_seq_reg <= 1; + end +end + if (SIM) begin : xcvr // simulation (no GT core) diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv index a7dba2d..5577019 100644 --- a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv @@ -127,6 +127,7 @@ module taxi_eth_phy_10g_us_gt_ll # output wire logic serdes_rx_data_valid, output wire logic [HDR_W-1:0] serdes_rx_hdr, output wire logic serdes_rx_hdr_valid, + output wire logic serdes_rx_gbx_sync, input wire logic serdes_rx_bitslip, /* @@ -558,6 +559,14 @@ if (!SIM) begin assign serdes_rx_hdr_valid = gt_rxheadervalid[0]; end +logic serdes_rx_data_valid_last_reg = 1'b0; + +assign serdes_rx_gbx_sync = serdes_rx_data_valid && !serdes_rx_data_valid_last_reg; + +always_ff @(posedge rx_clk) begin + serdes_rx_data_valid_last_reg <= serdes_rx_data_valid; +end + // 66 clock cycle sequence, with two stalls on cycles 64 and 65 // 32-bit internal, 32-bit external datapath width @@ -627,11 +636,11 @@ assign rx_ts_cor_val = rx_ts_cor_val_reg; always_ff @(posedge rx_clk) begin rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1; if (rx_ts_cor_seq_reg[0]) begin - rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (tx_ts_inc >> 4); + rx_ts_cor_val_reg <= rx_ts_cor_val_reg + (tx_ts_inc >> 4); end if (rx_ts_cor_seq_reg == 65) begin rx_ts_cor_seq_reg <= '0; - rx_ts_cor_val_reg <= rx_ts_inc << 1; // TODO odd offset + rx_ts_cor_val_reg <= '0; // TODO odd offset end if (rx_ts_cor_sync) begin rx_ts_cor_seq_reg <= 1; diff --git a/src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv b/src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv index 626ff24..9ac2cf1 100644 --- a/src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv +++ b/src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv @@ -127,6 +127,7 @@ module taxi_eth_phy_25g_us_gt_ll # output wire logic serdes_rx_data_valid, output wire logic [HDR_W-1:0] serdes_rx_hdr, output wire logic serdes_rx_hdr_valid, + output wire logic serdes_rx_gbx_sync, input wire logic serdes_rx_bitslip, /* @@ -558,6 +559,14 @@ if (!SIM) begin assign serdes_rx_hdr_valid = gt_rxheadervalid[0]; end +logic serdes_rx_data_valid_last_reg = 1'b0; + +assign serdes_rx_gbx_sync = serdes_rx_data_valid && !serdes_rx_data_valid_last_reg; + +always_ff @(posedge rx_clk) begin + serdes_rx_data_valid_last_reg <= serdes_rx_data_valid; +end + if (GT_TYPE == "GTY") begin : tx_seq // 66 clock cycle sequence for GTY, with two stalls on cycles 64 and 65 // 64-bit internal, 64-bit external datapath width (required for operation at 25G) @@ -625,10 +634,10 @@ if (GT_TYPE == "GTY") begin : tx_seq always_ff @(posedge rx_clk) begin rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1; - rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (tx_ts_inc >> 5); + rx_ts_cor_val_reg <= rx_ts_cor_val_reg + (tx_ts_inc >> 5); if (rx_ts_cor_seq_reg == 65) begin rx_ts_cor_seq_reg <= '0; - rx_ts_cor_val_reg <= rx_ts_inc << 1; // TODO odd offset + rx_ts_cor_val_reg <= '0; // TODO odd offset end if (rx_ts_cor_sync) begin rx_ts_cor_seq_reg <= 1; @@ -702,10 +711,10 @@ end else begin : tx_seq always_ff @(posedge rx_clk) begin rx_ts_cor_seq_reg <= rx_ts_cor_seq_reg + 1; - rx_ts_cor_val_reg <= rx_ts_cor_val_reg - (rx_ts_inc >> 5); + rx_ts_cor_val_reg <= rx_ts_cor_val_reg + (rx_ts_inc >> 5); if (rx_ts_cor_seq_reg == 32) begin rx_ts_cor_seq_reg <= '0; - rx_ts_cor_val_reg <= rx_ts_inc; // TODO odd offset + rx_ts_cor_val_reg <= '0; // TODO odd offset end if (rx_ts_cor_sync) begin rx_ts_cor_seq_reg <= 1; diff --git a/src/eth/tb/baser.py b/src/eth/tb/baser.py index 3d9a868..63d3844 100644 --- a/src/eth/tb/baser.py +++ b/src/eth/tb/baser.py @@ -127,16 +127,16 @@ class BaseRSerdesSource(): self.log.info(" Sequence length: %d cycles", seq_len) self.log.info(" Stall cycles: %s", seq_stall) - out_bits = 66 + out_bits = self.width in_cycles = seq_len out_cycles = in_cycles - len(seq_stall) - in_bits = (out_bits * out_cycles) // in_cycles + in_bits = int(((out_bits + 2/self.pack_cnt) * out_cycles) / in_cycles) - self.log.info(" Input: %d bits (%d cycles)", in_bits, in_cycles) + self.log.info(" Input: %d+2 bits (%d cycles)", in_bits, in_cycles) self.log.info(" Output: %d bits (%d cycles)", out_bits, out_cycles) - self.log.info(" Gearbox ratio: %d:%d", in_bits, out_bits) + self.log.info(" Gearbox ratio: %d+2:%d", in_bits, out_bits) - assert in_cycles*in_bits == out_cycles*out_bits + assert in_cycles*in_bits == out_cycles*(out_bits + 2/self.pack_cnt) self.gbx_seq = 0 self.gbx_seq_len = seq_len @@ -151,6 +151,9 @@ class BaseRSerdesSource(): continue self.gbx_bit_cnt = max(self.gbx_bit_cnt - out_bits, 0) + # sync packing with gearbox + self.pack_seq = max(self.pack_cnt-1, 0) + async def send(self, frame): while self.full(): self.dequeue_event.clear() @@ -234,6 +237,8 @@ class BaseRSerdesSource(): clk_period = 0 last_clk = 0 + symb_period = 0 + symb_start = 0 gbx_delay = 0 data = 0 @@ -255,15 +260,32 @@ class BaseRSerdesSource(): # gearbox sequence if self.gbx_seq_len: + symb_period = (clk_period * (self.pack_cnt*self.gbx_out_bits + 2)) // self.gbx_in_bits + self.gbx_seq = (self.gbx_seq + 1) % self.gbx_seq_len if self.gbx_sync is not None: self.gbx_sync.value = (self.gbx_seq == 0) + if self.gbx_seq == 0: + self.gbx_bit_cnt = 2*(self.gbx_seq_len-len(self.gbx_seq_stall))//self.pack_cnt + self.pack_seq = max(self.pack_cnt-2, 0) + + gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_in_bits + + stall = self.gbx_seq in self.gbx_seq_stall + self.gbx_bit_cnt += self.gbx_in_bits + if not stall: + self.gbx_bit_cnt -= self.gbx_out_bits + if self.pack_cnt == 1 or self.pack_seq == 0: + self.gbx_bit_cnt -= 2 + if self.gbx_bit_cnt < 0: + self.gbx_bit_cnt = 0 + # stall cycle - if self.gbx_seq in self.gbx_seq_stall: + if stall: self.data.value = 0 if self.data_valid is not None: self.data_valid.value = 0 @@ -271,10 +293,9 @@ class BaseRSerdesSource(): if self.hdr_valid is not None: self.hdr_valid.value = 0 continue - - self.gbx_bit_cnt = max(self.gbx_bit_cnt - self.gbx_out_bits, 0) - gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_in_bits else: + symb_period = clk_period * self.pack_cnt + self.gbx_seq = 0 self.gbx_bit_cnt = 0 gbx_delay = 0 @@ -284,6 +305,9 @@ class BaseRSerdesSource(): if self.pack_seq: # output data + if self.pack_seq == 0: + symb_start = sim_time - gbx_delay + data_out = data >> (self.width*(self.pack_cnt-self.pack_seq)) self.pack_seq = self.pack_seq-1 @@ -299,6 +323,8 @@ class BaseRSerdesSource(): self.hdr_valid.value = 0 continue + else: + symb_start = sim_time - gbx_delay dl = bytearray() cl = [] @@ -353,13 +379,13 @@ class BaseRSerdesSource(): d = XgmiiCtrl.START c = 1 frame.start_lane = k - frame.sim_time_start = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay + frame.sim_time_start = symb_start + ((symb_period * k) // 8) elif frame_offset >= len(frame.data): d = XgmiiCtrl.TERM c = 1 in_term = True ifg_cnt = max(self.ifg - (8-k), 0) - frame.sim_time_end = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay + frame.sim_time_end = symb_start + ((symb_period * k) // 8) frame.handle_tx_complete() frame = None self.current_frame = None @@ -367,7 +393,7 @@ class BaseRSerdesSource(): d = frame.data[frame_offset] c = frame.ctrl[frame_offset] if frame.sim_time_sfd is None and not in_pre: - frame.sim_time_sfd = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay + frame.sim_time_sfd = symb_start + ((symb_period * k) // 8) if d == EthPre.SFD and (not self.xgmii_rep_count or rep_cnt == 1): in_pre = False if frame_offset == 0: diff --git a/src/eth/tb/taxi_axis_baser_rx_32/Makefile b/src/eth/tb/taxi_axis_baser_rx_32/Makefile index 543b3c9..d2e288f 100644 --- a/src/eth/tb/taxi_axis_baser_rx_32/Makefile +++ b/src/eth/tb/taxi_axis_baser_rx_32/Makefile @@ -11,7 +11,7 @@ SIM ?= verilator WAVES ?= 0 COCOTB_HDL_TIMEUNIT = 1ns -COCOTB_HDL_TIMEPRECISION = 1ps +COCOTB_HDL_TIMEPRECISION = 1fs RTL_DIR = ../../rtl LIB_DIR = ../../lib @@ -37,9 +37,13 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES))) export PARAM_DATA_W := 32 export PARAM_HDR_W := 2 export PARAM_GBX_IF_EN := 1 +export PARAM_GBX_CNT := 1 export PARAM_USXGMII_EN := 1 export PARAM_PTP_TS_EN := 1 export PARAM_PTP_TS_FMT_TOD := 1 +export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96) +export PARAM_PTP_TS_COR_EN := 1 +export PARAM_PTP_TS_COR_W := 20 ifeq ($(SIM), icarus) PLUSARGS += -fst diff --git a/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.py b/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.py index 2f73d5b..657962e 100644 --- a/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.py +++ b/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.py @@ -14,13 +14,12 @@ import logging import os import sys -import cocotb_test.simulator import pytest - import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge from cocotb.utils import get_time_from_sim_steps +from cocotb_tools.runner import get_runner from cocotbext.eth import XgmiiFrame, PtpClockSimTime from cocotbext.axi import AxiStreamBus, AxiStreamSink @@ -44,7 +43,7 @@ class TB: self.log.setLevel(logging.DEBUG) if gbx_cfg: - self.clk_period = 3.102 + self.clk_period = 3.103102 else: self.clk_period = 3.2 @@ -55,6 +54,7 @@ class TB: data_valid=dut.encoded_rx_data_valid, hdr=dut.encoded_rx_hdr, hdr_valid=dut.encoded_rx_hdr_valid, + gbx_sync=dut.rx_gbx_sync, clock=dut.clk, scramble=False, gbx_cfg=gbx_cfg @@ -63,6 +63,8 @@ class TB: self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.clk) + dut.ptp_ts_cor_val.setimmediatevalue(0) + dut.cfg_rx_max_pkt_len.setimmediatevalue(0) dut.cfg_rx_enable.setimmediatevalue(0) if usxgmii_speed is not None: @@ -119,6 +121,8 @@ class TB: self.stats["stat_rx_err_preamble"] = 0 cocotb.start_soon(self._run_stats_counters()) + if gbx_cfg: + cocotb.start_soon(self._run_ts_cor()) async def reset(self): self.dut.rst.setimmediatevalue(0) @@ -143,6 +147,24 @@ class TB: for stat in self.stats: self.stats[stat] += int(getattr(self.dut, stat).value) + async def _run_ts_cor(self): + seq_len = self.source.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.source.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.clk) + seq += 1 + if seq % 2 == 0: + val += step + if seq >= seq_len: + seq = 0 + val = 0 + self.dut.ptp_ts_cor_val.value = val + if int(self.dut.ptp_ts_cor_sync.value): + seq = 1 + def size_list(): return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)] @@ -173,6 +195,12 @@ if getattr(cocotb, 'top', None) is not None: ) async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, payload_lengths=None, payload_data=None, ifg=12): + pipe_delay = 2 + + if gbx_cfg: + # baseline gearbox delay + pipe_delay += len(gbx_cfg[1]) + tb = TB(dut, gbx_cfg, usxgmii_speed) tb.source.ifg = ifg @@ -182,6 +210,9 @@ async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, pa await tb.reset() + for k in range(200): + await RisingEdge(dut.clk) + test_frames = [payload_data(x) for x in payload_lengths()] tx_frames = [] @@ -210,8 +241,7 @@ async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, pa assert rx_frame.tdata == test_data assert frame_error == 0 - if gbx_cfg is None: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*2) < 0.01 + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.001 assert tb.sink.empty() @@ -392,37 +422,55 @@ def test_taxi_axis_baser_rx_32(request, gbx_en): module = os.path.splitext(os.path.basename(__file__))[0] toplevel = module - verilog_sources = [ + sources = [ os.path.join(tests_dir, f"{toplevel}.sv"), os.path.join(rtl_dir, f"{dut}.sv"), os.path.join(taxi_src_dir, "lfsr", "rtl", "taxi_lfsr.sv"), os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_if.sv"), ] - verilog_sources = process_f_files(verilog_sources) + sources = process_f_files(sources) parameters = {} parameters['DATA_W'] = 32 parameters['HDR_W'] = 2 parameters['GBX_IF_EN'] = gbx_en + parameters['GBX_CNT'] = 1 parameters['USXGMII_EN'] = 1 parameters['PTP_TS_EN'] = 1 parameters['PTP_TS_FMT_TOD'] = 1 parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64 + parameters['PTP_TS_COR_EN'] = 1 + parameters['PTP_TS_COR_W'] = 16+4 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} sim_build = os.path.join(tests_dir, "sim_build", request.node.name.replace('[', '-').replace(']', '')) - cocotb_test.simulator.run( - simulator="verilator", - python_search=[tests_dir], - verilog_sources=verilog_sources, - toplevel=toplevel, - module=module, + timescale = ("1ns", "1fs") + sim = os.getenv("SIM", "verilator") + waves = bool(int(os.getenv("WAVES", 0))) + + sys.path.append(tests_dir) + + runner = get_runner(sim) + runner.build( + sources=sources, + hdl_toplevel=toplevel, parameters=parameters, - sim_build=sim_build, - extra_env=extra_env, + always=True, + build_dir=sim_build, + timescale=timescale, + waves=waves, + ) + runner.test( + hdl_toplevel=toplevel, + test_module=module, + parameters=parameters, + extra_env=extra_env, + build_dir=sim_build, + timescale=timescale, + waves=waves, ) diff --git a/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.sv b/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.sv index c92dc40..48bd125 100644 --- a/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.sv +++ b/src/eth/tb/taxi_axis_baser_rx_32/test_taxi_axis_baser_rx_32.sv @@ -21,10 +21,13 @@ module test_taxi_axis_baser_rx_32 # parameter DATA_W = 32, parameter HDR_W = 2, parameter logic GBX_IF_EN = 1'b0, + parameter GBX_CNT = 1, parameter logic USXGMII_EN = 1'b1, parameter logic PTP_TS_EN = 1'b0, parameter logic PTP_TS_FMT_TOD = 1'b1, - parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64 + parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4 /* verilator lint_on WIDTHTRUNC */ ) (); @@ -38,6 +41,7 @@ logic [DATA_W-1:0] encoded_rx_data; logic encoded_rx_data_valid; logic [HDR_W-1:0] encoded_rx_hdr; logic encoded_rx_hdr_valid; +logic [GBX_CNT-1:0] rx_gbx_sync; taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(USER_W)) m_axis_rx(); @@ -48,6 +52,8 @@ logic rx_os_match; logic rx_idle_match; logic [PTP_TS_W-1:0] ptp_ts; +logic [GBX_CNT-1:0] ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val; logic [15:0] cfg_rx_max_pkt_len; logic cfg_rx_enable; @@ -78,7 +84,9 @@ taxi_axis_baser_rx_32 #( .GBX_IF_EN(GBX_IF_EN), .USXGMII_EN(USXGMII_EN), .PTP_TS_EN(PTP_TS_EN), - .PTP_TS_W(PTP_TS_W) + .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W) ) uut ( .clk(clk), @@ -91,6 +99,7 @@ uut ( .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync), /* * AXI4-Stream output (source) @@ -110,6 +119,8 @@ uut ( * PTP */ .ptp_ts(ptp_ts), + .ptp_ts_cor_sync(ptp_ts_cor_sync), + .ptp_ts_cor_val(ptp_ts_cor_val), /* * Configuration diff --git a/src/eth/tb/taxi_axis_baser_rx_64/Makefile b/src/eth/tb/taxi_axis_baser_rx_64/Makefile index 5da51fe..683ca39 100644 --- a/src/eth/tb/taxi_axis_baser_rx_64/Makefile +++ b/src/eth/tb/taxi_axis_baser_rx_64/Makefile @@ -11,7 +11,7 @@ SIM ?= verilator WAVES ?= 0 COCOTB_HDL_TIMEUNIT = 1ns -COCOTB_HDL_TIMEPRECISION = 1ps +COCOTB_HDL_TIMEPRECISION = 1fs RTL_DIR = ../../rtl LIB_DIR = ../../lib @@ -37,9 +37,13 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES))) export PARAM_DATA_W := 64 export PARAM_HDR_W := 2 export PARAM_GBX_IF_EN := 1 +export PARAM_GBX_CNT := 1 export PARAM_USXGMII_EN := 1 export PARAM_PTP_TS_EN := 1 export PARAM_PTP_TS_FMT_TOD := 1 +export PARAM_PTP_TS_W := $(if $(filter-out 1,$(PARAM_PTP_TS_FMT_TOD)),64,96) +export PARAM_PTP_TS_COR_EN := 1 +export PARAM_PTP_TS_COR_W := 20 ifeq ($(SIM), icarus) PLUSARGS += -fst diff --git a/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.py b/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.py index a28d10c..e44d7fd 100644 --- a/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.py +++ b/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.py @@ -14,13 +14,12 @@ import logging import os import sys -import cocotb_test.simulator import pytest - import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge from cocotb.utils import get_time_from_sim_steps +from cocotb_tools.runner import get_runner from cocotbext.eth import XgmiiFrame, PtpClockSimTime from cocotbext.axi import AxiStreamBus, AxiStreamSink @@ -44,7 +43,7 @@ class TB: self.log.setLevel(logging.DEBUG) if gbx_cfg: - self.clk_period = 6.206 + self.clk_period = 6.206206 else: self.clk_period = 6.4 @@ -55,6 +54,7 @@ class TB: data_valid=dut.encoded_rx_data_valid, hdr=dut.encoded_rx_hdr, hdr_valid=dut.encoded_rx_hdr_valid, + gbx_sync=dut.rx_gbx_sync, clock=dut.clk, scramble=False, gbx_cfg=gbx_cfg @@ -63,6 +63,8 @@ class TB: self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.clk) + dut.ptp_ts_cor_val.setimmediatevalue(0) + dut.cfg_rx_max_pkt_len.setimmediatevalue(0) dut.cfg_rx_enable.setimmediatevalue(0) if usxgmii_speed is not None: @@ -119,6 +121,8 @@ class TB: self.stats["stat_rx_err_preamble"] = 0 cocotb.start_soon(self._run_stats_counters()) + if gbx_cfg: + cocotb.start_soon(self._run_ts_cor()) async def reset(self): self.dut.rst.setimmediatevalue(0) @@ -143,6 +147,23 @@ class TB: for stat in self.stats: self.stats[stat] += int(getattr(self.dut, stat).value) + async def _run_ts_cor(self): + seq_len = self.source.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.source.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.clk) + seq += 1 + val += step + if seq >= seq_len: + seq = 0 + val = 0 + self.dut.ptp_ts_cor_val.value = val + if int(self.dut.ptp_ts_cor_sync.value): + seq = 1 + def size_list(): return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)] @@ -173,9 +194,13 @@ if getattr(cocotb, 'top', None) is not None: async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, payload_lengths=None, payload_data=None, ifg=12): if dut.USXGMII_EN.value: - pipe_delay = 1 + pipe_delay = 2 else: - pipe_delay = 0 + pipe_delay = 1 + + if gbx_cfg: + # baseline gearbox delay + pipe_delay += len(gbx_cfg[1]) tb = TB(dut, gbx_cfg, usxgmii_speed) @@ -186,6 +211,9 @@ async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, pa await tb.reset() + for k in range(200): + await RisingEdge(dut.clk) + test_frames = [payload_data(x) for x in payload_lengths()] tx_frames = [] @@ -214,8 +242,7 @@ async def run_test(dut, gbx_cfg=None, offset_start=False, usxgmii_speed=None, pa assert rx_frame.tdata == test_data assert frame_error == 0 - if gbx_cfg is None: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.01 + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.001 assert tb.sink.empty() @@ -397,37 +424,55 @@ def test_taxi_axis_baser_rx_64(request, gbx_en, usxgmii_en): module = os.path.splitext(os.path.basename(__file__))[0] toplevel = module - verilog_sources = [ + sources = [ os.path.join(tests_dir, f"{toplevel}.sv"), os.path.join(rtl_dir, f"{dut}.sv"), os.path.join(taxi_src_dir, "lfsr", "rtl", "taxi_lfsr.sv"), os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_if.sv"), ] - verilog_sources = process_f_files(verilog_sources) + sources = process_f_files(sources) parameters = {} parameters['DATA_W'] = 64 parameters['HDR_W'] = 2 parameters['GBX_IF_EN'] = gbx_en + parameters['GBX_CNT'] = 1 parameters['USXGMII_EN'] = usxgmii_en parameters['PTP_TS_EN'] = 1 parameters['PTP_TS_FMT_TOD'] = 1 parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64 + parameters['PTP_TS_COR_EN'] = 1 + parameters['PTP_TS_COR_W'] = 16+4 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} sim_build = os.path.join(tests_dir, "sim_build", request.node.name.replace('[', '-').replace(']', '')) - cocotb_test.simulator.run( - simulator="verilator", - python_search=[tests_dir], - verilog_sources=verilog_sources, - toplevel=toplevel, - module=module, + timescale = ("1ns", "1fs") + sim = os.getenv("SIM", "verilator") + waves = bool(int(os.getenv("WAVES", 0))) + + sys.path.append(tests_dir) + + runner = get_runner(sim) + runner.build( + sources=sources, + hdl_toplevel=toplevel, parameters=parameters, - sim_build=sim_build, - extra_env=extra_env, + always=True, + build_dir=sim_build, + timescale=timescale, + waves=waves, + ) + runner.test( + hdl_toplevel=toplevel, + test_module=module, + parameters=parameters, + extra_env=extra_env, + build_dir=sim_build, + timescale=timescale, + waves=waves, ) diff --git a/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.sv b/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.sv index 3e45e50..4c8660b 100644 --- a/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.sv +++ b/src/eth/tb/taxi_axis_baser_rx_64/test_taxi_axis_baser_rx_64.sv @@ -21,10 +21,13 @@ module test_taxi_axis_baser_rx_64 # parameter DATA_W = 64, parameter HDR_W = 2, parameter logic GBX_IF_EN = 1'b0, + parameter GBX_CNT = 1, parameter logic USXGMII_EN = 1'b1, parameter logic PTP_TS_EN = 1'b0, parameter logic PTP_TS_FMT_TOD = 1'b1, - parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64 + parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4 /* verilator lint_on WIDTHTRUNC */ ) (); @@ -38,6 +41,7 @@ logic [DATA_W-1:0] encoded_rx_data; logic encoded_rx_data_valid; logic [HDR_W-1:0] encoded_rx_hdr; logic encoded_rx_hdr_valid; +logic [GBX_CNT-1:0] rx_gbx_sync; taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(USER_W)) m_axis_rx(); @@ -48,6 +52,8 @@ logic rx_os_match; logic rx_idle_match; logic [PTP_TS_W-1:0] ptp_ts; +logic [GBX_CNT-1:0] ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val; logic [15:0] cfg_rx_max_pkt_len; logic cfg_rx_enable; @@ -79,7 +85,9 @@ taxi_axis_baser_rx_64 #( .USXGMII_EN(USXGMII_EN), .PTP_TS_EN(PTP_TS_EN), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), - .PTP_TS_W(PTP_TS_W) + .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W) ) uut ( .clk(clk), @@ -92,6 +100,7 @@ uut ( .encoded_rx_data_valid(encoded_rx_data_valid), .encoded_rx_hdr(encoded_rx_hdr), .encoded_rx_hdr_valid(encoded_rx_hdr_valid), + .rx_gbx_sync(rx_gbx_sync), /* * AXI4-Stream output (source) @@ -111,6 +120,8 @@ uut ( * PTP */ .ptp_ts(ptp_ts), + .ptp_ts_cor_sync(ptp_ts_cor_sync), + .ptp_ts_cor_val(ptp_ts_cor_val), /* * Configuration diff --git a/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.py b/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.py index 5186ed2..4b86274 100644 --- a/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.py +++ b/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.py @@ -256,7 +256,7 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg= if dut.DATA_W.value == 64: if dut.COMBINED_MAC_PCS.value: - pipe_delay = 0 + 1 + pipe_delay = 1 + 1 else: pipe_delay = 2 + 1 if dut.USXGMII_EN.value: @@ -268,6 +268,10 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg= pipe_delay = 3 + 1 pipe_delay += int(dut.RX_SERDES_PIPELINE.value) + if dut.CFG_LOW_LATENCY.value: + # baseline gearbox delay + pipe_delay += 2 # TODO this is too simplistic + tb = TB(dut) tb.serdes_sources[port].ifg = ifg @@ -320,7 +324,7 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg= assert rx_frame.tdata == test_data assert frame_error == 0 - if not tb.serdes_sources[port].gbx_seq_len: + if not tb.serdes_sources[port].gbx_seq_len or dut.COMBINED_MAC_PCS.value: if dut.PTP_TD_EN.value: assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3 else: diff --git a/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.py b/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.py index 6f2e425..5b27dfd 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.py +++ b/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.py @@ -67,6 +67,7 @@ class TB: data_valid=dut.serdes_rx_data_valid, hdr=dut.serdes_rx_hdr, hdr_valid=dut.serdes_rx_hdr_valid, + gbx_sync=dut.serdes_rx_gbx_sync, clock=dut.rx_clk, slip=dut.serdes_rx_bitslip, gbx_cfg=gbx_cfg @@ -160,6 +161,7 @@ class TB: dut.cfg_rx_pfc_en.setimmediatevalue(0) if gbx_cfg: + cocotb.start_soon(self._run_rx_ts_cor()) cocotb.start_soon(self._run_tx_ts_cor()) async def reset(self): @@ -185,6 +187,24 @@ class TB: self.ptp_td_source.set_ts_tod_sim_time() self.ptp_td_source.set_ts_rel_sim_time() + async def _run_rx_ts_cor(self): + seq_len = self.serdes_source.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.serdes_source.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.rx_clk) + seq += 1 + if self.serdes_sink.width == 64 or seq % 2 == 0: + val += step + if seq >= seq_len: + seq = 0 + val = 0 + self.dut.rx_ptp_ts_cor_val.value = val + if int(self.dut.rx_ptp_ts_cor_sync.value): + seq = 1 + async def _run_tx_ts_cor(self): seq_len = self.serdes_sink.gbx_seq_len seq = 0 @@ -235,13 +255,18 @@ if getattr(cocotb, 'top', None) is not None: async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): if len(dut.serdes_rx_data) == 64: - pipe_delay = 0 + 1 + pipe_delay = 1 + 1 if dut.USXGMII_EN.value: pipe_delay += 1 else: pipe_delay = 2 + 1 + pipe_delay += int(dut.RX_SERDES_PIPELINE.value) + if gbx_cfg: + # baseline gearbox delay + pipe_delay += len(gbx_cfg[1]) + tb = TB(dut, gbx_cfg) tb.serdes_source.ifg = ifg @@ -263,6 +288,9 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None for k in range(2000): await RisingEdge(dut.rx_clk) + for k in range(100): + await RisingEdge(dut.rx_clk) + tb.dut.cfg_rx_enable.value = 1 test_frames = [payload_data(x) for x in payload_lengths()] @@ -291,11 +319,10 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None assert rx_frame.tdata == test_data assert frame_error == 0 - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.01 + if dut.PTP_TD_EN.value: + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.001 assert tb.axis_sink.empty() diff --git a/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.sv b/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.sv index 86cee73..60091f6 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.sv +++ b/src/eth/tb/taxi_eth_mac_phy_10g/test_taxi_eth_mac_phy_10g.sv @@ -77,6 +77,7 @@ logic [DATA_W-1:0] serdes_rx_data; logic serdes_rx_data_valid; logic [HDR_W-1:0] serdes_rx_hdr; logic serdes_rx_hdr_valid; +logic serdes_rx_gbx_sync; logic serdes_rx_bitslip; logic serdes_rx_reset_req; @@ -293,6 +294,7 @@ uut ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), diff --git a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.py b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.py index 7df239f..b5d3fb0 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.py +++ b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.py @@ -65,6 +65,7 @@ class TB: data_valid=dut.serdes_rx_data_valid, hdr=dut.serdes_rx_hdr, hdr_valid=dut.serdes_rx_hdr_valid, + gbx_sync=dut.serdes_rx_gbx_sync, clock=dut.rx_clk, slip=dut.serdes_rx_bitslip, gbx_cfg=gbx_cfg @@ -125,6 +126,7 @@ class TB: dut.cfg_rx_prbs31_enable.setimmediatevalue(0) if gbx_cfg: + cocotb.start_soon(self._run_rx_ts_cor()) cocotb.start_soon(self._run_tx_ts_cor()) async def reset(self): @@ -153,6 +155,24 @@ class TB: self.ptp_td_source.set_ts_tod_sim_time() self.ptp_td_source.set_ts_rel_sim_time() + async def _run_rx_ts_cor(self): + seq_len = self.serdes_source.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.serdes_source.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.rx_clk) + seq += 1 + if self.serdes_sink.width == 64 or seq % 2 == 0: + val += step + if seq >= seq_len: + seq = 0 + val = 0 + self.dut.rx_ptp_ts_cor_val.value = val + if int(self.dut.rx_ptp_ts_cor_sync.value): + seq = 1 + async def _run_tx_ts_cor(self): seq_len = self.serdes_sink.gbx_seq_len seq = 0 @@ -201,13 +221,18 @@ if getattr(cocotb, 'top', None) is not None: async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): if len(dut.serdes_rx_data) == 64: - pipe_delay = 0 + 1 + pipe_delay = 1 + 1 if dut.USXGMII_EN.value: pipe_delay += 1 else: pipe_delay = 2 + 1 + pipe_delay += int(dut.RX_SERDES_PIPELINE.value) + if gbx_cfg: + # baseline gearbox delay + pipe_delay += len(gbx_cfg[1]) + tb = TB(dut, gbx_cfg) tb.serdes_source.ifg = ifg @@ -227,6 +252,9 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None for k in range(2000): await RisingEdge(dut.rx_clk) + for k in range(100): + await RisingEdge(dut.rx_clk) + # clear out sink buffer tb.axis_sink.clear() @@ -253,11 +281,10 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None assert rx_frame.tdata == test_data assert frame_error == 0 - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 + if dut.PTP_TD_EN.value: + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 assert tb.axis_sink.empty() diff --git a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.sv b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.sv index 0027501..f0c6696 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.sv +++ b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/test_taxi_eth_mac_phy_10g_fifo.sv @@ -91,6 +91,7 @@ logic [DATA_W-1:0] serdes_rx_data; logic serdes_rx_data_valid; logic [HDR_W-1:0] serdes_rx_hdr; logic serdes_rx_hdr_valid; +logic serdes_rx_gbx_sync; logic serdes_rx_bitslip; logic serdes_rx_reset_req; @@ -235,6 +236,7 @@ uut ( .serdes_rx_data_valid(serdes_rx_data_valid), .serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_gbx_sync(serdes_rx_gbx_sync), .serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_reset_req(serdes_rx_reset_req), diff --git a/src/eth/tb/taxi_xgmii_baser_dec/test_taxi_xgmii_baser_dec.py b/src/eth/tb/taxi_xgmii_baser_dec/test_taxi_xgmii_baser_dec.py index b108026..1fef007 100644 --- a/src/eth/tb/taxi_xgmii_baser_dec/test_taxi_xgmii_baser_dec.py +++ b/src/eth/tb/taxi_xgmii_baser_dec/test_taxi_xgmii_baser_dec.py @@ -60,6 +60,7 @@ class TB: dut.encoded_rx_data_valid.setimmediatevalue(1) dut.encoded_rx_hdr_valid.setimmediatevalue(1) + dut.rx_gbx_sync_in.setimmediatevalue(0) async def reset(self): self.dut.rst.setimmediatevalue(0) @@ -269,6 +270,7 @@ def test_taxi_xgmii_baser_dec(request, data_w): parameters['CTRL_W'] = parameters['DATA_W'] // 8 parameters['HDR_W'] = 2 parameters['GBX_IF_EN'] = 0 + parameters['GBX_CNT'] = 1 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}