From f19a6a8439e130978d1d93efca8833b78f78a404 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 24 Aug 2026 16:02:47 -0700 Subject: [PATCH] eth: Add gearbox delay compensation for BASE-R TX Signed-off-by: Alex Forencich --- src/eth/rtl/taxi_axis_baser_tx_32.sv | 121 ++++--- src/eth/rtl/taxi_axis_baser_tx_64.sv | 89 +++-- src/eth/rtl/taxi_eth_mac_phy_10g.sv | 328 +++++++++--------- src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv | 166 +++++---- src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv | 86 ++--- src/eth/rtl/taxi_eth_mac_phy_10g_tx.sv | 88 +++-- src/eth/rtl/us/taxi_eth_mac_25g_us.sv | 2 + src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv | 55 ++- src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv | 146 +++++--- src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv | 178 +++++++--- src/eth/tb/baser.py | 43 ++- src/eth/tb/taxi_axis_baser_tx_32/Makefile | 4 +- .../test_taxi_axis_baser_tx_32.py | 67 +++- .../test_taxi_axis_baser_tx_32.sv | 10 +- src/eth/tb/taxi_axis_baser_tx_64/Makefile | 4 +- .../test_taxi_axis_baser_tx_64.py | 69 +++- .../test_taxi_axis_baser_tx_64.sv | 10 +- src/eth/tb/taxi_eth_mac_25g_us/Makefile | 3 +- .../test_taxi_eth_mac_25g_us.py | 49 ++- .../test_taxi_eth_mac_25g_us.sv | 4 +- src/eth/tb/taxi_eth_mac_phy_10g/Makefile | 4 +- .../test_taxi_eth_mac_phy_10g.py | 86 +++-- .../test_taxi_eth_mac_phy_10g.sv | 14 +- src/eth/tb/taxi_eth_mac_phy_10g_fifo/Makefile | 4 +- .../test_taxi_eth_mac_phy_10g_fifo.py | 86 +++-- .../test_taxi_eth_mac_phy_10g_fifo.sv | 14 +- 26 files changed, 1110 insertions(+), 620 deletions(-) diff --git a/src/eth/rtl/taxi_axis_baser_tx_32.sv b/src/eth/rtl/taxi_axis_baser_tx_32.sv index 742791a..c92b9ba 100644 --- a/src/eth/rtl/taxi_axis_baser_tx_32.sv +++ b/src/eth/rtl/taxi_axis_baser_tx_32.sv @@ -25,67 +25,71 @@ module taxi_axis_baser_tx_32 # parameter logic DIC_EN = 1'b1, parameter logic PTP_TS_EN = 1'b0, parameter PTP_TS_W = 96, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter logic TX_CPL_CTRL_IN_TUSER = 1'b1 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * Transmit interface (AXI stream) */ - taxi_axis_if.snk s_axis_tx, - taxi_axis_if.src m_axis_tx_cpl, + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, /* * 10GBASE-R encoded interface */ - output wire logic [DATA_W-1:0] encoded_tx_data, - output wire logic encoded_tx_data_valid, - output wire logic [HDR_W-1:0] encoded_tx_hdr, - output wire logic encoded_tx_hdr_valid, - input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0, - input wire logic tx_gbx_req_stall = '0, - output wire logic [GBX_CNT-1:0] tx_gbx_sync, + output wire logic [DATA_W-1:0] encoded_tx_data, + output wire logic encoded_tx_data_valid, + output wire logic [HDR_W-1:0] encoded_tx_hdr, + output wire logic encoded_tx_hdr_valid, + input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0, + input wire logic tx_gbx_req_stall = '0, + output wire logic [GBX_CNT-1:0] tx_gbx_sync, /* * Ordered sets */ - input wire logic [23:0] tx_os = '0, - input wire logic tx_os_sig = 1'b0, - input wire logic tx_os_valid = 1'b0, - output wire logic tx_os_ready, + input wire logic [23:0] tx_os = '0, + input wire logic tx_os_sig = 1'b0, + input wire logic tx_os_valid = 1'b0, + output wire logic tx_os_ready, /* * PTP */ - input wire logic [PTP_TS_W-1:0] ptp_ts, + input wire logic [PTP_TS_W-1:0] ptp_ts, + output wire logic 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_tx_max_pkt_len = 16'd1518-1, - input wire logic [7:0] cfg_tx_ifg = 8'd12, - input wire logic cfg_tx_enable, - input wire logic cfg_tx_usxgmii_en = 1'b1, - input wire logic cfg_tx_usxgmii_5g = 1'b0, - input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, + input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, + input wire logic [7:0] cfg_tx_ifg = 8'd12, + input wire logic cfg_tx_enable, + input wire logic cfg_tx_usxgmii_en = 1'b1, + input wire logic cfg_tx_usxgmii_5g = 1'b0, + input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, /* * Status */ - output wire logic tx_start_packet, - output wire logic [2:0] stat_tx_byte, - output wire logic [15:0] stat_tx_pkt_len, - output wire logic stat_tx_pkt_ucast, - output wire logic stat_tx_pkt_mcast, - output wire logic stat_tx_pkt_bcast, - output wire logic stat_tx_pkt_vlan, - output wire logic stat_tx_pkt_good, - output wire logic stat_tx_pkt_bad, - output wire logic stat_tx_err_oversize, - output wire logic stat_tx_err_user, - output wire logic stat_tx_err_underflow + output wire logic tx_start_packet, + output wire logic [2:0] stat_tx_byte, + output wire logic [15:0] stat_tx_pkt_len, + output wire logic stat_tx_pkt_ucast, + output wire logic stat_tx_pkt_mcast, + output wire logic stat_tx_pkt_bcast, + output wire logic stat_tx_pkt_vlan, + output wire logic stat_tx_pkt_good, + output wire logic stat_tx_pkt_bad, + output wire logic stat_tx_err_oversize, + output wire logic stat_tx_err_user, + output wire logic stat_tx_err_underflow ); // extract parameters @@ -210,9 +214,9 @@ logic rep_stall_reg = 1'b0; logic s_axis_tx_tready_reg = 1'b0, s_axis_tx_tready_next; -logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0, m_axis_tx_cpl_ts_next; +logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0; logic [TX_TAG_W-1:0] m_axis_tx_cpl_tag_reg = '0, m_axis_tx_cpl_tag_next; -logic m_axis_tx_cpl_valid_reg = 1'b0, m_axis_tx_cpl_valid_next; +logic m_axis_tx_cpl_valid_reg = 1'b0; logic tx_os_ready_reg = 1'b0; @@ -243,6 +247,10 @@ logic stat_tx_err_oversize_reg = 1'b0, stat_tx_err_oversize_next; logic stat_tx_err_user_reg = 1'b0, stat_tx_err_user_next; logic stat_tx_err_underflow_reg = 1'b0, stat_tx_err_underflow_next; +logic [4+16-1:0] last_ts_reg = '0; +logic [4+16-1:0] ts_inc_reg = '0; +logic gbx_en_reg = 1'b0; + assign s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall) && (!USXGMII_EN || !rep_stall_reg); assign encoded_tx_data = encoded_tx_data_reg; @@ -262,6 +270,8 @@ assign m_axis_tx_cpl.tuser = '0; assign tx_os_ready = tx_os_ready_reg; +assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? tx_gbx_req_sync : 1'b0; + assign tx_start_packet = start_packet_reg; assign stat_tx_byte = stat_tx_byte_reg; @@ -371,20 +381,7 @@ always_comb begin crc_data_next = crc_data_reg; - m_axis_tx_cpl_ts_next = m_axis_tx_cpl_ts_reg; m_axis_tx_cpl_tag_next = m_axis_tx_cpl_tag_reg; - m_axis_tx_cpl_valid_next = 1'b0; - - if (start_packet_reg) begin - if (PTP_TS_EN) begin - m_axis_tx_cpl_ts_next = ptp_ts; - end - if (TX_CPL_CTRL_IN_TUSER) begin - m_axis_tx_cpl_valid_next = (s_axis_tx.tuser >> 1) == 0; - end else begin - m_axis_tx_cpl_valid_next = 1'b1; - end - end output_data_next = output_data_reg; output_type_next = output_type_reg; @@ -733,14 +730,15 @@ always_ff @(posedge clk) begin s_axis_tx_tready_reg <= s_axis_tx_tready_next; - m_axis_tx_cpl_ts_reg <= m_axis_tx_cpl_ts_next; m_axis_tx_cpl_tag_reg <= m_axis_tx_cpl_tag_next; - m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_next; + m_axis_tx_cpl_valid_reg <= 1'b0; tx_os_ready_reg <= 1'b0; start_packet_int_reg <= start_packet_int_next; + start_packet_reg <= 1'b0; + stat_tx_byte_reg <= stat_tx_byte_next; stat_tx_pkt_len_reg <= stat_tx_pkt_len_next; stat_tx_pkt_ucast_reg <= stat_tx_pkt_ucast_next; @@ -763,7 +761,17 @@ always_ff @(posedge clk) begin output_start_packet_reg <= output_start_packet_next; output_data_d1_reg <= output_data_reg; - start_packet_reg <= output_start_packet_reg; + if (output_start_packet_reg) begin + start_packet_reg <= 1'b1; + if (PTP_TS_EN) begin + m_axis_tx_cpl_ts_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) + (GBX_IF_EN && gbx_en_reg && phase_reg == 1 ? PTP_TS_W'(ts_inc_reg >> 5) : '0) : '0); + end + if (TX_CPL_CTRL_IN_TUSER) begin + m_axis_tx_cpl_valid_reg <= (s_axis_tx.tuser >> 1) == 0; + end else begin + m_axis_tx_cpl_valid_reg <= 1'b1; + end + end if (phase_reg == 0) begin case ({output_type_reg, output_type_next}) @@ -920,6 +928,13 @@ always_ff @(posedge clk) begin tx_gbx_sync_reg <= tx_gbx_req_sync; + last_ts_reg <= (4+16)'(ptp_ts); + ts_inc_reg <= (4+16)'(ptp_ts) - last_ts_reg; + + if (tx_gbx_req_sync || tx_gbx_req_stall) begin + gbx_en_reg <= 1'b1; + end + if (rst) begin state_reg <= STATE_IDLE; @@ -942,6 +957,8 @@ always_ff @(posedge clk) begin phase_reg <= 1'b0; tx_gbx_sync_reg <= '0; + gbx_en_reg <= 1'b0; + output_type_reg <= OUT_TYPE_IDLE; output_start_packet_reg <= 1'b0; diff --git a/src/eth/rtl/taxi_axis_baser_tx_64.sv b/src/eth/rtl/taxi_axis_baser_tx_64.sv index f616753..d306376 100644 --- a/src/eth/rtl/taxi_axis_baser_tx_64.sv +++ b/src/eth/rtl/taxi_axis_baser_tx_64.sv @@ -26,67 +26,71 @@ module taxi_axis_baser_tx_64 # 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 logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter logic TX_CPL_CTRL_IN_TUSER = 1'b1 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * Transmit interface (AXI stream) */ - taxi_axis_if.snk s_axis_tx, - taxi_axis_if.src m_axis_tx_cpl, + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, /* * 10GBASE-R encoded interface */ - output wire logic [DATA_W-1:0] encoded_tx_data, - output wire logic encoded_tx_data_valid, - output wire logic [HDR_W-1:0] encoded_tx_hdr, - output wire logic encoded_tx_hdr_valid, - input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0, - input wire logic tx_gbx_req_stall = '0, - output wire logic [GBX_CNT-1:0] tx_gbx_sync, + output wire logic [DATA_W-1:0] encoded_tx_data, + output wire logic encoded_tx_data_valid, + output wire logic [HDR_W-1:0] encoded_tx_hdr, + output wire logic encoded_tx_hdr_valid, + input wire logic [GBX_CNT-1:0] tx_gbx_req_sync = '0, + input wire logic tx_gbx_req_stall = '0, + output wire logic [GBX_CNT-1:0] tx_gbx_sync, /* * Ordered sets */ - input wire logic [23:0] tx_os = '0, - input wire logic tx_os_sig = 1'b0, - input wire logic tx_os_valid = 1'b0, - output wire logic tx_os_ready, + input wire logic [23:0] tx_os = '0, + input wire logic tx_os_sig = 1'b0, + input wire logic tx_os_valid = 1'b0, + output wire logic tx_os_ready, /* * PTP */ - input wire logic [PTP_TS_W-1:0] ptp_ts, + input wire logic [PTP_TS_W-1:0] ptp_ts, + output wire logic 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_tx_max_pkt_len = 16'd1518-1, - input wire logic [7:0] cfg_tx_ifg = 8'd12, - input wire logic cfg_tx_enable, - input wire logic cfg_tx_usxgmii_en = 1'b1, - input wire logic cfg_tx_usxgmii_5g = 1'b0, - input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, + input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, + input wire logic [7:0] cfg_tx_ifg = 8'd12, + input wire logic cfg_tx_enable, + input wire logic cfg_tx_usxgmii_en = 1'b1, + input wire logic cfg_tx_usxgmii_5g = 1'b0, + input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, /* * Status */ - output wire logic [1:0] tx_start_packet, - output wire logic [3:0] stat_tx_byte, - output wire logic [15:0] stat_tx_pkt_len, - output wire logic stat_tx_pkt_ucast, - output wire logic stat_tx_pkt_mcast, - output wire logic stat_tx_pkt_bcast, - output wire logic stat_tx_pkt_vlan, - output wire logic stat_tx_pkt_good, - output wire logic stat_tx_pkt_bad, - output wire logic stat_tx_err_oversize, - output wire logic stat_tx_err_user, - output wire logic stat_tx_err_underflow + output wire logic [1:0] tx_start_packet, + output wire logic [3:0] stat_tx_byte, + output wire logic [15:0] stat_tx_pkt_len, + output wire logic stat_tx_pkt_ucast, + output wire logic stat_tx_pkt_mcast, + output wire logic stat_tx_pkt_bcast, + output wire logic stat_tx_pkt_vlan, + output wire logic stat_tx_pkt_good, + output wire logic stat_tx_pkt_bad, + output wire logic stat_tx_err_oversize, + output wire logic stat_tx_err_user, + output wire logic stat_tx_err_underflow ); // extract parameters @@ -260,6 +264,8 @@ logic stat_tx_err_underflow_reg = 1'b0, stat_tx_err_underflow_next; 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 s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall) && (!USXGMII_EN || !rep_stall_reg); @@ -280,6 +286,8 @@ assign m_axis_tx_cpl.tuser = '0; assign tx_os_ready = tx_os_ready_reg; +assign ptp_ts_cor_sync = (GBX_IF_EN && PTP_TS_COR_EN) ? tx_gbx_req_sync : 1'b0; + assign tx_start_packet = start_packet_reg; assign stat_tx_byte = stat_tx_byte_reg; @@ -1073,16 +1081,16 @@ always_ff @(posedge clk) begin if (PTP_TS_FMT_TOD) begin // workaround for verilator lint bug: unreachable by parameter value /* verilator lint_off SELRANGE */ - m_axis_tx_cpl_ts_reg[45:0] <= ptp_ts[45:0] + 46'(ts_inc_reg >> 1); + m_axis_tx_cpl_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); m_axis_tx_cpl_ts_reg[95:48] <= ptp_ts[95:48]; /* verilator lint_on SELRANGE */ end else begin - m_axis_tx_cpl_ts_reg <= ptp_ts + PTP_TS_W'(ts_inc_reg >> 1); + m_axis_tx_cpl_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 end else if (output_start_packet_remap[0]) begin if (PTP_TS_EN) begin - m_axis_tx_cpl_ts_reg <= ptp_ts; + m_axis_tx_cpl_ts_reg <= ptp_ts + (PTP_TS_COR_EN ? PTP_TS_W'(ptp_ts_cor_val) : '0); end end if (output_start_packet_remap != 0) begin @@ -1176,6 +1184,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 (tx_gbx_req_sync || tx_gbx_req_stall) begin + gbx_en_reg <= 1'b1; + end if (rst) begin state_reg <= STATE_IDLE; @@ -1205,6 +1218,8 @@ always_ff @(posedge clk) begin encoded_tx_hdr_valid_reg <= 1'b0; tx_gbx_sync_reg <= '0; + gbx_en_reg <= 1'b0; + output_data_reg <= '0; output_type_reg <= OUT_TYPE_IDLE; output_start_packet_reg <= 1'b0; diff --git a/src/eth/rtl/taxi_eth_mac_phy_10g.sv b/src/eth/rtl/taxi_eth_mac_phy_10g.sv index 945a45d..7a3407d 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g.sv @@ -28,6 +28,8 @@ module taxi_eth_mac_phy_10g # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN), + parameter PTP_TS_COR_W = PTP_TS_FNS_W+4, parameter PTP_TD_SDI_PIPELINE = 2, parameter logic BIT_REVERSE = 1'b0, parameter logic SCRAMBLER_DISABLE = 1'b0, @@ -48,207 +50,211 @@ module taxi_eth_mac_phy_10g # parameter logic [8*8-1:0] STAT_PREFIX_STR = "MAC" ) ( - input wire logic rx_clk, - input wire logic rx_rst, - input wire logic tx_clk, - input wire logic tx_rst, + input wire logic rx_clk, + input wire logic rx_rst, + input wire logic tx_clk, + input wire logic tx_rst, /* * Transmit interface (AXI stream) */ - taxi_axis_if.snk s_axis_tx, - taxi_axis_if.src m_axis_tx_cpl, + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, /* * Receive interface (AXI stream) */ - taxi_axis_if.src m_axis_rx, + taxi_axis_if.src m_axis_rx, /* * SERDES interface */ - output wire logic [DATA_W-1:0] serdes_tx_data, - output wire logic serdes_tx_data_valid, - output wire logic [HDR_W-1:0] serdes_tx_hdr, - output wire logic serdes_tx_hdr_valid, - input wire logic serdes_tx_gbx_req_sync = 1'b0, - input wire logic serdes_tx_gbx_req_stall = 1'b0, - output wire logic serdes_tx_gbx_sync, - input wire logic [DATA_W-1:0] serdes_rx_data, - 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, - output wire logic serdes_rx_bitslip, - output wire logic serdes_rx_reset_req, + output wire logic [DATA_W-1:0] serdes_tx_data, + output wire logic serdes_tx_data_valid, + output wire logic [HDR_W-1:0] serdes_tx_hdr, + output wire logic serdes_tx_hdr_valid, + input wire logic serdes_tx_gbx_req_sync = 1'b0, + input wire logic serdes_tx_gbx_req_stall = 1'b0, + output wire logic serdes_tx_gbx_sync, + input wire logic [DATA_W-1:0] serdes_rx_data, + 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, + output wire logic serdes_rx_bitslip, + output wire logic serdes_rx_reset_req, /* * USXGMII autonegotiation */ - input wire logic an_en = 1'b1, - input wire logic an_restart = 1'b0, - input wire logic an_speedup = 1'b0, - input wire logic an_timeout_en = 1'b1, - input wire logic an_usxgmii_en = 1'b0, - input wire logic an_usxgmii_auto = 1'b1, - input wire logic an_usxgmii_5g = 1'b0, - output wire logic an_intr, - output wire logic an_running, - output wire logic an_complete, - output wire logic an_timeout, - output wire logic an_usxgmii_mode, - input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601, - output wire logic [15:0] an_lp_adv_ability, - output wire logic an_lp_usxgmii_link, - output wire logic [2:0] an_lp_usxgmii_speed, - output wire logic an_res_full_duplex, + input wire logic an_en = 1'b1, + input wire logic an_restart = 1'b0, + input wire logic an_speedup = 1'b0, + input wire logic an_timeout_en = 1'b1, + input wire logic an_usxgmii_en = 1'b0, + input wire logic an_usxgmii_auto = 1'b1, + input wire logic an_usxgmii_5g = 1'b0, + output wire logic an_intr, + output wire logic an_running, + output wire logic an_complete, + output wire logic an_timeout, + output wire logic an_usxgmii_mode, + input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601, + output wire logic [15:0] an_lp_adv_ability, + output wire logic an_lp_usxgmii_link, + output wire logic [2:0] an_lp_usxgmii_speed, + output wire logic an_res_full_duplex, /* * PTP */ - input wire logic ptp_clk = 1'b0, - input wire logic ptp_rst = 1'b0, - input wire logic ptp_sample_clk = 1'b0, - input wire logic ptp_td_sdi = 1'b0, - input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in = '0, - output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out, - output wire logic tx_ptp_ts_step_out, - output wire logic tx_ptp_locked, - input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in = '0, - output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out, - output wire logic rx_ptp_ts_step_out, - output wire logic rx_ptp_locked, + input wire logic ptp_clk = 1'b0, + input wire logic ptp_rst = 1'b0, + input wire logic ptp_sample_clk = 1'b0, + input wire logic ptp_td_sdi = 1'b0, + input wire logic [PTP_TS_W-1:0] tx_ptp_ts_in = '0, + output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out, + output wire logic tx_ptp_ts_step_out, + output wire logic tx_ptp_locked, + output wire logic tx_ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val = '0, + input wire logic [PTP_TS_W-1:0] rx_ptp_ts_in = '0, + output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out, + output wire logic rx_ptp_ts_step_out, + output wire logic rx_ptp_locked, + output wire logic rx_ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val = '0, /* * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) */ - input wire logic tx_lfc_req = 1'b0, - input wire logic tx_lfc_resend = 1'b0, - input wire logic rx_lfc_en = 1'b0, - output wire logic rx_lfc_req, - input wire logic rx_lfc_ack = 1'b0, + input wire logic tx_lfc_req = 1'b0, + input wire logic tx_lfc_resend = 1'b0, + input wire logic rx_lfc_en = 1'b0, + output wire logic rx_lfc_req, + input wire logic rx_lfc_ack = 1'b0, /* * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) */ - input wire logic [7:0] tx_pfc_req = '0, - input wire logic tx_pfc_resend = 1'b0, - input wire logic [7:0] rx_pfc_en = '0, - output wire logic [7:0] rx_pfc_req, - input wire logic [7:0] rx_pfc_ack = '0, + input wire logic [7:0] tx_pfc_req = '0, + input wire logic tx_pfc_resend = 1'b0, + input wire logic [7:0] rx_pfc_en = '0, + output wire logic [7:0] rx_pfc_req, + input wire logic [7:0] rx_pfc_ack = '0, /* * Pause interface */ - input wire logic tx_lfc_pause_en = 1'b0, - input wire logic tx_pause_req = 1'b0, - output wire logic tx_pause_ack, + input wire logic tx_lfc_pause_en = 1'b0, + input wire logic tx_pause_req = 1'b0, + output wire logic tx_pause_ack, /* * Statistics */ - input wire logic stat_clk, - input wire logic stat_rst, - taxi_axis_if.src m_axis_stat, + input wire logic stat_clk, + input wire logic stat_rst, + taxi_axis_if.src m_axis_stat, /* * Status */ - output wire logic [1:0] tx_start_packet, - output wire logic [3:0] stat_tx_byte, - output wire logic [15:0] stat_tx_pkt_len, - output wire logic stat_tx_pkt_ucast, - output wire logic stat_tx_pkt_mcast, - output wire logic stat_tx_pkt_bcast, - output wire logic stat_tx_pkt_vlan, - output wire logic stat_tx_pkt_good, - output wire logic stat_tx_pkt_bad, - output wire logic stat_tx_pad_frame, - output wire logic stat_tx_err_oversize, - output wire logic stat_tx_err_user, - output wire logic stat_tx_err_underflow, - output wire logic [1:0] rx_start_packet, - output wire logic [6:0] rx_error_count, - output wire logic rx_block_lock, - output wire logic rx_high_ber, - output wire logic rx_status, - 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, - input wire logic stat_rx_fifo_drop = 1'b0, - output wire logic stat_tx_mcf, - output wire logic stat_rx_mcf, - output wire logic stat_tx_lfc_pkt, - output wire logic stat_tx_lfc_xon, - output wire logic stat_tx_lfc_xoff, - output wire logic stat_tx_lfc_paused, - output wire logic stat_tx_pfc_pkt, - output wire logic [7:0] stat_tx_pfc_xon, - output wire logic [7:0] stat_tx_pfc_xoff, - output wire logic [7:0] stat_tx_pfc_paused, - output wire logic stat_rx_lfc_pkt, - output wire logic stat_rx_lfc_xon, - output wire logic stat_rx_lfc_xoff, - output wire logic stat_rx_lfc_paused, - output wire logic stat_rx_pfc_pkt, - output wire logic [7:0] stat_rx_pfc_xon, - output wire logic [7:0] stat_rx_pfc_xoff, - output wire logic [7:0] stat_rx_pfc_paused, + output wire logic [1:0] tx_start_packet, + output wire logic [3:0] stat_tx_byte, + output wire logic [15:0] stat_tx_pkt_len, + output wire logic stat_tx_pkt_ucast, + output wire logic stat_tx_pkt_mcast, + output wire logic stat_tx_pkt_bcast, + output wire logic stat_tx_pkt_vlan, + output wire logic stat_tx_pkt_good, + output wire logic stat_tx_pkt_bad, + output wire logic stat_tx_pad_frame, + output wire logic stat_tx_err_oversize, + output wire logic stat_tx_err_user, + output wire logic stat_tx_err_underflow, + output wire logic [1:0] rx_start_packet, + output wire logic [6:0] rx_error_count, + output wire logic rx_block_lock, + output wire logic rx_high_ber, + output wire logic rx_status, + 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, + input wire logic stat_rx_fifo_drop = 1'b0, + output wire logic stat_tx_mcf, + output wire logic stat_rx_mcf, + output wire logic stat_tx_lfc_pkt, + output wire logic stat_tx_lfc_xon, + output wire logic stat_tx_lfc_xoff, + output wire logic stat_tx_lfc_paused, + output wire logic stat_tx_pfc_pkt, + output wire logic [7:0] stat_tx_pfc_xon, + output wire logic [7:0] stat_tx_pfc_xoff, + output wire logic [7:0] stat_tx_pfc_paused, + output wire logic stat_rx_lfc_pkt, + output wire logic stat_rx_lfc_xon, + output wire logic stat_rx_lfc_xoff, + output wire logic stat_rx_lfc_paused, + output wire logic stat_rx_pfc_pkt, + output wire logic [7:0] stat_rx_pfc_xon, + output wire logic [7:0] stat_rx_pfc_xoff, + output wire logic [7:0] stat_rx_pfc_paused, /* * Configuration */ - input wire logic cfg_tx_pad_en = 1'b1, - input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, - input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, - input wire logic [7:0] cfg_tx_ifg = 8'd12, - input wire logic cfg_tx_enable = 1'b1, - input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, - input wire logic cfg_rx_enable = 1'b1, - input wire logic cfg_tx_prbs31_enable = 1'b0, - input wire logic cfg_rx_prbs31_enable = 1'b0, - input wire logic [47:0] cfg_mcf_rx_eth_dst_mcast = 48'h01_80_C2_00_00_01, - input wire logic cfg_mcf_rx_check_eth_dst_mcast = 1'b1, - input wire logic [47:0] cfg_mcf_rx_eth_dst_ucast = 48'd0, - input wire logic cfg_mcf_rx_check_eth_dst_ucast = 1'b0, - input wire logic [47:0] cfg_mcf_rx_eth_src = 48'd0, - input wire logic cfg_mcf_rx_check_eth_src = 1'b0, - input wire logic [15:0] cfg_mcf_rx_eth_type = 16'h8808, - input wire logic [15:0] cfg_mcf_rx_opcode_lfc = 16'h0001, - input wire logic cfg_mcf_rx_check_opcode_lfc = 1'b1, - input wire logic [15:0] cfg_mcf_rx_opcode_pfc = 16'h0101, - input wire logic cfg_mcf_rx_check_opcode_pfc = 1'b1, - input wire logic cfg_mcf_rx_forward = 1'b0, - input wire logic cfg_mcf_rx_enable = 1'b0, - input wire logic [47:0] cfg_tx_lfc_eth_dst = 48'h01_80_C2_00_00_01, - input wire logic [47:0] cfg_tx_lfc_eth_src = 48'h80_23_31_43_54_4C, - input wire logic [15:0] cfg_tx_lfc_eth_type = 16'h8808, - input wire logic [15:0] cfg_tx_lfc_opcode = 16'h0001, - input wire logic cfg_tx_lfc_en = 1'b0, - input wire logic [15:0] cfg_tx_lfc_quanta = 16'hffff, - input wire logic [15:0] cfg_tx_lfc_refresh = 16'h7fff, - input wire logic [47:0] cfg_tx_pfc_eth_dst = 48'h01_80_C2_00_00_01, - input wire logic [47:0] cfg_tx_pfc_eth_src = 48'h80_23_31_43_54_4C, - input wire logic [15:0] cfg_tx_pfc_eth_type = 16'h8808, - input wire logic [15:0] cfg_tx_pfc_opcode = 16'h0101, - input wire logic cfg_tx_pfc_en = 1'b0, - input wire logic [15:0] cfg_tx_pfc_quanta[8] = '{8{16'hffff}}, - input wire logic [15:0] cfg_tx_pfc_refresh[8] = '{8{16'h7fff}}, - input wire logic [15:0] cfg_rx_lfc_opcode = 16'h0001, - input wire logic cfg_rx_lfc_en = 1'b0, - input wire logic [15:0] cfg_rx_pfc_opcode = 16'h0101, - input wire logic cfg_rx_pfc_en = 1'b0 + input wire logic cfg_tx_pad_en = 1'b1, + input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, + input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, + input wire logic [7:0] cfg_tx_ifg = 8'd12, + input wire logic cfg_tx_enable = 1'b1, + input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, + input wire logic cfg_rx_enable = 1'b1, + input wire logic cfg_tx_prbs31_enable = 1'b0, + input wire logic cfg_rx_prbs31_enable = 1'b0, + input wire logic [47:0] cfg_mcf_rx_eth_dst_mcast = 48'h01_80_C2_00_00_01, + input wire logic cfg_mcf_rx_check_eth_dst_mcast = 1'b1, + input wire logic [47:0] cfg_mcf_rx_eth_dst_ucast = 48'd0, + input wire logic cfg_mcf_rx_check_eth_dst_ucast = 1'b0, + input wire logic [47:0] cfg_mcf_rx_eth_src = 48'd0, + input wire logic cfg_mcf_rx_check_eth_src = 1'b0, + input wire logic [15:0] cfg_mcf_rx_eth_type = 16'h8808, + input wire logic [15:0] cfg_mcf_rx_opcode_lfc = 16'h0001, + input wire logic cfg_mcf_rx_check_opcode_lfc = 1'b1, + input wire logic [15:0] cfg_mcf_rx_opcode_pfc = 16'h0101, + input wire logic cfg_mcf_rx_check_opcode_pfc = 1'b1, + input wire logic cfg_mcf_rx_forward = 1'b0, + input wire logic cfg_mcf_rx_enable = 1'b0, + input wire logic [47:0] cfg_tx_lfc_eth_dst = 48'h01_80_C2_00_00_01, + input wire logic [47:0] cfg_tx_lfc_eth_src = 48'h80_23_31_43_54_4C, + input wire logic [15:0] cfg_tx_lfc_eth_type = 16'h8808, + input wire logic [15:0] cfg_tx_lfc_opcode = 16'h0001, + input wire logic cfg_tx_lfc_en = 1'b0, + input wire logic [15:0] cfg_tx_lfc_quanta = 16'hffff, + input wire logic [15:0] cfg_tx_lfc_refresh = 16'h7fff, + input wire logic [47:0] cfg_tx_pfc_eth_dst = 48'h01_80_C2_00_00_01, + input wire logic [47:0] cfg_tx_pfc_eth_src = 48'h80_23_31_43_54_4C, + input wire logic [15:0] cfg_tx_pfc_eth_type = 16'h8808, + input wire logic [15:0] cfg_tx_pfc_opcode = 16'h0101, + input wire logic cfg_tx_pfc_en = 1'b0, + input wire logic [15:0] cfg_tx_pfc_quanta[8] = '{8{16'hffff}}, + input wire logic [15:0] cfg_tx_pfc_refresh[8] = '{8{16'h7fff}}, + input wire logic [15:0] cfg_rx_lfc_opcode = 16'h0001, + input wire logic cfg_rx_lfc_en = 1'b0, + input wire logic [15:0] cfg_rx_pfc_opcode = 16'h0101, + input wire logic cfg_rx_pfc_en = 1'b0 ); localparam KEEP_W = s_axis_tx.KEEP_W; @@ -525,6 +531,8 @@ taxi_eth_mac_phy_10g_rx #( .PTP_TS_EN(PTP_TS_EN), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .PRBS31_EN(PRBS31_EN), @@ -565,6 +573,8 @@ eth_mac_phy_10g_rx_inst ( * PTP */ .ptp_ts(rx_ptp_ts_out), + .ptp_ts_cor_sync(rx_ptp_ts_cor_sync), + .ptp_ts_cor_val(rx_ptp_ts_cor_val), /* * Status @@ -610,6 +620,8 @@ taxi_eth_mac_phy_10g_tx #( .PTP_TS_EN(PTP_TS_EN), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .TX_CPL_CTRL_IN_TUSER(MAC_CTRL_EN), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), @@ -649,6 +661,8 @@ eth_mac_phy_10g_tx_inst ( * PTP */ .ptp_ts(tx_ptp_ts_out), + .ptp_ts_cor_sync(tx_ptp_ts_cor_sync), + .ptp_ts_cor_val(tx_ptp_ts_cor_val), /* * Status 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 286f29a..6bda8c1 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g_fifo.sv @@ -28,6 +28,8 @@ module taxi_eth_mac_phy_10g_fifo # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN), + parameter PTP_TS_COR_W = PTP_TS_FNS_W+4, parameter PTP_TD_SDI_PIPELINE = 2, parameter logic BIT_REVERSE = 1'b0, parameter logic SCRAMBLER_DISABLE = 1'b0, @@ -59,115 +61,119 @@ module taxi_eth_mac_phy_10g_fifo # parameter logic RX_DROP_WHEN_FULL = RX_DROP_OVERSIZE_FRAME ) ( - input wire logic rx_clk, - input wire logic rx_rst, - input wire logic tx_clk, - input wire logic tx_rst, - input wire logic logic_clk, - input wire logic logic_rst, + input wire logic rx_clk, + input wire logic rx_rst, + input wire logic tx_clk, + input wire logic tx_rst, + input wire logic logic_clk, + input wire logic logic_rst, /* * Transmit interface (AXI stream) */ - taxi_axis_if.snk s_axis_tx, - taxi_axis_if.src m_axis_tx_cpl, + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, /* * Receive interface (AXI stream) */ - taxi_axis_if.src m_axis_rx, + taxi_axis_if.src m_axis_rx, /* * SERDES interface */ - output wire logic [DATA_W-1:0] serdes_tx_data, - output wire logic serdes_tx_data_valid, - output wire logic [HDR_W-1:0] serdes_tx_hdr, - output wire logic serdes_tx_hdr_valid, - input wire logic serdes_tx_gbx_req_sync = 1'b0, - input wire logic serdes_tx_gbx_req_stall = 1'b0, - output wire logic serdes_tx_gbx_sync, - input wire logic [DATA_W-1:0] serdes_rx_data, - 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, - output wire logic serdes_rx_bitslip, - output wire logic serdes_rx_reset_req, + output wire logic [DATA_W-1:0] serdes_tx_data, + output wire logic serdes_tx_data_valid, + output wire logic [HDR_W-1:0] serdes_tx_hdr, + output wire logic serdes_tx_hdr_valid, + input wire logic serdes_tx_gbx_req_sync = 1'b0, + input wire logic serdes_tx_gbx_req_stall = 1'b0, + output wire logic serdes_tx_gbx_sync, + input wire logic [DATA_W-1:0] serdes_rx_data, + 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, + output wire logic serdes_rx_bitslip, + output wire logic serdes_rx_reset_req, /* * USXGMII autonegotiation */ - input wire logic an_en = 1'b1, - input wire logic an_restart = 1'b0, - input wire logic an_speedup = 1'b0, - input wire logic an_timeout_en = 1'b1, - input wire logic an_usxgmii_en = 1'b0, - input wire logic an_usxgmii_auto = 1'b1, - input wire logic an_usxgmii_5g = 1'b0, - output wire logic an_intr, - output wire logic an_running, - output wire logic an_complete, - output wire logic an_timeout, - output wire logic an_usxgmii_mode, - input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601, - output wire logic [15:0] an_lp_adv_ability, - output wire logic an_lp_usxgmii_link, - output wire logic [2:0] an_lp_usxgmii_speed, - output wire logic an_res_full_duplex, + input wire logic an_en = 1'b1, + input wire logic an_restart = 1'b0, + input wire logic an_speedup = 1'b0, + input wire logic an_timeout_en = 1'b1, + input wire logic an_usxgmii_en = 1'b0, + input wire logic an_usxgmii_auto = 1'b1, + input wire logic an_usxgmii_5g = 1'b0, + output wire logic an_intr, + output wire logic an_running, + output wire logic an_complete, + output wire logic an_timeout, + output wire logic an_usxgmii_mode, + input wire logic [15:0] an_adv_ability_usxgmii = 16'h1601, + output wire logic [15:0] an_lp_adv_ability, + output wire logic an_lp_usxgmii_link, + output wire logic [2:0] an_lp_usxgmii_speed, + output wire logic an_res_full_duplex, /* * PTP clock */ - input wire logic ptp_clk = 1'b0, - input wire logic ptp_rst = 1'b0, - input wire logic ptp_sample_clk = 1'b0, - input wire logic ptp_td_sdi = 1'b0, - input wire logic [PTP_TS_W-1:0] ptp_ts_in = '0, - input wire logic ptp_ts_step_in = 1'b0, - output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out, - output wire logic tx_ptp_ts_step_out, - output wire logic tx_ptp_locked, - output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out, - output wire logic rx_ptp_ts_step_out, - output wire logic rx_ptp_locked, + input wire logic ptp_clk = 1'b0, + input wire logic ptp_rst = 1'b0, + input wire logic ptp_sample_clk = 1'b0, + input wire logic ptp_td_sdi = 1'b0, + input wire logic [PTP_TS_W-1:0] ptp_ts_in = '0, + input wire logic ptp_ts_step_in = 1'b0, + output wire logic [PTP_TS_W-1:0] tx_ptp_ts_out, + output wire logic tx_ptp_ts_step_out, + output wire logic tx_ptp_locked, + output wire logic tx_ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val = '0, + output wire logic [PTP_TS_W-1:0] rx_ptp_ts_out, + output wire logic rx_ptp_ts_step_out, + output wire logic rx_ptp_locked, + output wire logic rx_ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val = '0, /* * Statistics */ - input wire logic stat_clk, - input wire logic stat_rst, - taxi_axis_if.src m_axis_stat, + input wire logic stat_clk, + input wire logic stat_rst, + taxi_axis_if.src m_axis_stat, /* * Status */ - output wire logic tx_error_underflow, - output wire logic tx_fifo_overflow, - output wire logic tx_fifo_bad_frame, - output wire logic tx_fifo_good_frame, - output wire logic rx_error_bad_frame, - output wire logic rx_error_bad_fcs, - output wire logic rx_bad_block, - output wire logic rx_sequence_error, - output wire logic rx_block_lock, - output wire logic rx_high_ber, - output wire logic rx_status, - output wire logic rx_fifo_overflow, - output wire logic rx_fifo_bad_frame, - output wire logic rx_fifo_good_frame, + output wire logic tx_error_underflow, + output wire logic tx_fifo_overflow, + output wire logic tx_fifo_bad_frame, + output wire logic tx_fifo_good_frame, + output wire logic rx_error_bad_frame, + output wire logic rx_error_bad_fcs, + output wire logic rx_bad_block, + output wire logic rx_sequence_error, + output wire logic rx_block_lock, + output wire logic rx_high_ber, + output wire logic rx_status, + output wire logic rx_fifo_overflow, + output wire logic rx_fifo_bad_frame, + output wire logic rx_fifo_good_frame, /* * Configuration */ - input wire logic cfg_tx_pad_en = 1'b1, - input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, - input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, - input wire logic [7:0] cfg_tx_ifg = 8'd12, - input wire logic cfg_tx_enable = 1'b1, - input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, - input wire logic cfg_rx_enable = 1'b1, - input wire logic cfg_tx_prbs31_enable = 1'b0, - input wire logic cfg_rx_prbs31_enable = 1'b0 + input wire logic cfg_tx_pad_en = 1'b1, + input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, + input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, + input wire logic [7:0] cfg_tx_ifg = 8'd12, + input wire logic cfg_tx_enable = 1'b1, + input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1, + input wire logic cfg_rx_enable = 1'b1, + input wire logic cfg_tx_prbs31_enable = 1'b0, + input wire logic cfg_rx_prbs31_enable = 1'b0 ); localparam KEEP_W = DATA_W/8; @@ -330,6 +336,8 @@ taxi_eth_mac_phy_10g #( .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), @@ -413,10 +421,14 @@ eth_mac_phy_10g_inst ( .tx_ptp_ts_out(tx_ptp_ts_out), .tx_ptp_ts_step_out(tx_ptp_ts_step_int), .tx_ptp_locked(tx_ptp_locked_int), + .tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ptp_ts_cor_val(tx_ptp_ts_cor_val), .rx_ptp_ts_in(rx_ptp_ts_int), .rx_ptp_ts_out(rx_ptp_ts_out), .rx_ptp_ts_step_out(rx_ptp_ts_step_int), .rx_ptp_locked(rx_ptp_locked_int), + .rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ptp_ts_cor_val(rx_ptp_ts_cor_val), /* * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) 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 6da82da..9e77242 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g_rx.sv @@ -24,6 +24,8 @@ module taxi_eth_mac_phy_10g_rx # 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 logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter logic BIT_REVERSE = 1'b0, parameter logic SCRAMBLER_DISABLE = 1'b0, parameter logic PRBS31_EN = 1'b0, @@ -33,71 +35,73 @@ module taxi_eth_mac_phy_10g_rx # parameter COUNT_125US = 125000/6.4 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * Receive interface (AXI stream) */ - taxi_axis_if.src m_axis_rx, + taxi_axis_if.src m_axis_rx, /* * SERDES interface */ - input wire logic [DATA_W-1:0] serdes_rx_data, - 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, - output wire logic serdes_rx_bitslip, - output wire logic serdes_rx_reset_req, + input wire logic [DATA_W-1:0] serdes_rx_data, + 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, + output wire logic serdes_rx_bitslip, + output wire logic serdes_rx_reset_req, /* * 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 ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0, /* * Status */ - output wire logic [1:0] rx_start_packet, - output wire logic [6:0] rx_error_count, - output wire logic rx_block_lock, - output wire logic rx_high_ber, - output wire logic rx_status, - 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 [6:0] rx_error_count, + output wire logic rx_block_lock, + output wire logic rx_high_ber, + output wire logic rx_status, + 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, /* * 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 cfg_rx_prbs31_enable + 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 cfg_rx_prbs31_enable ); wire [DATA_W-1:0] encoded_rx_data; diff --git a/src/eth/rtl/taxi_eth_mac_phy_10g_tx.sv b/src/eth/rtl/taxi_eth_mac_phy_10g_tx.sv index c778331..61fa7df 100644 --- a/src/eth/rtl/taxi_eth_mac_phy_10g_tx.sv +++ b/src/eth/rtl/taxi_eth_mac_phy_10g_tx.sv @@ -25,6 +25,8 @@ module taxi_eth_mac_phy_10g_tx # 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 logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0, parameter logic BIT_REVERSE = 1'b0, parameter logic SCRAMBLER_DISABLE = 1'b0, @@ -32,68 +34,70 @@ module taxi_eth_mac_phy_10g_tx # parameter SERDES_PIPELINE = 0 ) ( - input wire logic clk, - input wire logic rst, + input wire logic clk, + input wire logic rst, /* * Transmit interface (AXI stream) */ - taxi_axis_if.snk s_axis_tx, - taxi_axis_if.src m_axis_tx_cpl, + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, /* * SERDES interface */ - output wire logic [DATA_W-1:0] serdes_tx_data, - output wire logic serdes_tx_data_valid, - output wire logic [HDR_W-1:0] serdes_tx_hdr, - output wire logic serdes_tx_hdr_valid, - input wire logic serdes_tx_gbx_req_sync = 1'b0, - input wire logic serdes_tx_gbx_req_stall = 1'b0, - output wire logic serdes_tx_gbx_sync, + output wire logic [DATA_W-1:0] serdes_tx_data, + output wire logic serdes_tx_data_valid, + output wire logic [HDR_W-1:0] serdes_tx_hdr, + output wire logic serdes_tx_hdr_valid, + input wire logic serdes_tx_gbx_req_sync = 1'b0, + input wire logic serdes_tx_gbx_req_stall = 1'b0, + output wire logic serdes_tx_gbx_sync, /* * Ordered sets */ - input wire logic [23:0] tx_os = '0, - input wire logic tx_os_sig = 1'b0, - input wire logic tx_os_valid = 1'b0, - output wire logic tx_os_ready, + input wire logic [23:0] tx_os = '0, + input wire logic tx_os_sig = 1'b0, + input wire logic tx_os_valid = 1'b0, + output wire logic tx_os_ready, /* * PTP */ - input wire logic [PTP_TS_W-1:0] ptp_ts, + input wire logic [PTP_TS_W-1:0] ptp_ts, + output wire logic ptp_ts_cor_sync, + input wire logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val = '0, /* * Status */ - output wire logic [1:0] tx_start_packet, - output wire logic [3:0] stat_tx_byte, - output wire logic [15:0] stat_tx_pkt_len, - output wire logic stat_tx_pkt_ucast, - output wire logic stat_tx_pkt_mcast, - output wire logic stat_tx_pkt_bcast, - output wire logic stat_tx_pkt_vlan, - output wire logic stat_tx_pkt_good, - output wire logic stat_tx_pkt_bad, - output wire logic stat_tx_pad_frame, - output wire logic stat_tx_err_oversize, - output wire logic stat_tx_err_user, - output wire logic stat_tx_err_underflow, + output wire logic [1:0] tx_start_packet, + output wire logic [3:0] stat_tx_byte, + output wire logic [15:0] stat_tx_pkt_len, + output wire logic stat_tx_pkt_ucast, + output wire logic stat_tx_pkt_mcast, + output wire logic stat_tx_pkt_bcast, + output wire logic stat_tx_pkt_vlan, + output wire logic stat_tx_pkt_good, + output wire logic stat_tx_pkt_bad, + output wire logic stat_tx_pad_frame, + output wire logic stat_tx_err_oversize, + output wire logic stat_tx_err_user, + output wire logic stat_tx_err_underflow, /* * Configuration */ - input wire logic cfg_tx_pad_en = 1'b1, - input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, - input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, - input wire logic [7:0] cfg_tx_ifg = 8'd12, - input wire logic cfg_tx_enable, - input wire logic cfg_tx_usxgmii_en = 1'b1, - input wire logic cfg_tx_usxgmii_5g = 1'b0, - input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, - input wire logic cfg_tx_prbs31_enable + input wire logic cfg_tx_pad_en = 1'b1, + input wire logic [7:0] cfg_tx_min_pkt_len = 8'd60-1, + input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1, + input wire logic [7:0] cfg_tx_ifg = 8'd12, + input wire logic cfg_tx_enable, + input wire logic cfg_tx_usxgmii_en = 1'b1, + input wire logic cfg_tx_usxgmii_5g = 1'b0, + input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011, + input wire logic cfg_tx_prbs31_enable ); localparam TX_USER_W = s_axis_tx.USER_W; @@ -157,6 +161,8 @@ if (DATA_W == 64) begin .PTP_TS_EN(PTP_TS_EN), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER) ) axis_baser_tx_inst ( @@ -192,6 +198,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 @@ -231,6 +239,8 @@ end else begin .DIC_EN(DIC_EN), .PTP_TS_EN(PTP_TS_EN), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER) ) axis_baser_tx_inst ( @@ -266,6 +276,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/us/taxi_eth_mac_25g_us.sv b/src/eth/rtl/us/taxi_eth_mac_25g_us.sv index 2c59164..ee68c3d 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us.sv +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us.sv @@ -61,6 +61,7 @@ module taxi_eth_mac_25g_us # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY, parameter PTP_TD_SDI_PIPELINE = 2, parameter logic PRBS31_EN = 1'b0, parameter TX_SERDES_PIPELINE = 1, @@ -455,6 +456,7 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .PRBS31_EN(PRBS31_EN), .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), 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 16c1832..287fd4a 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 @@ -60,6 +60,7 @@ module taxi_eth_mac_25g_us_ch # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY, parameter PTP_TD_SDI_PIPELINE = 2, parameter logic PRBS31_EN = 1'b0, parameter TX_SERDES_PIPELINE = 1, @@ -322,6 +323,8 @@ localparam GBX_EN = CFG_LOW_LATENCY || GT_7; localparam HDR_W = 2; +localparam PTP_TS_COR_W = PTP_TS_FNS_W+4; + wire rx_reset_req; wire [DATA_W-1:0] serdes_tx_data; @@ -337,6 +340,11 @@ wire [HDR_W-1:0] serdes_rx_hdr; wire serdes_rx_hdr_valid; wire serdes_rx_bitslip; +wire tx_ptp_ts_cor_sync; +wire [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val; +wire rx_ptp_ts_cor_sync; +wire [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val; + if (GT_7) begin : gt taxi_eth_phy_10g_7_gt #( @@ -438,6 +446,9 @@ 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 #( @@ -473,7 +484,9 @@ end else if (DATA_W == 64 && CFG_LOW_LATENCY) 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), @@ -549,7 +562,17 @@ 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_bitslip(serdes_rx_bitslip) + .serdes_rx_bitslip(serdes_rx_bitslip), + + /* + * Timestamp correction + */ + .tx_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ts_inc(20'h27b80), // TODO + .tx_ts_cor_val(tx_ptp_ts_cor_val), + .rx_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ts_inc(20'h27b80), // TODO + .rx_ts_cor_val(rx_ptp_ts_cor_val) ); end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt @@ -666,6 +689,9 @@ end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); + assign tx_ptp_ts_cor_val = '0; + assign rx_ptp_ts_cor_val = '0; + end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt taxi_eth_phy_10g_us_gt_ll #( @@ -701,7 +727,9 @@ end else if (DATA_W == 32 && CFG_LOW_LATENCY) 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), @@ -777,7 +805,17 @@ 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_bitslip(serdes_rx_bitslip) + .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) ); end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt @@ -894,6 +932,9 @@ end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); + assign tx_ptp_ts_cor_val = '0; + assign rx_ptp_ts_cor_val = '0; + end else begin $fatal(0, "Error: invalid configuration (%m)"); @@ -914,6 +955,8 @@ if (COMBINED_MAC_PCS) begin : mac .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .BIT_REVERSE(1'b1), .SCRAMBLER_DISABLE(1'b0), @@ -999,10 +1042,14 @@ if (COMBINED_MAC_PCS) begin : mac .tx_ptp_ts_out(tx_ptp_ts_out), .tx_ptp_ts_step_out(tx_ptp_ts_step_out), .tx_ptp_locked(tx_ptp_locked), + .tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ptp_ts_cor_val(tx_ptp_ts_cor_val), .rx_ptp_ts_in(rx_ptp_ts_in), .rx_ptp_ts_out(rx_ptp_ts_out), .rx_ptp_ts_step_out(rx_ptp_ts_step_out), .rx_ptp_locked(rx_ptp_locked), + .rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ptp_ts_cor_val(rx_ptp_ts_cor_val), /* * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) 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 ade4c9c..a7dba2d 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 @@ -49,83 +49,95 @@ module taxi_eth_phy_10g_us_gt_ll # // 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, /* * Common */ - output wire logic xcvr_gtpowergood_out, + output wire logic xcvr_gtpowergood_out, /* * PLL out */ - input wire logic xcvr_gtrefclk00_in = 1'b0, - input wire logic xcvr_qpll0pd_in = 1'b0, - input wire logic xcvr_qpll0reset_in = 1'b0, - input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, - output wire logic xcvr_qpll0lock_out, - output wire logic xcvr_qpll0clk_out, - output wire logic xcvr_qpll0refclk_out, - input wire logic xcvr_gtrefclk01_in = 1'b0, - input wire logic xcvr_qpll1pd_in = 1'b0, - input wire logic xcvr_qpll1reset_in = 1'b0, - input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, - output wire logic xcvr_qpll1lock_out, - output wire logic xcvr_qpll1clk_out, - output wire logic xcvr_qpll1refclk_out, + input wire logic xcvr_gtrefclk00_in = 1'b0, + input wire logic xcvr_qpll0pd_in = 1'b0, + input wire logic xcvr_qpll0reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + input wire logic xcvr_gtrefclk01_in = 1'b0, + input wire logic xcvr_qpll1pd_in = 1'b0, + input wire logic xcvr_qpll1reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, + output wire logic xcvr_qpll1lock_out, + output wire logic xcvr_qpll1clk_out, + output wire logic xcvr_qpll1refclk_out, /* * PLL in */ - input wire logic xcvr_qpll0lock_in = 1'b0, - input wire logic xcvr_qpll0clk_in = 1'b0, - input wire logic xcvr_qpll0refclk_in = 1'b0, - input wire logic xcvr_qpll1lock_in = 1'b0, - input wire logic xcvr_qpll1clk_in = 1'b0, - input wire logic xcvr_qpll1refclk_in = 1'b0, + input wire logic xcvr_qpll0lock_in = 1'b0, + input wire logic xcvr_qpll0clk_in = 1'b0, + input wire logic xcvr_qpll0refclk_in = 1'b0, + input wire logic xcvr_qpll1lock_in = 1'b0, + input wire logic xcvr_qpll1clk_in = 1'b0, + input wire logic xcvr_qpll1refclk_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, + 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 ); localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM" @@ -586,6 +598,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 <= rx_ts_inc << 1; // 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_25g_us_gt_ll.sv b/src/eth/rtl/us/taxi_eth_phy_25g_us_gt_ll.sv index f9815c0..626ff24 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 @@ -49,83 +49,95 @@ module taxi_eth_phy_25g_us_gt_ll # // MAC/PHY parameters parameter DATA_W = 64, - 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, /* * Common */ - output wire logic xcvr_gtpowergood_out, + output wire logic xcvr_gtpowergood_out, /* * PLL out */ - input wire logic xcvr_gtrefclk00_in = 1'b0, - input wire logic xcvr_qpll0pd_in = 1'b0, - input wire logic xcvr_qpll0reset_in = 1'b0, - input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, - output wire logic xcvr_qpll0lock_out, - output wire logic xcvr_qpll0clk_out, - output wire logic xcvr_qpll0refclk_out, - input wire logic xcvr_gtrefclk01_in = 1'b0, - input wire logic xcvr_qpll1pd_in = 1'b0, - input wire logic xcvr_qpll1reset_in = 1'b0, - input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, - output wire logic xcvr_qpll1lock_out, - output wire logic xcvr_qpll1clk_out, - output wire logic xcvr_qpll1refclk_out, + input wire logic xcvr_gtrefclk00_in = 1'b0, + input wire logic xcvr_qpll0pd_in = 1'b0, + input wire logic xcvr_qpll0reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + input wire logic xcvr_gtrefclk01_in = 1'b0, + input wire logic xcvr_qpll1pd_in = 1'b0, + input wire logic xcvr_qpll1reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, + output wire logic xcvr_qpll1lock_out, + output wire logic xcvr_qpll1clk_out, + output wire logic xcvr_qpll1refclk_out, /* * PLL in */ - input wire logic xcvr_qpll0lock_in = 1'b0, - input wire logic xcvr_qpll0clk_in = 1'b0, - input wire logic xcvr_qpll0refclk_in = 1'b0, - input wire logic xcvr_qpll1lock_in = 1'b0, - input wire logic xcvr_qpll1clk_in = 1'b0, - input wire logic xcvr_qpll1refclk_in = 1'b0, + input wire logic xcvr_qpll0lock_in = 1'b0, + input wire logic xcvr_qpll0clk_in = 1'b0, + input wire logic xcvr_qpll0refclk_in = 1'b0, + input wire logic xcvr_qpll1lock_in = 1'b0, + input wire logic xcvr_qpll1clk_in = 1'b0, + input wire logic xcvr_qpll1refclk_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, + 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'h27b80, + 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'h27b80, + output wire logic [TS_COR_W-1:0] rx_ts_cor_val ); localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM" @@ -587,6 +599,42 @@ if (GT_TYPE == "GTY") begin : tx_seq 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; + tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 5); + 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; + 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 + end + if (rx_ts_cor_sync) begin + rx_ts_cor_seq_reg <= 1; + end + end + end else begin : tx_seq // 33 clock cycle sequence for GTH, with one stall on cycle 32 // 32-bit internal, 64-bit external datapath width @@ -628,6 +676,42 @@ end else begin : tx_seq end end + // Generate TX timestamp correction + logic [5: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; + tx_ts_cor_val_reg <= tx_ts_cor_val_reg + (tx_ts_inc >> 5); + if (tx_ts_cor_seq_reg == 32) 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 [5: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; + 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 + end + if (rx_ts_cor_sync) begin + rx_ts_cor_seq_reg <= 1; + end + end + end if (SIM) begin : xcvr diff --git a/src/eth/tb/baser.py b/src/eth/tb/baser.py index c4b4793..3d9a868 100644 --- a/src/eth/tb/baser.py +++ b/src/eth/tb/baser.py @@ -631,16 +631,16 @@ class BaseRSerdesSink: self.log.info(" Sequence length: %d cycles", seq_len) self.log.info(" Stall cycles: %s", seq_stall) - in_bits = 66 + in_bits = self.width out_cycles = seq_len in_cycles = out_cycles - len(seq_stall) - out_bits = (in_bits * in_cycles) // out_cycles + out_bits = int(((in_bits + 2/self.pack_cnt) * in_cycles) / out_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 + 2/self.pack_cnt) == out_cycles*out_bits self.gbx_seq = 0 self.gbx_seq_gen = 0 @@ -723,6 +723,8 @@ class BaseRSerdesSink: clock_edge_event = RisingEdge(self.clock) clk_period = 0 + symb_period = 0 + symb_start = 0 last_clk = 0 gbx_delay = 0 sync_bad = True @@ -746,6 +748,8 @@ class BaseRSerdesSink: # gearbox sequence if self.gbx_seq_len: + symb_period = (clk_period * (self.pack_cnt*self.gbx_in_bits + 2)) // self.gbx_out_bits + # generation self.gbx_seq_gen = (self.gbx_seq_gen + 1) % self.gbx_seq_len @@ -763,14 +767,23 @@ class BaseRSerdesSink: if int(self.gbx_sync.value): self.gbx_seq = 0 + if self.gbx_seq == 0: + self.gbx_bit_cnt = 0 + + gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_out_bits + + stall = self.gbx_seq in self.gbx_seq_stall + + if not stall: + self.gbx_bit_cnt += self.gbx_in_bits + if self.pack_cnt == 1 or self.pack_seq == 0: + self.gbx_bit_cnt += 2 self.gbx_bit_cnt = max(self.gbx_bit_cnt - self.gbx_out_bits, 0) - if self.gbx_seq in self.gbx_seq_stall: + if stall: continue - - self.gbx_bit_cnt += self.gbx_in_bits - gbx_delay = (self.gbx_bit_cnt * clk_period) // self.gbx_out_bits else: + symb_period = clk_period * self.pack_cnt self.gbx_seq = 0 self.gbx_seq_gen = 0 self.gbx_bit_cnt = 0 @@ -799,6 +812,9 @@ class BaseRSerdesSink: if self.pack_cnt > 1: # pack input data + if self.pack_seq == 0: + symb_start = sim_time + gbx_delay + if self.hdr_valid is not None: if self.hdr_valid.value: data = data_in @@ -807,13 +823,14 @@ class BaseRSerdesSink: continue data |= data_in << (self.width*self.pack_seq) - self.pack_seq = self.pack_seq+1 + self.pack_seq += 1 if self.pack_seq < self.pack_cnt: continue self.pack_seq = 0 else: + symb_start = sim_time + gbx_delay data = data_in hdr = hdr_in @@ -1004,7 +1021,7 @@ class BaseRSerdesSink: if c_val and d_val == XgmiiCtrl.START: # start frame = XgmiiFrame(bytearray([EthPre.PRE]), [0]) - frame.sim_time_start = sim_time + (clk_period // self.byte_lanes * k) + gbx_delay + frame.sim_time_start = symb_start + ((symb_period * k) // 8) frame.start_lane = k in_pre = True else: @@ -1016,7 +1033,7 @@ class BaseRSerdesSink: frame.ctrl.append(c_val) frame.compact() - frame.sim_time_end = sim_time + (clk_period // self.byte_lanes * k) + gbx_delay + frame.sim_time_end = symb_start + ((symb_period * k) // 8) self.log.info("RX frame: %s", frame) self.queue_occupancy_bytes += len(frame) @@ -1028,7 +1045,7 @@ class BaseRSerdesSink: frame = None else: 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_val == EthPre.SFD: in_pre = False diff --git a/src/eth/tb/taxi_axis_baser_tx_32/Makefile b/src/eth/tb/taxi_axis_baser_tx_32/Makefile index 7b6cf71..4e4b8f0 100644 --- a/src/eth/tb/taxi_axis_baser_tx_32/Makefile +++ b/src/eth/tb/taxi_axis_baser_tx_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 @@ -43,6 +43,8 @@ export PARAM_DIC_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 export PARAM_TX_TAG_W := 16 export PARAM_TX_CPL_CTRL_IN_TUSER := 1 diff --git a/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.py b/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.py index 2579e03..08f3bae 100644 --- a/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.py +++ b/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_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 PtpClockSimTime from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame @@ -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 @@ -71,6 +70,8 @@ class TB: dut.tx_os_sig.setimmediatevalue(0) dut.tx_os_valid.setimmediatevalue(0) + dut.ptp_ts_cor_val.setimmediatevalue(0) + dut.cfg_tx_max_pkt_len.setimmediatevalue(0) dut.cfg_tx_ifg.setimmediatevalue(0) dut.cfg_tx_enable.setimmediatevalue(0) @@ -124,6 +125,8 @@ class TB: self.stats["stat_tx_err_underflow"] = 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) @@ -148,6 +151,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.sink.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.sink.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(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)] @@ -214,8 +235,7 @@ async def run_test(dut, gbx_cfg=None, usxgmii_speed=None, payload_lengths=None, assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.01 + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.01 assert tb.sink.empty() @@ -522,14 +542,14 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_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 = {} @@ -542,6 +562,8 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_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 parameters['TX_TAG_W'] = 16 parameters['TX_CPL_CTRL_IN_TUSER'] = 1 @@ -550,13 +572,28 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_en): 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_tx_32/test_taxi_axis_baser_tx_32.sv b/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.sv index 9f2910a..04113ed 100644 --- a/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.sv +++ b/src/eth/tb/taxi_axis_baser_tx_32/test_taxi_axis_baser_tx_32.sv @@ -9,7 +9,7 @@ Authors: */ `resetall -`timescale 1ns / 1ps +`timescale 1ns / 1fs `default_nettype none /* @@ -27,6 +27,8 @@ module test_taxi_axis_baser_tx_32 # 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 logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter TX_TAG_W = 16, parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0 /* verilator lint_on WIDTHTRUNC */ @@ -55,6 +57,8 @@ logic tx_os_valid; logic tx_os_ready; logic [PTP_TS_W-1:0] ptp_ts; +logic ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val; logic [15:0] cfg_tx_max_pkt_len; logic [7:0] cfg_tx_ifg; @@ -85,6 +89,8 @@ taxi_axis_baser_tx_32 #( .DIC_EN(DIC_EN), .PTP_TS_EN(PTP_TS_EN), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER) ) uut ( @@ -120,6 +126,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_tx_64/Makefile b/src/eth/tb/taxi_axis_baser_tx_64/Makefile index bd4d02b..bbf2f0f 100644 --- a/src/eth/tb/taxi_axis_baser_tx_64/Makefile +++ b/src/eth/tb/taxi_axis_baser_tx_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 @@ -43,6 +43,8 @@ export PARAM_DIC_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 export PARAM_TX_TAG_W := 16 export PARAM_TX_CPL_CTRL_IN_TUSER := 1 diff --git a/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.py b/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.py index a0ab13c..92d8333 100644 --- a/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.py +++ b/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_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 PtpClockSimTime from cocotbext.axi import AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame @@ -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 @@ -71,6 +70,8 @@ class TB: dut.tx_os_sig.setimmediatevalue(0) dut.tx_os_valid.setimmediatevalue(0) + dut.ptp_ts_cor_val.setimmediatevalue(0) + dut.cfg_tx_max_pkt_len.setimmediatevalue(0) dut.cfg_tx_ifg.setimmediatevalue(0) dut.cfg_tx_enable.setimmediatevalue(0) @@ -124,6 +125,8 @@ class TB: self.stats["stat_tx_err_underflow"] = 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) @@ -148,6 +151,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.sink.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.sink.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(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)] @@ -214,8 +234,7 @@ async def run_test(dut, gbx_cfg=None, usxgmii_speed=None, payload_lengths=None, assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.01 + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.001 assert tb.sink.empty() @@ -294,8 +313,7 @@ async def run_test_alignment(dut, gbx_cfg=None, usxgmii_speed=None, payload_data assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.01 + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*1) < 0.001 start_lane.append(rx_frame.start_lane) @@ -638,14 +656,14 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_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 = {} @@ -658,6 +676,8 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_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 parameters['TX_TAG_W'] = 16 parameters['TX_CPL_CTRL_IN_TUSER'] = 1 @@ -666,13 +686,28 @@ def test_taxi_axis_baser_tx_64(request, gbx_en, dic_en): 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_tx_64/test_taxi_axis_baser_tx_64.sv b/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.sv index faa4a0b..be48dd2 100644 --- a/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.sv +++ b/src/eth/tb/taxi_axis_baser_tx_64/test_taxi_axis_baser_tx_64.sv @@ -9,7 +9,7 @@ Authors: */ `resetall -`timescale 1ns / 1ps +`timescale 1ns / 1fs `default_nettype none /* @@ -27,6 +27,8 @@ module test_taxi_axis_baser_tx_64 # 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 logic PTP_TS_COR_EN = PTP_TS_EN && GBX_IF_EN, + parameter PTP_TS_COR_W = 16+4, parameter TX_TAG_W = 16, parameter logic TX_CPL_CTRL_IN_TUSER = 1'b0 /* verilator lint_on WIDTHTRUNC */ @@ -55,6 +57,8 @@ logic tx_os_valid; logic tx_os_ready; logic [PTP_TS_W-1:0] ptp_ts; +logic ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] ptp_ts_cor_val; logic [15:0] cfg_tx_max_pkt_len; logic [7:0] cfg_tx_ifg; @@ -85,6 +89,8 @@ taxi_axis_baser_tx_64 #( .DIC_EN(DIC_EN), .PTP_TS_EN(PTP_TS_EN), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER) ) uut ( @@ -120,6 +126,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/Makefile b/src/eth/tb/taxi_eth_mac_25g_us/Makefile index d92b658..a4319ba 100644 --- a/src/eth/tb/taxi_eth_mac_25g_us/Makefile +++ b/src/eth/tb/taxi_eth_mac_25g_us/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 @@ -51,6 +51,7 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN) export PARAM_PTP_TS_FMT_TOD := 1 export PARAM_PTP_TS_FNS_W := 16 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_TD_SDI_PIPELINE := 2 export PARAM_TX_TAG_W := 16 export PARAM_PRBS31_EN := 1 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 943d04a..5186ed2 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 @@ -18,12 +18,11 @@ import sys from scapy.layers.l2 import Ether import pytest -import cocotb_test.simulator - import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, Timer 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, AxiStreamSource, AxiStreamSink, AxiStreamFrame @@ -51,7 +50,7 @@ class TB: cocotb.start_soon(Clock(dut.xcvr_ctrl_clk, 8, units="ns").start()) cocotb.start_soon(Clock(dut.stat_clk, 8, units="ns").start()) - cocotb.start_soon(Clock(dut.xcvr_gtrefclk00_in, 6.206, units="ns").start()) + cocotb.start_soon(Clock(dut.xcvr_gtrefclk00_in, 6.206206, units="ns").start()) self.apb_ctrl = ApbMaster(ApbBus.from_entity(dut.s_apb_ctrl), dut.xcvr_ctrl_clk, dut.xcvr_ctrl_rst) @@ -65,14 +64,14 @@ class TB: if ch.ch_inst.DATA_W.value == 64: if ch.ch_inst.CFG_LOW_LATENCY.value: - clk = 2.482 + clk = 2.482482 gbx_cfg = (66, [64, 65]) else: clk = 2.56 gbx_cfg = None else: if ch.ch_inst.CFG_LOW_LATENCY.value: - clk = 3.102 + clk = 3.103102 gbx_cfg = (66, [64, 65]) else: clk = 3.2 @@ -399,7 +398,7 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg= assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if not tb.serdes_sinks[port].gbx_seq_len: + if not tb.serdes_sinks[port].gbx_seq_len or dut.COMBINED_MAC_PCS.value: if dut.PTP_TD_EN.value: assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3 else: @@ -485,7 +484,7 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12): assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if not tb.serdes_sinks[port].gbx_seq_len: + if not tb.serdes_sinks[port].gbx_seq_len or dut.COMBINED_MAC_PCS.value: if dut.PTP_TD_EN.value: assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < tb.clk_period[port]*3 else: @@ -1200,12 +1199,12 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic 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, "us", f"{dut}.f"), ] - verilog_sources = process_f_files(verilog_sources) + sources = process_f_files(sources) parameters = {} @@ -1228,6 +1227,7 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic parameters['PTP_TS_FMT_TOD'] = 1 parameters['PTP_TS_FNS_W'] = 16 parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64 + parameters['PTP_TS_COR_EN'] = 1 parameters['PTP_TD_SDI_PIPELINE'] = 2 parameters['TX_TAG_W'] = 16 parameters['PRBS31_EN'] = 1 @@ -1250,13 +1250,28 @@ def test_taxi_eth_mac_25g_us(request, data_w, combined_mac_pcs, low_latency, dic 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_eth_mac_25g_us/test_taxi_eth_mac_25g_us.sv b/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.sv index 7c9b1d2..0bf6298 100644 --- a/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.sv +++ b/src/eth/tb/taxi_eth_mac_25g_us/test_taxi_eth_mac_25g_us.sv @@ -9,7 +9,7 @@ Authors: */ `resetall -`timescale 1ns / 1ps +`timescale 1ns / 1fs `default_nettype none /* @@ -50,6 +50,7 @@ module test_taxi_eth_mac_25g_us # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && CFG_LOW_LATENCY, parameter PTP_TD_SDI_PIPELINE = 2, parameter TX_TAG_W = 16, parameter logic PRBS31_EN = 1'b0, @@ -292,6 +293,7 @@ taxi_eth_mac_25g_us #( .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .PRBS31_EN(PRBS31_EN), .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), diff --git a/src/eth/tb/taxi_eth_mac_phy_10g/Makefile b/src/eth/tb/taxi_eth_mac_phy_10g/Makefile index 8c2bad8..63b7c52 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g/Makefile +++ b/src/eth/tb/taxi_eth_mac_phy_10g/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 @@ -43,6 +43,8 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN) export PARAM_PTP_TS_FMT_TOD := 1 export PARAM_PTP_TS_FNS_W := 16 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 export PARAM_PTP_TD_SDI_PIPELINE := 2 export PARAM_TX_TAG_W := 16 export PARAM_BIT_REVERSE := 0 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 28c43b0..6f2e425 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 @@ -18,12 +18,11 @@ import sys from scapy.layers.l2 import Ether import pytest -import cocotb_test.simulator - import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, Timer 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, AxiStreamSource, AxiStreamSink, AxiStreamFrame @@ -50,12 +49,12 @@ class TB: if len(dut.serdes_tx_data) == 64: if gbx_cfg: - self.clk_period = 6.206 + self.clk_period = 6.206206 else: self.clk_period = 6.4 else: if gbx_cfg: - self.clk_period = 3.102 + self.clk_period = 3.103102 else: self.clk_period = 3.2 @@ -114,6 +113,9 @@ class TB: dut.an_usxgmii_5g.setimmediatevalue(0) dut.an_adv_ability_usxgmii.setimmediatevalue(0x1601) + dut.tx_ptp_ts_cor_val.setimmediatevalue(0) + dut.rx_ptp_ts_cor_val.setimmediatevalue(0) + dut.stat_rx_fifo_drop.setimmediatevalue(0) dut.cfg_tx_pad_en.setimmediatevalue(0) @@ -157,6 +159,9 @@ class TB: dut.cfg_rx_pfc_opcode.setimmediatevalue(0) dut.cfg_rx_pfc_en.setimmediatevalue(0) + if gbx_cfg: + cocotb.start_soon(self._run_tx_ts_cor()) + async def reset(self): self.dut.rx_rst.setimmediatevalue(0) self.dut.tx_rst.setimmediatevalue(0) @@ -180,6 +185,24 @@ class TB: self.ptp_td_source.set_ts_tod_sim_time() self.ptp_td_source.set_ts_rel_sim_time() + async def _run_tx_ts_cor(self): + seq_len = self.serdes_sink.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.serdes_sink.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.tx_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.tx_ptp_ts_cor_val.value = val + if int(self.dut.tx_ptp_ts_cor_sync.value): + seq = 1 + def size_list(): return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 @@ -339,11 +362,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01 + if dut.PTP_TD_EN.value: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.001 assert tb.serdes_sink.empty() @@ -418,11 +440,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12): assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01 + if dut.PTP_TD_EN.value: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.001 start_lane.append(rx_frame.start_lane) @@ -1103,12 +1124,12 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_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}.f"), ] - verilog_sources = process_f_files(verilog_sources) + sources = process_f_files(sources) parameters = {} @@ -1123,6 +1144,8 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en parameters['PTP_TS_FMT_TOD'] = 1 parameters['PTP_TS_FNS_W'] = 16 parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64 + parameters['PTP_TS_COR_EN'] = 1 + parameters['PTP_TS_COR_W'] = parameters['PTP_TS_FNS_W']+4 parameters['PTP_TD_SDI_PIPELINE'] = 2 parameters['TX_TAG_W'] = 16 parameters['BIT_REVERSE'] = 0 @@ -1148,13 +1171,28 @@ def test_taxi_eth_mac_phy_10g(request, data_w, ptp_td_en, gbx_en, dic_en, pfc_en 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_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 f8f8b68..86cee73 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 @@ -9,7 +9,7 @@ Authors: */ `resetall -`timescale 1ns / 1ps +`timescale 1ns / 1fs `default_nettype none /* @@ -29,6 +29,8 @@ module test_taxi_eth_mac_phy_10g # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN), + parameter PTP_TS_COR_W = PTP_TS_FNS_W+4, parameter PTP_TD_SDI_PIPELINE = 2, parameter TX_TAG_W = 16, parameter logic BIT_REVERSE = 1'b0, @@ -104,10 +106,14 @@ logic [PTP_TS_W-1:0] tx_ptp_ts_in; logic [PTP_TS_W-1:0] tx_ptp_ts_out; logic tx_ptp_ts_step_out; logic tx_ptp_locked; +logic tx_ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val; logic [PTP_TS_W-1:0] rx_ptp_ts_in; logic [PTP_TS_W-1:0] rx_ptp_ts_out; logic rx_ptp_ts_step_out; logic rx_ptp_locked; +logic rx_ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val; logic tx_lfc_req; logic tx_lfc_resend; @@ -235,6 +241,8 @@ taxi_eth_mac_phy_10g #( .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), @@ -320,10 +328,14 @@ uut ( .tx_ptp_ts_out(tx_ptp_ts_out), .tx_ptp_ts_step_out(tx_ptp_ts_step_out), .tx_ptp_locked(tx_ptp_locked), + .tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ptp_ts_cor_val(tx_ptp_ts_cor_val), .rx_ptp_ts_in(rx_ptp_ts_in), .rx_ptp_ts_out(rx_ptp_ts_out), .rx_ptp_ts_step_out(rx_ptp_ts_step_out), .rx_ptp_locked(rx_ptp_locked), + .rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ptp_ts_cor_val(rx_ptp_ts_cor_val), /* * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) diff --git a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/Makefile b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/Makefile index 08771cc..3acf96b 100644 --- a/src/eth/tb/taxi_eth_mac_phy_10g_fifo/Makefile +++ b/src/eth/tb/taxi_eth_mac_phy_10g_fifo/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 @@ -44,6 +44,8 @@ export PARAM_PTP_TD_EN := $(PARAM_PTP_TS_EN) export PARAM_PTP_TS_FMT_TOD := 1 export PARAM_PTP_TS_FNS_W := 16 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 export PARAM_PTP_TD_SDI_PIPELINE := 2 export PARAM_TX_TAG_W := 16 export PARAM_BIT_REVERSE := 0 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 5205320..7df239f 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 @@ -15,12 +15,11 @@ import os import sys import pytest -import cocotb_test.simulator - import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, Timer 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, AxiStreamSource, AxiStreamSink, AxiStreamFrame @@ -47,12 +46,12 @@ class TB: if len(dut.serdes_tx_data) == 64: if gbx_cfg: - self.clk_period = 6.206 + self.clk_period = 6.206206 else: self.clk_period = 6.4 else: if gbx_cfg: - self.clk_period = 3.102 + self.clk_period = 3.103102 else: self.clk_period = 3.2 @@ -112,6 +111,9 @@ class TB: dut.an_usxgmii_5g.setimmediatevalue(0) dut.an_adv_ability_usxgmii.setimmediatevalue(0x1601) + dut.tx_ptp_ts_cor_val.setimmediatevalue(0) + dut.rx_ptp_ts_cor_val.setimmediatevalue(0) + dut.cfg_tx_pad_en.setimmediatevalue(0) dut.cfg_tx_min_pkt_len.setimmediatevalue(0) dut.cfg_tx_max_pkt_len.setimmediatevalue(0) @@ -122,6 +124,9 @@ class TB: dut.cfg_tx_prbs31_enable.setimmediatevalue(0) dut.cfg_rx_prbs31_enable.setimmediatevalue(0) + if gbx_cfg: + cocotb.start_soon(self._run_tx_ts_cor()) + async def reset(self): self.dut.logic_rst.setimmediatevalue(0) self.dut.rx_rst.setimmediatevalue(0) @@ -148,6 +153,24 @@ class TB: self.ptp_td_source.set_ts_tod_sim_time() self.ptp_td_source.set_ts_rel_sim_time() + async def _run_tx_ts_cor(self): + seq_len = self.serdes_sink.gbx_seq_len + seq = 0 + val = 0 + ui = self.clk_period / self.serdes_sink.width + step = int(ui*2*65536+0.5) + while True: + await RisingEdge(self.dut.tx_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.tx_ptp_ts_cor_val.value = val + if int(self.dut.tx_ptp_ts_cor_sync.value): + seq = 1 + def size_list(): return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 @@ -296,11 +319,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 + if dut.PTP_TD_EN.value: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 assert tb.serdes_sink.empty() @@ -371,11 +393,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12): assert rx_frame.get_payload() == test_data assert rx_frame.check_fcs() assert rx_frame.ctrl is None - if gbx_cfg is None: - if dut.PTP_TD_EN.value: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 - else: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 + if dut.PTP_TD_EN.value: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*5 + else: + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2 start_lane.append(rx_frame.start_lane) @@ -640,12 +661,12 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_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}.f"), ] - verilog_sources = process_f_files(verilog_sources) + sources = process_f_files(sources) parameters = {} @@ -661,6 +682,8 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en): parameters['PTP_TS_FMT_TOD'] = 1 parameters['PTP_TS_FNS_W'] = 16 parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64 + parameters['PTP_TS_COR_EN'] = 1 + parameters['PTP_TS_COR_W'] = parameters['PTP_TS_FNS_W']+4 parameters['PTP_TD_SDI_PIPELINE'] = 2 parameters['TX_TAG_W'] = 16 parameters['BIT_REVERSE'] = 0 @@ -697,13 +720,28 @@ def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en): 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_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 83a0bd4..0027501 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 @@ -9,7 +9,7 @@ Authors: */ `resetall -`timescale 1ns / 1ps +`timescale 1ns / 1fs `default_nettype none /* @@ -30,6 +30,8 @@ module test_taxi_eth_mac_phy_10g_fifo # parameter logic PTP_TS_FMT_TOD = 1'b1, parameter PTP_TS_FNS_W = 16, parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PTP_TS_COR_EN = PTP_TS_EN && (TX_GBX_IF_EN || RX_GBX_IF_EN), + parameter PTP_TS_COR_W = PTP_TS_FNS_W+4, parameter PTP_TD_SDI_PIPELINE = 2, parameter TX_TAG_W = 16, parameter logic BIT_REVERSE = 1'b0, @@ -119,9 +121,13 @@ logic ptp_ts_step_in; logic [PTP_TS_W-1:0] tx_ptp_ts_out; logic tx_ptp_ts_step_out; logic tx_ptp_locked; +logic tx_ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] tx_ptp_ts_cor_val; logic [PTP_TS_W-1:0] rx_ptp_ts_out; logic rx_ptp_ts_step_out; logic rx_ptp_locked; +logic rx_ptp_ts_cor_sync; +logic [PTP_TS_COR_W-1:0] rx_ptp_ts_cor_val; logic stat_clk; logic stat_rst; @@ -164,6 +170,8 @@ taxi_eth_mac_phy_10g_fifo #( .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), .PTP_TS_FNS_W(PTP_TS_FNS_W), .PTP_TS_W(PTP_TS_W), + .PTP_TS_COR_EN(PTP_TS_COR_EN), + .PTP_TS_COR_W(PTP_TS_COR_W), .PTP_TD_SDI_PIPELINE(PTP_TD_SDI_PIPELINE), .BIT_REVERSE(BIT_REVERSE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), @@ -263,9 +271,13 @@ uut ( .tx_ptp_ts_out(tx_ptp_ts_out), .tx_ptp_ts_step_out(tx_ptp_ts_step_out), .tx_ptp_locked(tx_ptp_locked), + .tx_ptp_ts_cor_sync(tx_ptp_ts_cor_sync), + .tx_ptp_ts_cor_val(tx_ptp_ts_cor_val), .rx_ptp_ts_out(rx_ptp_ts_out), .rx_ptp_ts_step_out(rx_ptp_ts_step_out), .rx_ptp_locked(rx_ptp_locked), + .rx_ptp_ts_cor_sync(rx_ptp_ts_cor_sync), + .rx_ptp_ts_cor_val(rx_ptp_ts_cor_val), /* * Statistics