From e42f11f1fbd98f7bbb41540e8243eb236350b37c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 8 Jun 2026 21:11:56 -0700 Subject: [PATCH] eth: Update KCU105 example design to use BASE-X core for 1G Signed-off-by: Alex Forencich --- src/eth/example/KCU105/fpga/fpga_1g/Makefile | 5 +- .../KCU105/fpga/ip/basex_pcs_pma_0.tcl | 21 - .../KCU105/fpga/ip/basex_pcs_pma_1.tcl | 21 - src/eth/example/KCU105/fpga/rtl/fpga.sv | 210 +----- src/eth/example/KCU105/fpga/rtl/fpga_core.sv | 615 ++++++++++-------- .../example/KCU105/fpga/tb/fpga_core/Makefile | 1 + .../example/KCU105/fpga/tb/fpga_core/basex.py | 1 + .../fpga/tb/fpga_core/test_fpga_core.py | 115 ++-- 8 files changed, 383 insertions(+), 606 deletions(-) delete mode 100644 src/eth/example/KCU105/fpga/ip/basex_pcs_pma_0.tcl delete mode 100644 src/eth/example/KCU105/fpga/ip/basex_pcs_pma_1.tcl create mode 120000 src/eth/example/KCU105/fpga/tb/fpga_core/basex.py diff --git a/src/eth/example/KCU105/fpga/fpga_1g/Makefile b/src/eth/example/KCU105/fpga/fpga_1g/Makefile index 87b9e89..7a5fb30 100644 --- a/src/eth/example/KCU105/fpga/fpga_1g/Makefile +++ b/src/eth/example/KCU105/fpga/fpga_1g/Makefile @@ -19,9 +19,11 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src SYN_FILES = $(RTL_DIR)/fpga.sv SYN_FILES += $(RTL_DIR)/fpga_core.sv SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f +SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_1g_basex_us.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_i2c_master.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv @@ -40,8 +42,7 @@ XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl # IP IP_TCL_FILES = ../ip/sgmii_pcs_pma_0.tcl -IP_TCL_FILES += ../ip/basex_pcs_pma_0.tcl -IP_TCL_FILES += ../ip/basex_pcs_pma_1.tcl +IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_1g_basex_us_gth_156.tcl # Configuration CONFIG_TCL_FILES = ./config.tcl diff --git a/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_0.tcl b/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_0.tcl deleted file mode 100644 index 43a289a..0000000 --- a/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_0.tcl +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: MIT -# -# Copyright (c) 2025 FPGA Ninja, LLC -# -# Authors: -# - Alex Forencich -# - -create_ip -name gig_ethernet_pcs_pma -vendor xilinx.com -library ip -module_name basex_pcs_pma_0 - -set_property -dict [list \ - CONFIG.Standard {1000BASEX} \ - CONFIG.Physical_Interface {Transceiver} \ - CONFIG.Management_Interface {false} \ - CONFIG.Auto_Negotiation {false} \ - CONFIG.TransceiverControl {false} \ - CONFIG.RefClkRate {156.25} \ - CONFIG.DrpClkRate {62.5} \ - CONFIG.SupportLevel {Include_Shared_Logic_in_Core} \ - CONFIG.GT_Location {X0Y10} \ -] [get_ips basex_pcs_pma_0] diff --git a/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_1.tcl b/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_1.tcl deleted file mode 100644 index bca6438..0000000 --- a/src/eth/example/KCU105/fpga/ip/basex_pcs_pma_1.tcl +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: MIT -# -# Copyright (c) 2025 FPGA Ninja, LLC -# -# Authors: -# - Alex Forencich -# - -create_ip -name gig_ethernet_pcs_pma -vendor xilinx.com -library ip -module_name basex_pcs_pma_1 - -set_property -dict [list \ - CONFIG.Standard {1000BASEX} \ - CONFIG.Physical_Interface {Transceiver} \ - CONFIG.Management_Interface {false} \ - CONFIG.Auto_Negotiation {false} \ - CONFIG.TransceiverControl {false} \ - CONFIG.RefClkRate {156.25} \ - CONFIG.DrpClkRate {62.5} \ - CONFIG.SupportLevel {Include_Shared_Logic_in_Example_Design} \ - CONFIG.GT_Location {X0Y9} \ -] [get_ips basex_pcs_pma_1] diff --git a/src/eth/example/KCU105/fpga/rtl/fpga.sv b/src/eth/example/KCU105/fpga/rtl/fpga.sv index 2e8941b..5fbb14a 100644 --- a/src/eth/example/KCU105/fpga/rtl/fpga.sv +++ b/src/eth/example/KCU105/fpga/rtl/fpga.sv @@ -370,194 +370,10 @@ eth_pcspma ( .signal_detect (1'b1) ); -// SFP+ -wire sfp_tx_p_int[2]; -wire sfp_tx_n_int[2]; - -wire sfp0_gmii_clk_int; -wire sfp0_gmii_rst_int; -wire sfp0_gmii_clk_en_int = 1'b1; -wire [7:0] sfp0_gmii_txd_int; -wire sfp0_gmii_tx_en_int; -wire sfp0_gmii_tx_er_int; -wire [7:0] sfp0_gmii_rxd_int; -wire sfp0_gmii_rx_dv_int; -wire sfp0_gmii_rx_er_int; - -wire [15:0] sfp0_status_vect; - -wire sfp1_gmii_clk_int; -wire sfp1_gmii_rst_int; -wire sfp1_gmii_clk_en_int = 1'b1; -wire [7:0] sfp1_gmii_txd_int; -wire sfp1_gmii_tx_en_int; -wire sfp1_gmii_tx_er_int; -wire [7:0] sfp1_gmii_rxd_int; -wire sfp1_gmii_rx_dv_int; -wire sfp1_gmii_rx_er_int; - -wire [15:0] sfp1_status_vect; - -if (SFP_RATE == 0) begin : sfp_phy - // 1000BASE-X - - wire sfp0_gmii_gtrefclk; - wire sfp0_gmii_txuserclk; - wire sfp0_gmii_txuserclk2; - wire sfp0_gmii_rxuserclk; - wire sfp0_gmii_rxuserclk2; - wire sfp0_gmii_resetdone; - wire sfp0_gmii_pmareset; - wire sfp0_gmii_mmcm_locked; - - assign sfp0_gmii_clk_int = sfp0_gmii_txuserclk2; - - taxi_sync_reset #( - .N(4) - ) - sync_reset_sfp0_inst ( - .clk(sfp0_gmii_clk_int), - .rst(rst_125mhz_int || !sfp0_gmii_resetdone), - .out(sfp0_gmii_rst_int) - ); - - wire sfp0_status_link_status = sfp0_status_vect[0]; - wire sfp0_status_link_synchronization = sfp0_status_vect[1]; - wire sfp0_status_rudi_c = sfp0_status_vect[2]; - wire sfp0_status_rudi_i = sfp0_status_vect[3]; - wire sfp0_status_rudi_invalid = sfp0_status_vect[4]; - wire sfp0_status_rxdisperr = sfp0_status_vect[5]; - wire sfp0_status_rxnotintable = sfp0_status_vect[6]; - wire sfp0_status_phy_link_status = sfp0_status_vect[7]; - wire [1:0] sfp0_status_remote_fault_encdg = sfp0_status_vect[9:8]; - wire [1:0] sfp0_status_speed = sfp0_status_vect[11:10]; - wire sfp0_status_duplex = sfp0_status_vect[12]; - wire sfp0_status_remote_fault = sfp0_status_vect[13]; - wire [1:0] sfp0_status_pause = sfp0_status_vect[15:14]; - - wire [4:0] sfp0_config_vect; - - assign sfp0_config_vect[4] = 1'b0; // autonegotiation enable - assign sfp0_config_vect[3] = 1'b0; // isolate - assign sfp0_config_vect[2] = 1'b0; // power down - assign sfp0_config_vect[1] = 1'b0; // loopback enable - assign sfp0_config_vect[0] = 1'b0; // unidirectional enable - - basex_pcs_pma_0 - sfp0_pcspma ( - .gtrefclk_p(sfp_mgt_refclk_0_p), - .gtrefclk_n(sfp_mgt_refclk_0_n), - .gtrefclk_out(sfp0_gmii_gtrefclk), - .txn(sfp_tx_n[0]), - .txp(sfp_tx_p[0]), - .rxn(sfp_rx_n[0]), - .rxp(sfp_rx_p[0]), - .independent_clock_bufg(clk_62mhz_int), - .userclk_out(sfp0_gmii_txuserclk), - .userclk2_out(sfp0_gmii_txuserclk2), - .rxuserclk_out(sfp0_gmii_rxuserclk), - .rxuserclk2_out(sfp0_gmii_rxuserclk2), - .gtpowergood(), - .resetdone(sfp0_gmii_resetdone), - .pma_reset_out(sfp0_gmii_pmareset), - .mmcm_locked_out(sfp0_gmii_mmcm_locked), - .gmii_txd(sfp0_gmii_txd_int), - .gmii_tx_en(sfp0_gmii_tx_en_int), - .gmii_tx_er(sfp0_gmii_tx_er_int), - .gmii_rxd(sfp0_gmii_rxd_int), - .gmii_rx_dv(sfp0_gmii_rx_dv_int), - .gmii_rx_er(sfp0_gmii_rx_er_int), - .gmii_isolate(), - .configuration_vector(sfp0_config_vect), - .status_vector(sfp0_status_vect), - .reset(rst_125mhz_int), - .signal_detect(1'b1) - ); - - wire sfp1_gmii_txuserclk2 = sfp0_gmii_txuserclk2; - wire sfp1_gmii_resetdone; - - assign sfp1_gmii_clk_int = sfp1_gmii_txuserclk2; - - taxi_sync_reset #( - .N(4) - ) - sync_reset_sfp1_inst ( - .clk(sfp1_gmii_clk_int), - .rst(rst_125mhz_int || !sfp1_gmii_resetdone), - .out(sfp1_gmii_rst_int) - ); - - wire sfp1_status_link_status = sfp1_status_vect[0]; - wire sfp1_status_link_synchronization = sfp1_status_vect[1]; - wire sfp1_status_rudi_c = sfp1_status_vect[2]; - wire sfp1_status_rudi_i = sfp1_status_vect[3]; - wire sfp1_status_rudi_invalid = sfp1_status_vect[4]; - wire sfp1_status_rxdisperr = sfp1_status_vect[5]; - wire sfp1_status_rxnotintable = sfp1_status_vect[6]; - wire sfp1_status_phy_link_status = sfp1_status_vect[7]; - wire [1:0] sfp1_status_remote_fault_encdg = sfp1_status_vect[9:8]; - wire [1:0] sfp1_status_speed = sfp1_status_vect[11:10]; - wire sfp1_status_duplex = sfp1_status_vect[12]; - wire sfp1_status_remote_fault = sfp1_status_vect[13]; - wire [1:0] sfp1_status_pause = sfp1_status_vect[15:14]; - - wire [4:0] sfp1_config_vect; - - assign sfp1_config_vect[4] = 1'b0; // autonegotiation enable - assign sfp1_config_vect[3] = 1'b0; // isolate - assign sfp1_config_vect[2] = 1'b0; // power down - assign sfp1_config_vect[1] = 1'b0; // loopback enable - assign sfp1_config_vect[0] = 1'b0; // unidirectional enable - - basex_pcs_pma_1 - sfp1_pcspma ( - .gtrefclk(sfp0_gmii_gtrefclk), - .txn(sfp_tx_n[1]), - .txp(sfp_tx_p[1]), - .rxn(sfp_rx_n[1]), - .rxp(sfp_rx_p[1]), - .independent_clock_bufg(clk_62mhz_int), - .txoutclk(), - .gtpowergood(), - .rxoutclk(), - .resetdone(sfp1_gmii_resetdone), - .cplllock(), - .mmcm_reset(), - .userclk(sfp0_gmii_txuserclk), - .userclk2(sfp0_gmii_txuserclk2), - .pma_reset(sfp0_gmii_pmareset), - .mmcm_locked(sfp0_gmii_mmcm_locked), - .rxuserclk(sfp0_gmii_txuserclk), - .rxuserclk2(sfp0_gmii_txuserclk2), - .gmii_txd(sfp1_gmii_txd_int), - .gmii_tx_en(sfp1_gmii_tx_en_int), - .gmii_tx_er(sfp1_gmii_tx_er_int), - .gmii_rxd(sfp1_gmii_rxd_int), - .gmii_rx_dv(sfp1_gmii_rx_dv_int), - .gmii_rx_er(sfp1_gmii_rx_er_int), - .gmii_isolate(), - .configuration_vector(sfp1_config_vect), - .status_vector(sfp1_status_vect), - .reset(rst_125mhz_int), - .signal_detect(1'b1) - ); - -end else begin - // 10GBASE-R - - assign sfp_tx_p = sfp_tx_p_int; - assign sfp_tx_n = sfp_tx_n_int; - -end - // SGMII interface debug: // SW12:1 (sw[3]) off for payload byte, on for status vector -// SW12:2 (sw[2]) off for BASE-T port (SGMII), on for SFP -// SW12:3 (sw[1]) off for SFP0, on for SFP1 // SW12:4 (sw[0]) off for LSB of status vector, on for MSB -wire [15:0] sel_sv = sw[2] ? (sw[1] ? sfp1_status_vect : sfp0_status_vect) : sgmii_status_vect; -assign led = sw[3] ? (sw[0] ? sel_sv[15:8] : sel_sv[7:0]) : led_int; +assign led = sw[3] ? (sw[0] ? sgmii_status_vect[15:8] : sgmii_status_vect[7:0]) : led_int; fpga_core #( .SIM(SIM), @@ -620,31 +436,11 @@ core_inst ( */ .sfp_rx_p(sfp_rx_p), .sfp_rx_n(sfp_rx_n), - .sfp_tx_p(sfp_tx_p_int), - .sfp_tx_n(sfp_tx_n_int), + .sfp_tx_p(sfp_tx_p), + .sfp_tx_n(sfp_tx_n), .sfp_mgt_refclk_0_p(sfp_mgt_refclk_0_p), .sfp_mgt_refclk_0_n(sfp_mgt_refclk_0_n), - .sfp0_gmii_clk(sfp0_gmii_clk_int), - .sfp0_gmii_rst(sfp0_gmii_rst_int), - .sfp0_gmii_clk_en(sfp0_gmii_clk_en_int), - .sfp0_gmii_rxd(sfp0_gmii_rxd_int), - .sfp0_gmii_rx_dv(sfp0_gmii_rx_dv_int), - .sfp0_gmii_rx_er(sfp0_gmii_rx_er_int), - .sfp0_gmii_txd(sfp0_gmii_txd_int), - .sfp0_gmii_tx_en(sfp0_gmii_tx_en_int), - .sfp0_gmii_tx_er(sfp0_gmii_tx_er_int), - - .sfp1_gmii_clk(sfp1_gmii_clk_int), - .sfp1_gmii_rst(sfp1_gmii_rst_int), - .sfp1_gmii_clk_en(sfp1_gmii_clk_en_int), - .sfp1_gmii_rxd(sfp1_gmii_rxd_int), - .sfp1_gmii_rx_dv(sfp1_gmii_rx_dv_int), - .sfp1_gmii_rx_er(sfp1_gmii_rx_er_int), - .sfp1_gmii_txd(sfp1_gmii_txd_int), - .sfp1_gmii_tx_en(sfp1_gmii_tx_en_int), - .sfp1_gmii_tx_er(sfp1_gmii_tx_er_int), - .sfp_tx_disable_b(sfp_tx_disable_b), .sfp_rx_los(sfp_rx_los) ); diff --git a/src/eth/example/KCU105/fpga/rtl/fpga_core.sv b/src/eth/example/KCU105/fpga/rtl/fpga_core.sv index e91943c..6bb5060 100644 --- a/src/eth/example/KCU105/fpga/rtl/fpga_core.sv +++ b/src/eth/example/KCU105/fpga/rtl/fpga_core.sv @@ -86,26 +86,6 @@ module fpga_core # input wire logic sfp_mgt_refclk_0_p, input wire logic sfp_mgt_refclk_0_n, - input wire logic sfp0_gmii_clk, - input wire logic sfp0_gmii_rst, - input wire logic sfp0_gmii_clk_en, - input wire logic [7:0] sfp0_gmii_rxd, - input wire logic sfp0_gmii_rx_dv, - input wire logic sfp0_gmii_rx_er, - output wire logic [7:0] sfp0_gmii_txd, - output wire logic sfp0_gmii_tx_en, - output wire logic sfp0_gmii_tx_er, - - input wire logic sfp1_gmii_clk, - input wire logic sfp1_gmii_rst, - input wire logic sfp1_gmii_clk_en, - input wire logic [7:0] sfp1_gmii_rxd, - input wire logic sfp1_gmii_rx_dv, - input wire logic sfp1_gmii_rx_er, - output wire logic [7:0] sfp1_gmii_txd, - output wire logic sfp1_gmii_tx_en, - output wire logic sfp1_gmii_tx_er, - output wire logic [1:0] sfp_tx_disable_b, input wire logic [1:0] sfp_rx_los ); @@ -143,7 +123,7 @@ xfcp_if_uart_inst ( .prescale(16'(125000000/921600)) ); -localparam XFCP_PORTS = SFP_RATE ? 3 : 2; +localparam XFCP_PORTS = 3; taxi_axis_if #(.DATA_W(8), .USER_EN(1), .USER_W(1)) xfcp_sw_ds[XFCP_PORTS](), xfcp_sw_us[XFCP_PORTS](); @@ -195,7 +175,7 @@ xfcp_stats_inst ( .s_axis_stat(axis_stat) ); -taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[SFP_RATE ? 2 : 3](); +taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[2](); taxi_axis_arb_mux #( .S_COUNT($size(axis_eth_stat)), @@ -333,63 +313,221 @@ eth_mac_inst ( // SFP+ assign sfp_tx_disable_b = '1; +wire sfp_tx_clk[2]; +wire sfp_tx_rst[2]; +wire sfp_rx_clk[2]; +wire sfp_rx_rst[2]; + +wire sfp_rx_status[2]; + +wire sfp_gtpowergood; + +wire sfp_mgt_refclk_0; +wire sfp_mgt_refclk_0_int; +wire sfp_mgt_refclk_0_bufg; + +wire sfp_rst; + +localparam SFP_DATA_W = SFP_RATE ? 32 : 16; + +taxi_axis_if #(.DATA_W(SFP_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_tx[2](); +taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl[2](); +taxi_axis_if #(.DATA_W(SFP_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_rx[2](); + +if (SIM) begin + + assign sfp_mgt_refclk_0 = sfp_mgt_refclk_0_p; + assign sfp_mgt_refclk_0_int = sfp_mgt_refclk_0_p; + assign sfp_mgt_refclk_0_bufg = sfp_mgt_refclk_0_int; + +end else begin + + IBUFDS_GTE3 ibufds_gte3_sfp_mgt_refclk_0_inst ( + .I (sfp_mgt_refclk_0_p), + .IB (sfp_mgt_refclk_0_n), + .CEB (1'b0), + .O (sfp_mgt_refclk_0), + .ODIV2 (sfp_mgt_refclk_0_int) + ); + + BUFG_GT bufg_gt_sfp_mgt_refclk_0_inst ( + .CE (sfp_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (sfp_mgt_refclk_0_int), + .O (sfp_mgt_refclk_0_bufg) + ); + +end + +taxi_sync_reset #( + .N(4) +) +sfp_sync_reset_inst ( + .clk(sfp_mgt_refclk_0_bufg), + .rst(rst), + .out(sfp_rst) +); + +taxi_apb_if #( + .ADDR_W(18), + .DATA_W(16) +) +gt_apb_ctrl(); + +taxi_xfcp_mod_apb #( + .XFCP_EXT_ID_STR("GTH CTRL") +) +xfcp_mod_apb_inst ( + .clk(clk), + .rst(rst), + + /* + * XFCP upstream port + */ + .xfcp_usp_ds(xfcp_sw_ds[2]), + .xfcp_usp_us(xfcp_sw_us[2]), + + /* + * APB master interface + */ + .m_apb(gt_apb_ctrl) +); + if (SFP_RATE == 0) begin : sfp_mac - taxi_axis_if #(.DATA_W(8), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp0_eth(); - taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp0_tx_cpl(); + taxi_eth_mac_1g_basex_us #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), - taxi_axis_if #(.DATA_W(8), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp1_eth(); - taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp1_tx_cpl(); + .CNT(2), - taxi_eth_mac_1g_fifo #( + // GT config + .CFG_LOW_LATENCY(1), + + // GT type + .GT_TYPE("GTH"), + + // PHY parameters + .DIC_EN(1'b1), + .PTP_TS_EN(1'b0), + .PTP_TD_EN(1'b0), + .PTP_TS_FMT_TOD(1'b1), + .PTP_TS_W(96), + .PTP_TD_SDI_PIPELINE(2), + .PRBS31_EN(1'b0), + .TX_SERDES_PIPELINE(1), + .RX_SERDES_PIPELINE(1), + .COUNT_125US(125000/6.4), .STAT_EN(1), .STAT_TX_LEVEL(1), .STAT_RX_LEVEL(1), - .STAT_ID_BASE((16+16)+(16+16)*0), - .STAT_UPDATE_PERIOD(1024), - .STAT_STR_EN(1), - .STAT_PREFIX_STR("SFP0"), - .TX_FIFO_DEPTH(16384), - .TX_FRAME_FIFO(1), - .RX_FIFO_DEPTH(16384), - .RX_FRAME_FIFO(1) + .STAT_ID_BASE(16+16), + .STAT_UPDATE_PERIOD(1024)//, + // disabled due to verilator bug + // .STAT_STR_EN(1), + // .STAT_PREFIX_STR('{"SFP0", "SFP1"}) ) - sfp0_eth_mac_inst ( - .rx_clk(sfp0_gmii_clk), - .rx_rst(sfp0_gmii_rst), - .tx_clk(sfp0_gmii_clk), - .tx_rst(sfp0_gmii_rst), - .logic_clk(clk), - .logic_rst(rst), + sfp_mac_inst ( + .xcvr_ctrl_clk(clk), + .xcvr_ctrl_rst(sfp_rst), + + /* + * Transceiver control + */ + .s_apb_ctrl(gt_apb_ctrl), + + /* + * Common + */ + .xcvr_gtpowergood_out(sfp_gtpowergood), + .xcvr_gtrefclk00_in(sfp_mgt_refclk_0), + .xcvr_qpll0pd_in(1'b0), + .xcvr_qpll0reset_in(1'b0), + .xcvr_qpll0pcierate_in(3'd0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0clk_out(), + .xcvr_qpll0refclk_out(), + .xcvr_gtrefclk01_in(sfp_mgt_refclk_0), + .xcvr_qpll1pd_in(1'b0), + .xcvr_qpll1reset_in(1'b0), + .xcvr_qpll1pcierate_in(3'd0), + .xcvr_qpll1lock_out(), + .xcvr_qpll1clk_out(), + .xcvr_qpll1refclk_out(), + + /* + * Serial data + */ + .xcvr_txp(sfp_tx_p), + .xcvr_txn(sfp_tx_n), + .xcvr_rxp(sfp_rx_p), + .xcvr_rxn(sfp_rx_n), + + /* + * MAC clocks + */ + .rx_clk(sfp_rx_clk), + .rx_rst_in('{2{1'b0}}), + .rx_rst_out(sfp_rx_rst), + .tx_clk(sfp_tx_clk), + .tx_rst_in('{2{1'b0}}), + .tx_rst_out(sfp_tx_rst), /* * Transmit interface (AXI stream) */ - .s_axis_tx(axis_sfp0_eth), - .m_axis_tx_cpl(axis_sfp0_tx_cpl), + .s_axis_tx(axis_sfp_tx), + .m_axis_tx_cpl(axis_sfp_tx_cpl), /* * Receive interface (AXI stream) */ - .m_axis_rx(axis_sfp0_eth), + .m_axis_rx(axis_sfp_rx), /* - * GMII interface + * PTP clock */ - .gmii_rxd(sfp0_gmii_rxd), - .gmii_rx_dv(sfp0_gmii_rx_dv), - .gmii_rx_er(sfp0_gmii_rx_er), - .gmii_txd(sfp0_gmii_txd), - .gmii_tx_en(sfp0_gmii_tx_en), - .gmii_tx_er(sfp0_gmii_tx_er), + .ptp_clk(1'b0), + .ptp_rst(1'b0), + .ptp_sample_clk(1'b0), + .ptp_td_sdi(1'b0), + .tx_ptp_ts_in('{2{'0}}), + .tx_ptp_ts_out(), + .tx_ptp_ts_step_out(), + .tx_ptp_locked(), + .rx_ptp_ts_in('{2{'0}}), + .rx_ptp_ts_out(), + .rx_ptp_ts_step_out(), + .rx_ptp_locked(), /* - * Control + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) */ - .rx_clk_enable(sfp0_gmii_clk_en), - .tx_clk_enable(sfp0_gmii_clk_en), - .rx_mii_select(1'b0), - .tx_mii_select(1'b0), + .tx_lfc_req('{2{1'b0}}), + .tx_lfc_resend('{2{1'b0}}), + .rx_lfc_en('{2{1'b0}}), + .rx_lfc_req(), + .rx_lfc_ack('{2{1'b0}}), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req('{2{'0}}), + .tx_pfc_resend('{2{1'b0}}), + .rx_pfc_en('{2{'0}}), + .rx_pfc_req(), + .rx_pfc_ack('{2{'0}}), + + /* + * Pause interface + */ + .tx_lfc_pause_en('{2{1'b0}}), + .tx_pause_req('{2{1'b0}}), + .tx_pause_ack(), /* * Statistics @@ -401,193 +539,106 @@ if (SFP_RATE == 0) begin : sfp_mac /* * Status */ - .tx_error_underflow(), - .tx_fifo_overflow(), - .tx_fifo_bad_frame(), - .tx_fifo_good_frame(), - .rx_error_bad_frame(), - .rx_error_bad_fcs(), - .rx_fifo_overflow(), - .rx_fifo_bad_frame(), - .rx_fifo_good_frame(), + .tx_start_packet(), + .stat_tx_byte(), + .stat_tx_pkt_len(), + .stat_tx_pkt_ucast(), + .stat_tx_pkt_mcast(), + .stat_tx_pkt_bcast(), + .stat_tx_pkt_vlan(), + .stat_tx_pkt_good(), + .stat_tx_pkt_bad(), + .stat_tx_pad_frame(), + .stat_tx_err_oversize(), + .stat_tx_err_user(), + .stat_tx_err_underflow(), + .rx_start_packet(), + .rx_error_count(), + .rx_block_lock(), + .rx_high_ber(), + .rx_status(sfp_rx_status), + .stat_rx_byte(), + .stat_rx_pkt_len(), + .stat_rx_pkt_fragment(), + .stat_rx_pkt_jabber(), + .stat_rx_pkt_ucast(), + .stat_rx_pkt_mcast(), + .stat_rx_pkt_bcast(), + .stat_rx_pkt_vlan(), + .stat_rx_pkt_good(), + .stat_rx_pkt_bad(), + .stat_rx_err_oversize(), + .stat_rx_err_bad_fcs(), + .stat_rx_err_bad_block(), + .stat_rx_err_framing(), + .stat_rx_err_preamble(), + .stat_rx_fifo_drop('{2{1'b0}}), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), /* * Configuration */ - .cfg_tx_pad_en(1'b1), - .cfg_tx_min_pkt_len(8'd60-1), - .cfg_tx_max_pkt_len(16'd9218-1), - .cfg_tx_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_max_pkt_len(16'd9218-1), - .cfg_rx_enable(1'b1) - ); - - taxi_eth_mac_1g_fifo #( - .STAT_EN(1), - .STAT_TX_LEVEL(1), - .STAT_RX_LEVEL(1), - .STAT_ID_BASE((16+16)+(16+16)*1), - .STAT_UPDATE_PERIOD(1024), - .STAT_STR_EN(1), - .STAT_PREFIX_STR("SFP1"), - .TX_FIFO_DEPTH(16384), - .TX_FRAME_FIFO(1), - .RX_FIFO_DEPTH(16384), - .RX_FRAME_FIFO(1) - ) - sfp1_eth_mac_inst ( - .rx_clk(sfp1_gmii_clk), - .rx_rst(sfp1_gmii_rst), - .tx_clk(sfp1_gmii_clk), - .tx_rst(sfp1_gmii_rst), - .logic_clk(clk), - .logic_rst(rst), - - /* - * Transmit interface (AXI stream) - */ - .s_axis_tx(axis_sfp1_eth), - .m_axis_tx_cpl(axis_sfp1_tx_cpl), - - /* - * Receive interface (AXI stream) - */ - .m_axis_rx(axis_sfp1_eth), - - /* - * GMII interface - */ - .gmii_rxd(sfp1_gmii_rxd), - .gmii_rx_dv(sfp1_gmii_rx_dv), - .gmii_rx_er(sfp1_gmii_rx_er), - .gmii_txd(sfp1_gmii_txd), - .gmii_tx_en(sfp1_gmii_tx_en), - .gmii_tx_er(sfp1_gmii_tx_er), - - /* - * Control - */ - .rx_clk_enable(sfp1_gmii_clk_en), - .tx_clk_enable(sfp1_gmii_clk_en), - .rx_mii_select(1'b0), - .tx_mii_select(1'b0), - - /* - * Statistics - */ - .stat_clk(clk), - .stat_rst(rst), - .m_axis_stat(axis_eth_stat[2]), - - /* - * Status - */ - .tx_error_underflow(), - .tx_fifo_overflow(), - .tx_fifo_bad_frame(), - .tx_fifo_good_frame(), - .rx_error_bad_frame(), - .rx_error_bad_fcs(), - .rx_fifo_overflow(), - .rx_fifo_bad_frame(), - .rx_fifo_good_frame(), - - /* - * Configuration - */ - .cfg_tx_pad_en(1'b1), - .cfg_tx_min_pkt_len(8'd60-1), - .cfg_tx_max_pkt_len(16'd9218-1), - .cfg_tx_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_max_pkt_len(16'd9218-1), - .cfg_rx_enable(1'b1) + .cfg_tx_pad_en('{2{1'b1}}), + .cfg_tx_min_pkt_len('{2{8'd60-1}}), + .cfg_tx_max_pkt_len('{2{16'd9218-1}}), + .cfg_tx_ifg('{2{8'd12}}), + .cfg_tx_enable('{2{1'b1}}), + .cfg_rx_max_pkt_len('{2{16'd9218-1}}), + .cfg_rx_enable('{2{1'b1}}), + .cfg_tx_prbs31_enable('{2{1'b0}}), + .cfg_rx_prbs31_enable('{2{1'b0}}), + .cfg_mcf_rx_eth_dst_mcast('{2{48'h01_80_C2_00_00_01}}), + .cfg_mcf_rx_check_eth_dst_mcast('{2{1'b1}}), + .cfg_mcf_rx_eth_dst_ucast('{2{48'd0}}), + .cfg_mcf_rx_check_eth_dst_ucast('{2{1'b0}}), + .cfg_mcf_rx_eth_src('{2{48'd0}}), + .cfg_mcf_rx_check_eth_src('{2{1'b0}}), + .cfg_mcf_rx_eth_type('{2{16'h8808}}), + .cfg_mcf_rx_opcode_lfc('{2{16'h0001}}), + .cfg_mcf_rx_check_opcode_lfc('{2{1'b1}}), + .cfg_mcf_rx_opcode_pfc('{2{16'h0101}}), + .cfg_mcf_rx_check_opcode_pfc('{2{1'b1}}), + .cfg_mcf_rx_forward('{2{1'b0}}), + .cfg_mcf_rx_enable('{2{1'b0}}), + .cfg_tx_lfc_eth_dst('{2{48'h01_80_C2_00_00_01}}), + .cfg_tx_lfc_eth_src('{2{48'h80_23_31_43_54_4C}}), + .cfg_tx_lfc_eth_type('{2{16'h8808}}), + .cfg_tx_lfc_opcode('{2{16'h0001}}), + .cfg_tx_lfc_en('{2{1'b0}}), + .cfg_tx_lfc_quanta('{2{16'hffff}}), + .cfg_tx_lfc_refresh('{2{16'h7fff}}), + .cfg_tx_pfc_eth_dst('{2{48'h01_80_C2_00_00_01}}), + .cfg_tx_pfc_eth_src('{2{48'h80_23_31_43_54_4C}}), + .cfg_tx_pfc_eth_type('{2{16'h8808}}), + .cfg_tx_pfc_opcode('{2{16'h0101}}), + .cfg_tx_pfc_en('{2{1'b0}}), + .cfg_tx_pfc_quanta('{2{'{8{16'hffff}}}}), + .cfg_tx_pfc_refresh('{2{'{8{16'h7fff}}}}), + .cfg_rx_lfc_opcode('{2{16'h0001}}), + .cfg_rx_lfc_en('{2{1'b0}}), + .cfg_rx_pfc_opcode('{2{16'h0101}}), + .cfg_rx_pfc_en('{2{1'b0}}) ); end else begin : sfp_mac - wire sfp_tx_clk[2]; - wire sfp_tx_rst[2]; - wire sfp_rx_clk[2]; - wire sfp_rx_rst[2]; - - wire sfp_rx_status[2]; - - wire sfp_gtpowergood; - - wire sfp_mgt_refclk_0; - wire sfp_mgt_refclk_0_int; - wire sfp_mgt_refclk_0_bufg; - - wire sfp_rst; - - taxi_axis_if #(.DATA_W(32), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_tx[2](); - taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl[2](); - taxi_axis_if #(.DATA_W(32), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_rx[2](); - - if (SIM) begin - - assign sfp_mgt_refclk_0 = sfp_mgt_refclk_0_p; - assign sfp_mgt_refclk_0_int = sfp_mgt_refclk_0_p; - assign sfp_mgt_refclk_0_bufg = sfp_mgt_refclk_0_int; - - end else begin - - IBUFDS_GTE3 ibufds_gte3_sfp_mgt_refclk_0_inst ( - .I (sfp_mgt_refclk_0_p), - .IB (sfp_mgt_refclk_0_n), - .CEB (1'b0), - .O (sfp_mgt_refclk_0), - .ODIV2 (sfp_mgt_refclk_0_int) - ); - - BUFG_GT bufg_gt_sfp_mgt_refclk_0_inst ( - .CE (sfp_gtpowergood), - .CEMASK (1'b1), - .CLR (1'b0), - .CLRMASK (1'b1), - .DIV (3'd0), - .I (sfp_mgt_refclk_0_int), - .O (sfp_mgt_refclk_0_bufg) - ); - - end - - taxi_sync_reset #( - .N(4) - ) - sfp_sync_reset_inst ( - .clk(sfp_mgt_refclk_0_bufg), - .rst(rst), - .out(sfp_rst) - ); - - taxi_apb_if #( - .ADDR_W(18), - .DATA_W(16) - ) - gt_apb_ctrl(); - - taxi_xfcp_mod_apb #( - .XFCP_EXT_ID_STR("GTH CTRL") - ) - xfcp_mod_apb_inst ( - .clk(clk), - .rst(rst), - - /* - * XFCP upstream port - */ - .xfcp_usp_ds(xfcp_sw_ds[2]), - .xfcp_usp_us(xfcp_sw_us[2]), - - /* - * APB master interface - */ - .m_apb(gt_apb_ctrl) - ); - taxi_eth_mac_25g_us #( .SIM(SIM), .VENDOR(VENDOR), @@ -828,57 +879,57 @@ end else begin : sfp_mac .cfg_rx_pfc_en('{2{1'b0}}) ); - for (genvar n = 0; n < 2; n = n + 1) begin : sfp_ch +end - taxi_axis_async_fifo #( - .DEPTH(16384), - .RAM_PIPELINE(2), - .FRAME_FIFO(1), - .USER_BAD_FRAME_VALUE(1'b1), - .USER_BAD_FRAME_MASK(1'b1), - .DROP_OVERSIZE_FRAME(1), - .DROP_BAD_FRAME(1), - .DROP_WHEN_FULL(1) - ) - ch_fifo ( - /* - * AXI4-Stream input (sink) - */ - .s_clk(sfp_rx_clk[n]), - .s_rst(sfp_rx_rst[n]), - .s_axis(axis_sfp_rx[n]), +for (genvar n = 0; n < $size(axis_sfp_tx); n = n + 1) begin : sfp_ch - /* - * AXI4-Stream output (source) - */ - .m_clk(sfp_tx_clk[n]), - .m_rst(sfp_tx_rst[n]), - .m_axis(axis_sfp_tx[n]), + taxi_axis_async_fifo #( + .DEPTH(16384), + .RAM_PIPELINE(2), + .FRAME_FIFO(1), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_OVERSIZE_FRAME(1), + .DROP_BAD_FRAME(1), + .DROP_WHEN_FULL(1) + ) + ch_fifo ( + /* + * AXI4-Stream input (sink) + */ + .s_clk(sfp_rx_clk[n]), + .s_rst(sfp_rx_rst[n]), + .s_axis(axis_sfp_rx[n]), - /* - * Pause - */ - .s_pause_req(1'b0), - .s_pause_ack(), - .m_pause_req(1'b0), - .m_pause_ack(), + /* + * AXI4-Stream output (source) + */ + .m_clk(sfp_tx_clk[n]), + .m_rst(sfp_tx_rst[n]), + .m_axis(axis_sfp_tx[n]), - /* - * Status - */ - .s_status_depth(), - .s_status_depth_commit(), - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_depth(), - .m_status_depth_commit(), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() - ); + /* + * Pause + */ + .s_pause_req(1'b0), + .s_pause_ack(), + .m_pause_req(1'b0), + .m_pause_ack(), - end + /* + * Status + */ + .s_status_depth(), + .s_status_depth_commit(), + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_depth(), + .m_status_depth_commit(), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() + ); end diff --git a/src/eth/example/KCU105/fpga/tb/fpga_core/Makefile b/src/eth/example/KCU105/fpga/tb/fpga_core/Makefile index b75064b..b05df5d 100644 --- a/src/eth/example/KCU105/fpga/tb/fpga_core/Makefile +++ b/src/eth/example/KCU105/fpga/tb/fpga_core/Makefile @@ -25,6 +25,7 @@ TOPLEVEL = $(COCOTB_TOPLEVEL) VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f +VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_1g_basex_us.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_i2c_master.f diff --git a/src/eth/example/KCU105/fpga/tb/fpga_core/basex.py b/src/eth/example/KCU105/fpga/tb/fpga_core/basex.py new file mode 120000 index 0000000..b976cc4 --- /dev/null +++ b/src/eth/example/KCU105/fpga/tb/fpga_core/basex.py @@ -0,0 +1 @@ +../../lib/taxi/src/eth/tb/basex.py \ No newline at end of file diff --git a/src/eth/example/KCU105/fpga/tb/fpga_core/test_fpga_core.py b/src/eth/example/KCU105/fpga/tb/fpga_core/test_fpga_core.py index 5593c51..ce2ab3b 100644 --- a/src/eth/example/KCU105/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/eth/example/KCU105/fpga/tb/fpga_core/test_fpga_core.py @@ -20,17 +20,19 @@ import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, Combine -from cocotbext.eth import GmiiFrame, GmiiSource, GmiiSink +from cocotbext.eth import GmiiSource, GmiiSink from cocotbext.eth import XgmiiFrame from cocotbext.uart import UartSource, UartSink try: from baser import BaseRSerdesSource, BaseRSerdesSink + from basex import BaseXSerdesSource, BaseXSerdesSink except ImportError: # attempt import from current directory sys.path.insert(0, os.path.join(os.path.dirname(__file__))) try: from baser import BaseRSerdesSource, BaseRSerdesSink + from basex import BaseXSerdesSource, BaseXSerdesSink finally: del sys.path[0] @@ -53,25 +55,41 @@ class TB: self.sfp_sources = [] self.sfp_sinks = [] - if dut.SFP_RATE.value == 0: - cocotb.start_soon(Clock(dut.sfp0_gmii_clk, 8, units="ns").start()) - cocotb.start_soon(Clock(dut.sfp1_gmii_clk, 8, units="ns").start()) + cocotb.start_soon(Clock(dut.sfp_mgt_refclk_0_p, 6.4, units="ns").start()) - self.sfp_sources.append(GmiiSource(dut.sfp0_gmii_rxd, dut.sfp0_gmii_rx_er, dut.sfp0_gmii_rx_dv, - dut.sfp0_gmii_clk, dut.sfp0_gmii_rst, dut.sfp0_gmii_clk_en)) - self.sfp_sinks.append(GmiiSink(dut.sfp0_gmii_txd, dut.sfp0_gmii_tx_er, dut.sfp0_gmii_tx_en, - dut.sfp0_gmii_clk, dut.sfp0_gmii_rst, dut.sfp0_gmii_clk_en)) + for ch in dut.sfp_mac.sfp_mac_inst.ch: + gt_inst = ch.ch_inst.gt.gt_inst - self.sfp_sources.append(GmiiSource(dut.sfp1_gmii_rxd, dut.sfp1_gmii_rx_er, dut.sfp1_gmii_rx_dv, - dut.sfp1_gmii_clk, dut.sfp1_gmii_rst, dut.sfp1_gmii_clk_en)) - self.sfp_sinks.append(GmiiSink(dut.sfp1_gmii_txd, dut.sfp1_gmii_tx_er, dut.sfp1_gmii_tx_en, - dut.sfp1_gmii_clk, dut.sfp1_gmii_rst, dut.sfp1_gmii_clk_en)) - else: - cocotb.start_soon(Clock(dut.sfp_mgt_refclk_0_p, 6.4, units="ns").start()) + if dut.SFP_RATE.value == 0: + if ch.ch_inst.CFG_LOW_LATENCY.value: + clk = 16 + gbx_cfg = None + else: + clk = 16 + gbx_cfg = None - for ch in dut.sfp_mac.sfp_mac_inst.ch: - gt_inst = ch.ch_inst.gt.gt_inst + cocotb.start_soon(Clock(gt_inst.tx_clk, clk, units="ns").start()) + cocotb.start_soon(Clock(gt_inst.rx_clk, clk, units="ns").start()) + self.sfp_sources.append(BaseXSerdesSource( + data=gt_inst.serdes_rx_data, + data_k=gt_inst.serdes_rx_data_k, + data_valid=gt_inst.serdes_rx_data_valid, + clock=gt_inst.rx_clk, + enc_8b10b=False, + gbx_cfg=gbx_cfg + )) + self.sfp_sinks.append(BaseXSerdesSink( + data=gt_inst.serdes_tx_data, + data_k=gt_inst.serdes_tx_data_k, + data_valid=gt_inst.serdes_tx_data_valid, + gbx_sync=gt_inst.serdes_tx_gbx_sync, + clock=gt_inst.tx_clk, + dec_8b10b=False, + gbx_cfg=gbx_cfg + )) + + else: if ch.ch_inst.CFG_LOW_LATENCY.value: clk = 3.102 gbx_cfg = (66, [64, 65]) @@ -120,24 +138,18 @@ class TB: self.dut.rst.setimmediatevalue(0) self.dut.phy_gmii_rst.setimmediatevalue(0) - self.dut.sfp0_gmii_rst.setimmediatevalue(0) - self.dut.sfp1_gmii_rst.setimmediatevalue(0) for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 1 self.dut.phy_gmii_rst.value = 1 - self.dut.sfp0_gmii_rst.value = 1 - self.dut.sfp1_gmii_rst.value = 1 for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 0 self.dut.phy_gmii_rst.value = 0 - self.dut.sfp0_gmii_rst.value = 0 - self.dut.sfp1_gmii_rst.value = 0 for k in range(10): await RisingEdge(self.dut.clk) @@ -146,51 +158,7 @@ class TB: async def mac_test(tb, source, sink): tb.log.info("Test MAC") - tb.log.info("Multiple small packets") - - count = 64 - - pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] - - for p in pkts: - await source.send(GmiiFrame.from_payload(p)) - - for k in range(count): - rx_frame = await sink.recv() - - tb.log.info("RX frame: %s", rx_frame) - - assert rx_frame.get_payload() == pkts[k] - assert rx_frame.check_fcs() - assert rx_frame.error is None - - tb.log.info("Multiple large packets") - - count = 32 - - pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] - - for p in pkts: - await source.send(GmiiFrame.from_payload(p)) - - for k in range(count): - rx_frame = await sink.recv() - - tb.log.info("RX frame: %s", rx_frame) - - assert rx_frame.get_payload() == pkts[k] - assert rx_frame.check_fcs() - assert rx_frame.error is None - - tb.log.info("MAC test done") - - -async def mac_test_10g(tb, source, sink): - tb.log.info("Test MAC") - - tb.log.info("Wait for block lock") - for k in range(1200): - await RisingEdge(tb.dut.clk) + sink.clear() tb.log.info("Multiple small packets") @@ -238,17 +206,17 @@ async def run_test(dut): tests = [] + tb.log.info("Wait for block lock") + for k in range(1200): + await RisingEdge(dut.clk) + tb.log.info("Start BASE-T MAC loopback test") tests.append(cocotb.start_soon(mac_test(tb, tb.gmii_source, tb.gmii_sink))) for k in range(len(tb.sfp_sources)): - if dut.SFP_RATE.value == 0: - tb.log.info("Start SFP %d 1G MAC loopback test", k) - tests.append(cocotb.start_soon(mac_test(tb, tb.sfp_sources[k], tb.sfp_sinks[k]))) - else: - tb.log.info("Start SFP %d 10G MAC loopback test", k) - tests.append(cocotb.start_soon(mac_test_10g(tb, tb.sfp_sources[k], tb.sfp_sinks[k]))) + tb.log.info("Start SFP %d MAC loopback test", k) + tests.append(cocotb.start_soon(mac_test(tb, tb.sfp_sources[k], tb.sfp_sinks[k]))) await Combine(*tests) @@ -287,6 +255,7 @@ def test_fpga_core(request, sfp_rate): os.path.join(rtl_dir, f"{dut}.sv"), os.path.join(taxi_src_dir, "eth", "rtl", "taxi_eth_mac_1g_fifo.f"), os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_25g_us.f"), + os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_1g_basex_us.f"), os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_if_uart.f"), os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_switch.sv"), os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_mod_i2c_master.f"),