From 0fd4000f6952cbed03e202846e8f9638f9e03864 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 13 Jun 2025 14:31:14 -0700 Subject: [PATCH] eth: Support both split and combined MAC/PCS in UltraScale wrapper Signed-off-by: Alex Forencich --- src/eth/rtl/us/taxi_eth_mac_25g_us.f | 2 + src/eth/rtl/us/taxi_eth_mac_25g_us.sv | 2 + src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv | 648 +++++++++++++----- src/eth/tb/taxi_eth_mac_25g_us/Makefile | 1 + .../test_taxi_eth_mac_25g_us.py | 31 +- .../test_taxi_eth_mac_25g_us.sv | 2 + 6 files changed, 490 insertions(+), 196 deletions(-) diff --git a/src/eth/rtl/us/taxi_eth_mac_25g_us.f b/src/eth/rtl/us/taxi_eth_mac_25g_us.f index c33b881..e5cd83a 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us.f +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us.f @@ -3,3 +3,5 @@ taxi_eth_mac_25g_us_ch.sv taxi_eth_phy_25g_us_gt.f taxi_eth_phy_25g_us_gt_ll.f ../taxi_eth_mac_phy_10g.f +../taxi_eth_mac_10g.f +../taxi_eth_phy_10g.f 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 9ec20c1..1d17ff9 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us.sv +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us.sv @@ -51,6 +51,7 @@ module taxi_eth_mac_25g_us # parameter logic [CNT-1:0] GT_RX_POLARITY = '0, // MAC/PHY parameters + parameter logic COMBINED_MAC_PCS = 1'b1, parameter logic PADDING_EN = 1'b1, parameter logic DIC_EN = 1'b1, parameter MIN_FRAME_LEN = 64, @@ -366,6 +367,7 @@ for (genvar n = 0; n < CNT; n = n + 1) begin : ch .GT_RX_POLARITY(GT_RX_POLARITY[n]), // MAC/PHY parameters + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), .PADDING_EN(PADDING_EN), .DIC_EN(DIC_EN), .MIN_FRAME_LEN(MIN_FRAME_LEN), 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 39b94a3..4a98895 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 @@ -51,6 +51,7 @@ module taxi_eth_mac_25g_us_ch # parameter logic GT_RX_POLARITY = 1'b0, // MAC/PHY parameters + parameter logic COMBINED_MAC_PCS = 1'b1, parameter logic PADDING_EN = 1'b1, parameter logic DIC_EN = 1'b1, parameter MIN_FRAME_LEN = 64, @@ -516,204 +517,475 @@ end else begin : gt end -taxi_eth_mac_phy_10g #( - .DATA_W(DATA_W), - .HDR_W(HDR_W), - .TX_GBX_IF_EN(CFG_LOW_LATENCY), - .RX_GBX_IF_EN(CFG_LOW_LATENCY), - .PADDING_EN(PADDING_EN), - .DIC_EN(DIC_EN), - .MIN_FRAME_LEN(MIN_FRAME_LEN), - .PTP_TS_EN(PTP_TS_EN), - .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), - .PTP_TS_W(PTP_TS_W), - .BIT_REVERSE(1'b1), - .SCRAMBLER_DISABLE(1'b0), - .PRBS31_EN(PRBS31_EN), - .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), - .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), - .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), - .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), - .COUNT_125US(COUNT_125US), - .PFC_EN(PFC_EN), - .PAUSE_EN(PAUSE_EN), - .STAT_EN(STAT_EN), - .STAT_TX_LEVEL(STAT_TX_LEVEL), - .STAT_RX_LEVEL(STAT_RX_LEVEL), - .STAT_ID_BASE(STAT_ID_BASE), - .STAT_UPDATE_PERIOD(STAT_UPDATE_PERIOD), - .STAT_STR_EN(STAT_STR_EN), - .STAT_PREFIX_STR(STAT_PREFIX_STR) -) -eth_mac_phy_10g_inst ( - .tx_clk(tx_clk), - .tx_rst(tx_rst_out), - .rx_clk(rx_clk), - .rx_rst(rx_rst_out), +if (COMBINED_MAC_PCS) begin : mac - /* - * Transmit interface (AXI stream) - */ - .s_axis_tx(s_axis_tx), - .m_axis_tx_cpl(m_axis_tx_cpl), + taxi_eth_mac_phy_10g #( + .DATA_W(DATA_W), + .HDR_W(HDR_W), + .TX_GBX_IF_EN(CFG_LOW_LATENCY), + .RX_GBX_IF_EN(CFG_LOW_LATENCY), + .PADDING_EN(PADDING_EN), + .DIC_EN(DIC_EN), + .MIN_FRAME_LEN(MIN_FRAME_LEN), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .BIT_REVERSE(1'b1), + .SCRAMBLER_DISABLE(1'b0), + .PRBS31_EN(PRBS31_EN), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), + .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), + .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), + .COUNT_125US(COUNT_125US), + .PFC_EN(PFC_EN), + .PAUSE_EN(PAUSE_EN), + .STAT_EN(STAT_EN), + .STAT_TX_LEVEL(STAT_TX_LEVEL), + .STAT_RX_LEVEL(STAT_RX_LEVEL), + .STAT_ID_BASE(STAT_ID_BASE), + .STAT_UPDATE_PERIOD(STAT_UPDATE_PERIOD), + .STAT_STR_EN(STAT_STR_EN), + .STAT_PREFIX_STR(STAT_PREFIX_STR) + ) + mac_phy_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst_out), + .rx_clk(rx_clk), + .rx_rst(rx_rst_out), - /* - * Receive interface (AXI stream) - */ - .m_axis_rx(m_axis_rx), + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(s_axis_tx), + .m_axis_tx_cpl(m_axis_tx_cpl), - /* - * Serdes interface - */ - .serdes_tx_data(serdes_tx_data), - .serdes_tx_data_valid(serdes_tx_data_valid), - .serdes_tx_hdr(serdes_tx_hdr), - .serdes_tx_hdr_valid(serdes_tx_hdr_valid), - .serdes_tx_gbx_req_sync(serdes_tx_gbx_req_sync), - .serdes_tx_gbx_req_stall(serdes_tx_gbx_req_stall), - .serdes_tx_gbx_sync(serdes_tx_gbx_sync), - .serdes_rx_data(serdes_rx_data), - .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_reset_req(rx_reset_req), + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(m_axis_rx), - /* - * PTP - */ - .tx_ptp_ts(tx_ptp_ts), - .rx_ptp_ts(rx_ptp_ts), + /* + * Serdes interface + */ + .serdes_tx_data(serdes_tx_data), + .serdes_tx_data_valid(serdes_tx_data_valid), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_tx_hdr_valid(serdes_tx_hdr_valid), + .serdes_tx_gbx_req_sync(serdes_tx_gbx_req_sync), + .serdes_tx_gbx_req_stall(serdes_tx_gbx_req_stall), + .serdes_tx_gbx_sync(serdes_tx_gbx_sync), + .serdes_rx_data(serdes_rx_data), + .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_reset_req(rx_reset_req), - /* - * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) - */ - .tx_lfc_req(tx_lfc_req), - .tx_lfc_resend(tx_lfc_resend), - .rx_lfc_en(rx_lfc_en), - .rx_lfc_req(rx_lfc_req), - .rx_lfc_ack(rx_lfc_ack), + /* + * PTP + */ + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) - */ - .tx_pfc_req(tx_pfc_req), - .tx_pfc_resend(tx_pfc_resend), - .rx_pfc_en(rx_pfc_en), - .rx_pfc_req(rx_pfc_req), - .rx_pfc_ack(rx_pfc_ack), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(tx_lfc_req), + .tx_lfc_resend(tx_lfc_resend), + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), - /* - * Pause interface - */ - .tx_lfc_pause_en(tx_lfc_pause_en), - .tx_pause_req(tx_pause_req), - .tx_pause_ack(tx_pause_ack), + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(tx_pfc_req), + .tx_pfc_resend(tx_pfc_resend), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), - /* - * Statistics - */ - .stat_clk(stat_clk), - .stat_rst(stat_rst), - .m_axis_stat(m_axis_stat), + /* + * Pause interface + */ + .tx_lfc_pause_en(tx_lfc_pause_en), + .tx_pause_req(tx_pause_req), + .tx_pause_ack(tx_pause_ack), - /* - * Status - */ - .tx_start_packet(tx_start_packet), - .stat_tx_byte(stat_tx_byte), - .stat_tx_pkt_len(stat_tx_pkt_len), - .stat_tx_pkt_ucast(stat_tx_pkt_ucast), - .stat_tx_pkt_mcast(stat_tx_pkt_mcast), - .stat_tx_pkt_bcast(stat_tx_pkt_bcast), - .stat_tx_pkt_vlan(stat_tx_pkt_vlan), - .stat_tx_pkt_good(stat_tx_pkt_good), - .stat_tx_pkt_bad(stat_tx_pkt_bad), - .stat_tx_err_oversize(stat_tx_err_oversize), - .stat_tx_err_user(stat_tx_err_user), - .stat_tx_err_underflow(stat_tx_err_underflow), - .rx_start_packet(rx_start_packet), - .rx_error_count(rx_error_count), - .rx_block_lock(rx_block_lock), - .rx_high_ber(rx_high_ber), - .rx_status(rx_status), - .stat_rx_byte(stat_rx_byte), - .stat_rx_pkt_len(stat_rx_pkt_len), - .stat_rx_pkt_fragment(stat_rx_pkt_fragment), - .stat_rx_pkt_jabber(stat_rx_pkt_jabber), - .stat_rx_pkt_ucast(stat_rx_pkt_ucast), - .stat_rx_pkt_mcast(stat_rx_pkt_mcast), - .stat_rx_pkt_bcast(stat_rx_pkt_bcast), - .stat_rx_pkt_vlan(stat_rx_pkt_vlan), - .stat_rx_pkt_good(stat_rx_pkt_good), - .stat_rx_pkt_bad(stat_rx_pkt_bad), - .stat_rx_err_oversize(stat_rx_err_oversize), - .stat_rx_err_bad_fcs(stat_rx_err_bad_fcs), - .stat_rx_err_bad_block(stat_rx_err_bad_block), - .stat_rx_err_framing(stat_rx_err_framing), - .stat_rx_err_preamble(stat_rx_err_preamble), - .stat_rx_fifo_drop(stat_rx_fifo_drop), - .stat_tx_mcf(stat_tx_mcf), - .stat_rx_mcf(stat_rx_mcf), - .stat_tx_lfc_pkt(stat_tx_lfc_pkt), - .stat_tx_lfc_xon(stat_tx_lfc_xon), - .stat_tx_lfc_xoff(stat_tx_lfc_xoff), - .stat_tx_lfc_paused(stat_tx_lfc_paused), - .stat_tx_pfc_pkt(stat_tx_pfc_pkt), - .stat_tx_pfc_xon(stat_tx_pfc_xon), - .stat_tx_pfc_xoff(stat_tx_pfc_xoff), - .stat_tx_pfc_paused(stat_tx_pfc_paused), - .stat_rx_lfc_pkt(stat_rx_lfc_pkt), - .stat_rx_lfc_xon(stat_rx_lfc_xon), - .stat_rx_lfc_xoff(stat_rx_lfc_xoff), - .stat_rx_lfc_paused(stat_rx_lfc_paused), - .stat_rx_pfc_pkt(stat_rx_pfc_pkt), - .stat_rx_pfc_xon(stat_rx_pfc_xon), - .stat_rx_pfc_xoff(stat_rx_pfc_xoff), - .stat_rx_pfc_paused(stat_rx_pfc_paused), + /* + * Statistics + */ + .stat_clk(stat_clk), + .stat_rst(stat_rst), + .m_axis_stat(m_axis_stat), - /* - * Configuration - */ - .cfg_tx_max_pkt_len(cfg_tx_max_pkt_len), - .cfg_tx_ifg(cfg_tx_ifg), - .cfg_tx_enable(cfg_tx_enable), - .cfg_rx_max_pkt_len(cfg_rx_max_pkt_len), - .cfg_rx_enable(cfg_rx_enable), - .cfg_tx_prbs31_enable(cfg_tx_prbs31_enable), - .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable), - .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), - .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), - .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), - .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), - .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), - .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), - .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), - .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), - .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), - .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), - .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), - .cfg_mcf_rx_forward(cfg_mcf_rx_forward), - .cfg_mcf_rx_enable(cfg_mcf_rx_enable), - .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), - .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), - .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), - .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), - .cfg_tx_lfc_en(cfg_tx_lfc_en), - .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), - .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), - .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), - .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), - .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), - .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), - .cfg_tx_pfc_en(cfg_tx_pfc_en), - .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), - .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), - .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), - .cfg_rx_lfc_en(cfg_rx_lfc_en), - .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), - .cfg_rx_pfc_en(cfg_rx_pfc_en) -); + /* + * Status + */ + .tx_start_packet(tx_start_packet), + .stat_tx_byte(stat_tx_byte), + .stat_tx_pkt_len(stat_tx_pkt_len), + .stat_tx_pkt_ucast(stat_tx_pkt_ucast), + .stat_tx_pkt_mcast(stat_tx_pkt_mcast), + .stat_tx_pkt_bcast(stat_tx_pkt_bcast), + .stat_tx_pkt_vlan(stat_tx_pkt_vlan), + .stat_tx_pkt_good(stat_tx_pkt_good), + .stat_tx_pkt_bad(stat_tx_pkt_bad), + .stat_tx_err_oversize(stat_tx_err_oversize), + .stat_tx_err_user(stat_tx_err_user), + .stat_tx_err_underflow(stat_tx_err_underflow), + .rx_start_packet(rx_start_packet), + .rx_error_count(rx_error_count), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber), + .rx_status(rx_status), + .stat_rx_byte(stat_rx_byte), + .stat_rx_pkt_len(stat_rx_pkt_len), + .stat_rx_pkt_fragment(stat_rx_pkt_fragment), + .stat_rx_pkt_jabber(stat_rx_pkt_jabber), + .stat_rx_pkt_ucast(stat_rx_pkt_ucast), + .stat_rx_pkt_mcast(stat_rx_pkt_mcast), + .stat_rx_pkt_bcast(stat_rx_pkt_bcast), + .stat_rx_pkt_vlan(stat_rx_pkt_vlan), + .stat_rx_pkt_good(stat_rx_pkt_good), + .stat_rx_pkt_bad(stat_rx_pkt_bad), + .stat_rx_err_oversize(stat_rx_err_oversize), + .stat_rx_err_bad_fcs(stat_rx_err_bad_fcs), + .stat_rx_err_bad_block(stat_rx_err_bad_block), + .stat_rx_err_framing(stat_rx_err_framing), + .stat_rx_err_preamble(stat_rx_err_preamble), + .stat_rx_fifo_drop(stat_rx_fifo_drop), + .stat_tx_mcf(stat_tx_mcf), + .stat_rx_mcf(stat_rx_mcf), + .stat_tx_lfc_pkt(stat_tx_lfc_pkt), + .stat_tx_lfc_xon(stat_tx_lfc_xon), + .stat_tx_lfc_xoff(stat_tx_lfc_xoff), + .stat_tx_lfc_paused(stat_tx_lfc_paused), + .stat_tx_pfc_pkt(stat_tx_pfc_pkt), + .stat_tx_pfc_xon(stat_tx_pfc_xon), + .stat_tx_pfc_xoff(stat_tx_pfc_xoff), + .stat_tx_pfc_paused(stat_tx_pfc_paused), + .stat_rx_lfc_pkt(stat_rx_lfc_pkt), + .stat_rx_lfc_xon(stat_rx_lfc_xon), + .stat_rx_lfc_xoff(stat_rx_lfc_xoff), + .stat_rx_lfc_paused(stat_rx_lfc_paused), + .stat_rx_pfc_pkt(stat_rx_pfc_pkt), + .stat_rx_pfc_xon(stat_rx_pfc_xon), + .stat_rx_pfc_xoff(stat_rx_pfc_xoff), + .stat_rx_pfc_paused(stat_rx_pfc_paused), + + /* + * Configuration + */ + .cfg_tx_max_pkt_len(cfg_tx_max_pkt_len), + .cfg_tx_ifg(cfg_tx_ifg), + .cfg_tx_enable(cfg_tx_enable), + .cfg_rx_max_pkt_len(cfg_rx_max_pkt_len), + .cfg_rx_enable(cfg_rx_enable), + .cfg_tx_prbs31_enable(cfg_tx_prbs31_enable), + .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable), + .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), + .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), + .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), + .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), + .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), + .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), + .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), + .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), + .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), + .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), + .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), + .cfg_mcf_rx_forward(cfg_mcf_rx_forward), + .cfg_mcf_rx_enable(cfg_mcf_rx_enable), + .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), + .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), + .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), + .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), + .cfg_tx_lfc_en(cfg_tx_lfc_en), + .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), + .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), + .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), + .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), + .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), + .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), + .cfg_tx_pfc_en(cfg_tx_pfc_en), + .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), + .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), + .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), + .cfg_rx_lfc_en(cfg_rx_lfc_en), + .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), + .cfg_rx_pfc_en(cfg_rx_pfc_en) + ); + +end else begin : mac + + if (CFG_LOW_LATENCY) + $fatal(0, "Split MAC/PCS does not currently support low latency mode"); + + localparam CTRL_W = DATA_W / 8; + + wire [DATA_W-1:0] xgmii_txd; + wire [CTRL_W-1:0] xgmii_txc; + wire xgmii_tx_valid = 1'b1; + wire [DATA_W-1:0] xgmii_rxd; + wire [CTRL_W-1:0] xgmii_rxc; + wire xgmii_rx_valid = 1'b1; + wire tx_gbx_req_sync; + wire tx_gbx_req_stall; + wire tx_gbx_sync = 1'b0; + + taxi_eth_phy_10g #( + .DATA_W(DATA_W), + .CTRL_W(CTRL_W), + .HDR_W(HDR_W), + .TX_GBX_IF_EN(CFG_LOW_LATENCY), + .RX_GBX_IF_EN(CFG_LOW_LATENCY), + .BIT_REVERSE(1'b1), + .SCRAMBLER_DISABLE(1'b0), + .PRBS31_EN(PRBS31_EN), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), + .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), + .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), + .COUNT_125US(COUNT_125US) + ) + phy_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst_out), + .rx_clk(rx_clk), + .rx_rst(rx_rst_out), + + /* + * XGMII interface + */ + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + .xgmii_tx_valid(xgmii_tx_valid), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + .xgmii_rx_valid(xgmii_rx_valid), + .tx_gbx_req_sync(tx_gbx_req_sync), + .tx_gbx_req_stall(tx_gbx_req_stall), + .tx_gbx_sync(tx_gbx_sync), + + /* + * SERDES interface + */ + .serdes_tx_data(serdes_tx_data), + .serdes_tx_data_valid(serdes_tx_data_valid), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_tx_hdr_valid(serdes_tx_hdr_valid), + .serdes_tx_gbx_req_sync(serdes_tx_gbx_req_sync), + .serdes_tx_gbx_req_stall(serdes_tx_gbx_req_stall), + .serdes_tx_gbx_sync(serdes_tx_gbx_sync), + .serdes_rx_data(serdes_rx_data), + .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_reset_req(rx_reset_req), + + /* + * Status + */ + .tx_bad_block(), + .rx_error_count(rx_error_count), + .rx_bad_block(), + .rx_sequence_error(), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber), + .rx_status(rx_status), + + /* + * Configuration + */ + .cfg_tx_prbs31_enable(cfg_tx_prbs31_enable), + .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable) + ); + + taxi_eth_mac_10g #( + .DATA_W(DATA_W), + .CTRL_W(CTRL_W), + // .TX_GBX_IF_EN(CFG_LOW_LATENCY), + // .RX_GBX_IF_EN(CFG_LOW_LATENCY), + .PADDING_EN(PADDING_EN), + .DIC_EN(DIC_EN), + .MIN_FRAME_LEN(MIN_FRAME_LEN), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .PFC_EN(PFC_EN), + .PAUSE_EN(PAUSE_EN), + .STAT_EN(STAT_EN), + .STAT_TX_LEVEL(STAT_TX_LEVEL), + .STAT_RX_LEVEL(STAT_RX_LEVEL), + .STAT_ID_BASE(STAT_ID_BASE), + .STAT_UPDATE_PERIOD(STAT_UPDATE_PERIOD), + .STAT_STR_EN(STAT_STR_EN), + .STAT_PREFIX_STR(STAT_PREFIX_STR) + ) + mac_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst_out), + .rx_clk(rx_clk), + .rx_rst(rx_rst_out), + + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(s_axis_tx), + .m_axis_tx_cpl(m_axis_tx_cpl), + + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(m_axis_rx), + + /* + * XGMII interface + */ + .xgmii_txd(xgmii_txd), + .xgmii_txc(xgmii_txc), + // .xgmii_tx_valid(xgmii_tx_valid), + .xgmii_rxd(xgmii_rxd), + .xgmii_rxc(xgmii_rxc), + // .xgmii_rx_valid(xgmii_rx_valid), + // .tx_gbx_req_sync(tx_gbx_req_sync), + // .tx_gbx_req_stall(tx_gbx_req_stall), + // .tx_gbx_sync(tx_gbx_sync), + + /* + * PTP + */ + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(tx_lfc_req), + .tx_lfc_resend(tx_lfc_resend), + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(tx_pfc_req), + .tx_pfc_resend(tx_pfc_resend), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + + /* + * Pause interface + */ + .tx_lfc_pause_en(tx_lfc_pause_en), + .tx_pause_req(tx_pause_req), + .tx_pause_ack(tx_pause_ack), + + /* + * Statistics + */ + .stat_clk(stat_clk), + .stat_rst(stat_rst), + .m_axis_stat(m_axis_stat), + + /* + * Status + */ + .tx_start_packet(tx_start_packet), + .stat_tx_byte(stat_tx_byte), + .stat_tx_pkt_len(stat_tx_pkt_len), + .stat_tx_pkt_ucast(stat_tx_pkt_ucast), + .stat_tx_pkt_mcast(stat_tx_pkt_mcast), + .stat_tx_pkt_bcast(stat_tx_pkt_bcast), + .stat_tx_pkt_vlan(stat_tx_pkt_vlan), + .stat_tx_pkt_good(stat_tx_pkt_good), + .stat_tx_pkt_bad(stat_tx_pkt_bad), + .stat_tx_err_oversize(stat_tx_err_oversize), + .stat_tx_err_user(stat_tx_err_user), + .stat_tx_err_underflow(stat_tx_err_underflow), + .rx_start_packet(rx_start_packet), + .stat_rx_byte(stat_rx_byte), + .stat_rx_pkt_len(stat_rx_pkt_len), + .stat_rx_pkt_fragment(stat_rx_pkt_fragment), + .stat_rx_pkt_jabber(stat_rx_pkt_jabber), + .stat_rx_pkt_ucast(stat_rx_pkt_ucast), + .stat_rx_pkt_mcast(stat_rx_pkt_mcast), + .stat_rx_pkt_bcast(stat_rx_pkt_bcast), + .stat_rx_pkt_vlan(stat_rx_pkt_vlan), + .stat_rx_pkt_good(stat_rx_pkt_good), + .stat_rx_pkt_bad(stat_rx_pkt_bad), + .stat_rx_err_oversize(stat_rx_err_oversize), + .stat_rx_err_bad_fcs(stat_rx_err_bad_fcs), + .stat_rx_err_bad_block(stat_rx_err_bad_block), + .stat_rx_err_framing(stat_rx_err_framing), + .stat_rx_err_preamble(stat_rx_err_preamble), + .stat_rx_fifo_drop(stat_rx_fifo_drop), + .stat_tx_mcf(stat_tx_mcf), + .stat_rx_mcf(stat_rx_mcf), + .stat_tx_lfc_pkt(stat_tx_lfc_pkt), + .stat_tx_lfc_xon(stat_tx_lfc_xon), + .stat_tx_lfc_xoff(stat_tx_lfc_xoff), + .stat_tx_lfc_paused(stat_tx_lfc_paused), + .stat_tx_pfc_pkt(stat_tx_pfc_pkt), + .stat_tx_pfc_xon(stat_tx_pfc_xon), + .stat_tx_pfc_xoff(stat_tx_pfc_xoff), + .stat_tx_pfc_paused(stat_tx_pfc_paused), + .stat_rx_lfc_pkt(stat_rx_lfc_pkt), + .stat_rx_lfc_xon(stat_rx_lfc_xon), + .stat_rx_lfc_xoff(stat_rx_lfc_xoff), + .stat_rx_lfc_paused(stat_rx_lfc_paused), + .stat_rx_pfc_pkt(stat_rx_pfc_pkt), + .stat_rx_pfc_xon(stat_rx_pfc_xon), + .stat_rx_pfc_xoff(stat_rx_pfc_xoff), + .stat_rx_pfc_paused(stat_rx_pfc_paused), + + /* + * Configuration + */ + .cfg_tx_max_pkt_len(cfg_tx_max_pkt_len), + .cfg_tx_ifg(cfg_tx_ifg), + .cfg_tx_enable(cfg_tx_enable), + .cfg_rx_max_pkt_len(cfg_rx_max_pkt_len), + .cfg_rx_enable(cfg_rx_enable), + .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), + .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), + .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), + .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), + .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), + .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), + .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), + .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), + .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), + .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), + .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), + .cfg_mcf_rx_forward(cfg_mcf_rx_forward), + .cfg_mcf_rx_enable(cfg_mcf_rx_enable), + .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), + .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), + .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), + .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), + .cfg_tx_lfc_en(cfg_tx_lfc_en), + .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), + .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), + .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), + .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), + .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), + .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), + .cfg_tx_pfc_en(cfg_tx_pfc_en), + .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), + .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), + .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), + .cfg_rx_lfc_en(cfg_rx_lfc_en), + .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), + .cfg_rx_pfc_en(cfg_rx_pfc_en) + ); + +end endmodule diff --git a/src/eth/tb/taxi_eth_mac_25g_us/Makefile b/src/eth/tb/taxi_eth_mac_25g_us/Makefile index dd857b2..e79c29f 100644 --- a/src/eth/tb/taxi_eth_mac_25g_us/Makefile +++ b/src/eth/tb/taxi_eth_mac_25g_us/Makefile @@ -42,6 +42,7 @@ export PARAM_QPLL0_PD := 0 export PARAM_QPLL1_PD := 1 export PARAM_QPLL0_EXT_CTRL := 0 export PARAM_QPLL1_EXT_CTRL := 0 +export PARAM_COMBINED_MAC_PCS := 1 export PARAM_PADDING_EN := 1 export PARAM_DIC_EN := 1 export PARAM_MIN_FRAME_LEN := 64 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 41bb080..60c542d 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 @@ -173,6 +173,11 @@ class TB: async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg=12): + if dut.COMBINED_MAC_PCS.value: + pipe_delay = 4 + else: + pipe_delay = 5 + tb = TB(dut) tb.serdes_sources[port].ifg = ifg @@ -219,12 +224,12 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg= tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns) tb.log.info("Difference: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns)) - tb.log.info("Error: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*4)) + tb.log.info("Error: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay)) assert rx_frame.tdata == test_data assert frame_error == 0 if not tb.serdes_sources[port].gbx_seq_len: - assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*4) < 0.01 + assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period[port]*pipe_delay) < 0.01 assert tb.axis_sinks[port].empty() @@ -234,6 +239,11 @@ async def run_test_rx(dut, port=0, payload_lengths=None, payload_data=None, ifg= async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg=12): + if dut.COMBINED_MAC_PCS.value: + pipe_delay = 5 + else: + pipe_delay = 5 + tb = TB(dut) tb.serdes_sources[port].ifg = ifg @@ -271,13 +281,13 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg= tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns) tb.log.info("Difference: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns)) - tb.log.info("Error: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*5)) + tb.log.info("Error: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay)) 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: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*5) < 0.01 + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01 assert tb.serdes_sinks[port].empty() @@ -289,6 +299,11 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12): dic_en = int(cocotb.top.DIC_EN.value) + if dut.COMBINED_MAC_PCS.value: + pipe_delay = 5 + else: + pipe_delay = 5 + tb = TB(dut) byte_width = tb.axis_sources[port].width // 8 @@ -339,7 +354,7 @@ async def run_test_tx_alignment(dut, port=0, payload_data=None, ifg=12): assert rx_frame.check_fcs() assert rx_frame.ctrl is None if not tb.serdes_sinks[port].gbx_seq_len: - assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*5) < 0.01 + assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period[port]*pipe_delay) < 0.01 start_lane.append(rx_frame.start_lane) @@ -896,9 +911,8 @@ def process_f_files(files): @pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)]) -@pytest.mark.parametrize("low_latency", [1, 0]) -@pytest.mark.parametrize("data_w", [64]) -def test_taxi_eth_mac_25g_us(request, data_w, low_latency, dic_en, pfc_en): +@pytest.mark.parametrize(("low_latency", "combined_mac_pcs"), [(1, 1), (0, 1), (0, 0)]) +def test_taxi_eth_mac_25g_us(request, combined_mac_pcs, low_latency, dic_en, pfc_en): dut = "taxi_eth_mac_25g_us" module = os.path.splitext(os.path.basename(__file__))[0] toplevel = module @@ -922,6 +936,7 @@ def test_taxi_eth_mac_25g_us(request, data_w, low_latency, dic_en, pfc_en): parameters['QPLL1_PD'] = 1 parameters['QPLL0_EXT_CTRL'] = 0 parameters['QPLL1_EXT_CTRL'] = 0 + parameters['COMBINED_MAC_PCS'] = combined_mac_pcs parameters['PADDING_EN'] = 1 parameters['DIC_EN'] = dic_en parameters['MIN_FRAME_LEN'] = 64 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 d6d2fd5..689ddcb 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 @@ -41,6 +41,7 @@ module test_taxi_eth_mac_25g_us # parameter logic [CNT-1:0] GT_RX_QPLL_SEL = '0, parameter logic [CNT-1:0] GT_RX_LPM_EN = '0, parameter logic [CNT-1:0] GT_RX_POLARITY = '0, + parameter logic COMBINED_MAC_PCS = 1'b1, parameter logic PADDING_EN = 1'b1, parameter logic DIC_EN = 1'b1, parameter MIN_FRAME_LEN = 64, @@ -245,6 +246,7 @@ taxi_eth_mac_25g_us #( .GT_RX_QPLL_SEL(GT_RX_QPLL_SEL), .GT_RX_LPM_EN(GT_RX_LPM_EN), .GT_RX_POLARITY(GT_RX_POLARITY), + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), .PADDING_EN(PADDING_EN), .DIC_EN(DIC_EN), .MIN_FRAME_LEN(MIN_FRAME_LEN),