From e5cc625e3b07dcbe6d216822c4c9d7e453329f49 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 11 Aug 2026 16:15:42 -0700 Subject: [PATCH] cndm: Add 1000BASE-X support to AS02MC04 design Signed-off-by: Alex Forencich --- src/cndm/board/AS02MC04/fpga/fpga_1g/Makefile | 99 +++ .../board/AS02MC04/fpga/fpga_1g/config.tcl | 131 +++ src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv | 747 ++++++++++++------ .../board/AS02MC04/fpga/tb/fpga_core/Makefile | 1 + .../board/AS02MC04/fpga/tb/fpga_core/basex.py | 1 + .../fpga/tb/fpga_core/test_fpga_core.py | 101 ++- 6 files changed, 807 insertions(+), 273 deletions(-) create mode 100644 src/cndm/board/AS02MC04/fpga/fpga_1g/Makefile create mode 100644 src/cndm/board/AS02MC04/fpga/fpga_1g/config.tcl create mode 120000 src/cndm/board/AS02MC04/fpga/tb/fpga_core/basex.py diff --git a/src/cndm/board/AS02MC04/fpga/fpga_1g/Makefile b/src/cndm/board/AS02MC04/fpga/fpga_1g/Makefile new file mode 100644 index 0000000..f55e571 --- /dev/null +++ b/src/cndm/board/AS02MC04/fpga/fpga_1g/Makefile @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +# FPGA settings +FPGA_PART = xcku3p-ffvb676-1-e +FPGA_TOP = fpga +FPGA_ARCH = kintexuplus + +RTL_DIR = ../rtl +LIB_DIR = ../lib +TAXI_SRC_DIR = $(LIB_DIR)/taxi/src + +# Files for synthesis +SYN_FILES = $(RTL_DIR)/fpga.sv +SYN_FILES += $(RTL_DIR)/fpga_core.sv +SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f +SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_brd_ctrl_i2c.f +SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_1g_basex_us.f +SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv +SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f + +# XDC files +XDC_FILES += ../syn/fpga.xdc +XDC_FILES += ../syn/gpio.xdc +XDC_FILES += ../syn/i2c.xdc +XDC_FILES += ../syn/smbus.xdc +XDC_FILES += ../syn/sfp28.xdc +XDC_FILES += ../syn/pcie.xdc +XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl + +# IP +IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_1g_basex_us_gty_156.tcl +IP_TCL_FILES += ../ip/pcie4_uscale_plus_0.tcl + +# Configuration +CONFIG_TCL_FILES = ./config.tcl + +include ../common/vivado.mk + +program: $(PROJECT).bit + echo "open_hw_manager" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit + echo "write_cfgmem -force -format mcs -size 32 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(PROJECT).mcs $(PROJECT).prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/src/cndm/board/AS02MC04/fpga/fpga_1g/config.tcl b/src/cndm/board/AS02MC04/fpga/fpga_1g/config.tcl new file mode 100644 index 0000000..67a3fa3 --- /dev/null +++ b/src/cndm/board/AS02MC04/fpga/fpga_1g/config.tcl @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# collect build information +set build_date [clock seconds] +set git_hash 00000000 +set git_tag "" + +if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } { + puts "Error running git or project not under version control" +} + +if { [catch {set git_tag [exec git describe --tags HEAD]}] } { + puts "Error running git, project not under version control, or no tag found" +} + +puts "Build date: ${build_date}" +puts "Git hash: ${git_hash}" +puts "Git tag: ${git_tag}" + +if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } { + puts "Failed to extract version from git tag" + set tag_ver 0.0.1 +} + +puts "Tag version: ${tag_ver}" + +# FW and board IDs +set fpga_id [expr 0x4A63093] +set fw_id [expr 0x0000C001] +set fw_ver $tag_ver +set board_vendor_id [expr 0x1ded] +set board_device_id [expr 0x0009] +set board_ver 1.0 +set release_info [expr 0x00000000] + +# PCIe IDs +set pcie_vendor_id [expr 0x1234] +set pcie_device_id [expr 0xC001] +set pcie_class_code [expr 0x020000] +set pcie_revision_id [expr 0x00] +set pcie_subsystem_device_id $board_device_id +set pcie_subsystem_vendor_id $board_vendor_id + +# FW ID +dict set params FPGA_ID [format "32'h%08x" $fpga_id] +dict set params FW_ID [format "32'h%08x" $fw_id] +dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0] +dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id] +dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0] +dict set params BUILD_DATE "32'd${build_date}" +dict set params GIT_HASH "32'h${git_hash}" +dict set params RELEASE_INFO [format "32'h%08x" $release_info] + +# PTP configuration +dict set params PTP_TS_EN "1" + +# AXI lite interface configuration (control) +dict set params AXIL_CTRL_DATA_W "32" +dict set params AXIL_CTRL_ADDR_W "24" + +# MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "16" + +# PCIe IP core settings +set pcie [get_ips pcie4_uscale_plus_0] + +# configure BAR settings +proc configure_bar {pcie pf bar aperture} { + set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes} + for { set i 0 } { $i < [llength $size_list] } { incr i } { + set scale [lindex $size_list $i] + + if {$aperture > 0 && $aperture < ($i+1)*10} { + set size [expr 1 << $aperture - ($i*10)] + + puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)" + + set pcie_config [dict create] + + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size + + set_property -dict $pcie_config $pcie + + return + } + } + puts "${pcie} PF${pf} BAR${bar}: disabled" + set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie +} + +# Control BAR (BAR 0) +configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W] + +# PCIe IP core configuration +set pcie_config [dict create] + +# PCIe IDs +dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id] +dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id] +dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code] +dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id] + +# MSI +dict set pcie_config "CONFIG.pf0_msi_enabled" {true} + +set_property -dict $pcie_config $pcie + +# apply parameters to top-level +set param_list {} +dict for {name value} $params { + lappend param_list $name=$value +} + +set_property generic $param_list [get_filesets sources_1] diff --git a/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv b/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv index 8723854..ba36e95 100644 --- a/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv +++ b/src/cndm/board/AS02MC04/fpga/rtl/fpga_core.sv @@ -449,264 +449,533 @@ wire ptp_pps_str; assign led_g = ptp_pps_str; -taxi_eth_mac_25g_us #( - .SIM(SIM), - .VENDOR(VENDOR), - .FAMILY(FAMILY), +if (MAC_DATA_W == 16) begin : sfp_mac - .CNT(2), + taxi_eth_mac_1g_basex_us #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), - // GT config - .CFG_LOW_LATENCY(CFG_LOW_LATENCY), + .CNT(2), - // GT type - .GT_TYPE("GTY"), + // GT config + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), - // GT parameters - .GT_TX_POLARITY('0), - .GT_RX_POLARITY('0), + // GT type + .GT_TYPE("GTY"), - // MAC/PHY config - .COMBINED_MAC_PCS(COMBINED_MAC_PCS), - .DATA_W(axis_sfp_tx[0].DATA_W), - .USXGMII_EN(COMBINED_MAC_PCS && axis_sfp_tx[0].DATA_W == 32), - .DIC_EN(1'b1), - .PTP_TS_EN(PTP_TS_EN), - .PTP_TD_EN(PTP_TS_EN), - .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), - .PTP_TS_W(PTP_TS_W), - .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'b0) -) -sfp_mac_inst ( - .xcvr_ctrl_clk(clk_125mhz), - .xcvr_ctrl_rst(sfp_rst), + // GT parameters + .GT_TX_POLARITY('0), + .GT_RX_POLARITY('0), - /* - * Transceiver control - */ - .s_apb_ctrl(gt_apb_ctrl), + // MAC/PHY config + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .SGMII_EN(1'b1), + .AN_EN(1'b1), + .DIC_EN(1'b1), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TD_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .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'b0) + ) + sfp_mac_inst ( + .xcvr_ctrl_clk(clk_125mhz), + .xcvr_ctrl_rst(sfp_rst), - /* - * Common - */ - .xcvr_gtpowergood_out(sfp_gtpowergood), - .xcvr_gtrefclk00_in(sfp_mgt_refclk), - .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), - .xcvr_qpll1pd_in(1'b0), - .xcvr_qpll1reset_in(1'b0), - .xcvr_qpll1pcierate_in(3'd0), - .xcvr_qpll1lock_out(), - .xcvr_qpll1clk_out(), - .xcvr_qpll1refclk_out(), + /* + * Transceiver control + */ + .s_apb_ctrl(gt_apb_ctrl), - /* - * Serial data - */ - .xcvr_txp(sfp_tx_p), - .xcvr_txn(sfp_tx_n), - .xcvr_rxp(sfp_rx_p), - .xcvr_rxn(sfp_rx_n), + /* + * Common + */ + .xcvr_gtpowergood_out(sfp_gtpowergood), + .xcvr_gtrefclk00_in(sfp_mgt_refclk), + .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), + .xcvr_qpll1pd_in(1'b0), + .xcvr_qpll1reset_in(1'b0), + .xcvr_qpll1pcierate_in(3'd0), + .xcvr_qpll1lock_out(), + .xcvr_qpll1clk_out(), + .xcvr_qpll1refclk_out(), - /* - * 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), + /* + * Serial data + */ + .xcvr_txp(sfp_tx_p), + .xcvr_txn(sfp_tx_n), + .xcvr_rxp(sfp_rx_p), + .xcvr_rxn(sfp_rx_n), - /* - * Transmit interface (AXI stream) - */ - .s_axis_tx(axis_sfp_tx), - .m_axis_tx_cpl(axis_sfp_tx_cpl), + /* + * 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), - /* - * Receive interface (AXI stream) - */ - .m_axis_rx(axis_sfp_rx), + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(axis_sfp_tx), + .m_axis_tx_cpl(axis_sfp_tx_cpl), - /* - * USXGMII autonegotiation - */ - .an_en('{2{1'b1}}), - .an_restart('{2{1'b0}}), - .an_speedup('{2{1'b0}}), - .an_timeout_en('{2{1'b1}}), - .an_usxgmii_en('{2{1'b0}}), - .an_usxgmii_auto('{2{1'b1}}), - .an_intr(), - .an_running(), - .an_complete(), - .an_timeout(), - .an_usxgmii_mode(), - .an_adv_ability_usxgmii('{2{16'h1601}}), - .an_lp_adv_ability(), - .an_lp_usxgmii_link(), - .an_lp_usxgmii_speed(), - .an_res_full_duplex(), + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(axis_sfp_rx), - /* - * PTP clock - */ - .ptp_clk(ptp_clk), - .ptp_rst(ptp_rst), - .ptp_sample_clk(ptp_sample_clk), - .ptp_td_sdi(ptp_td_sd), - .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(), + /* + * Autonegotiation + */ + .an_en('{2{1'b1}}), + .an_restart('{2{1'b0}}), + .an_speedup('{2{1'b0}}), + .an_timeout_en('{2{1'b1}}), + .an_sgmii_en('{2{1'b0}}), + .an_sgmii_auto('{2{1'b1}}), + .an_intr(), + .an_running(), + .an_complete(), + .an_timeout(), + .an_sgmii_mode(), + .an_adv_ability_basex('{2{16'h0020}}), + .an_adv_ability_sgmii('{2{16'h0001}}), + .an_lp_adv_ability(), + .an_lp_remote_fault(), + .an_lp_sgmii_link(), + .an_lp_sgmii_speed(), + .an_res_full_duplex(), + .an_res_tx_pause(), + .an_res_rx_pause(), - /* - * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) - */ - .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}}), + /* + * PTP clock + */ + .ptp_clk(ptp_clk), + .ptp_rst(ptp_rst), + .ptp_sample_clk(ptp_sample_clk), + .ptp_td_sdi(ptp_td_sd), + .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(), - /* - * 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}}), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .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}}), - /* - * Pause interface - */ - .tx_lfc_pause_en('{2{1'b0}}), - .tx_pause_req('{2{1'b0}}), - .tx_pause_ack(), + /* + * 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}}), - /* - * Statistics - */ - .stat_clk(clk_125mhz), - .stat_rst(rst_125mhz), - .m_axis_stat(axis_sfp_stat), + /* + * Pause interface + */ + .tx_lfc_pause_en('{2{1'b0}}), + .tx_pause_req('{2{1'b0}}), + .tx_pause_ack(), - /* - * Status - */ - .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(), + /* + * Statistics + */ + .stat_clk(clk_125mhz), + .stat_rst(rst_125mhz), + .m_axis_stat(axis_sfp_stat), - /* - * Configuration - */ - .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}}) -); + /* + * Status + */ + .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('{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 + + taxi_eth_mac_25g_us #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), + + .CNT(2), + + // GT config + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), + + // GT type + .GT_TYPE("GTY"), + + // GT parameters + .GT_TX_POLARITY('0), + .GT_RX_POLARITY('0), + + // MAC/PHY config + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .DATA_W(axis_sfp_tx[0].DATA_W), + .USXGMII_EN(COMBINED_MAC_PCS), + .DIC_EN(1'b1), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TD_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .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'b0) + ) + sfp_mac_inst ( + .xcvr_ctrl_clk(clk_125mhz), + .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), + .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), + .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_sfp_tx), + .m_axis_tx_cpl(axis_sfp_tx_cpl), + + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(axis_sfp_rx), + + /* + * USXGMII autonegotiation + */ + .an_en('{2{1'b1}}), + .an_restart('{2{1'b0}}), + .an_speedup('{2{1'b0}}), + .an_timeout_en('{2{1'b1}}), + .an_usxgmii_en('{2{1'b0}}), + .an_usxgmii_auto('{2{1'b1}}), + .an_intr(), + .an_running(), + .an_complete(), + .an_timeout(), + .an_usxgmii_mode(), + .an_adv_ability_usxgmii('{2{16'h1601}}), + .an_lp_adv_ability(), + .an_lp_usxgmii_link(), + .an_lp_usxgmii_speed(), + .an_res_full_duplex(), + + /* + * PTP clock + */ + .ptp_clk(ptp_clk), + .ptp_rst(ptp_rst), + .ptp_sample_clk(ptp_sample_clk), + .ptp_td_sdi(ptp_td_sd), + .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(), + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .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 + */ + .stat_clk(clk_125mhz), + .stat_rst(rst_125mhz), + .m_axis_stat(axis_sfp_stat), + + /* + * Status + */ + .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('{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 cndm_micro_pcie_us #( .SIM(SIM), diff --git a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile index 1651671..bbb88a8 100644 --- a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile +++ b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/Makefile @@ -27,6 +27,7 @@ VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_brd_ctrl_i2c.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)/axis/rtl/taxi_axis_async_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv diff --git a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/basex.py b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/basex.py new file mode 120000 index 0000000..b976cc4 --- /dev/null +++ b/src/cndm/board/AS02MC04/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/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py index 6dbc0bb..b5918cd 100644 --- a/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/cndm/board/AS02MC04/fpga/tb/fpga_core/test_fpga_core.py @@ -29,12 +29,14 @@ from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice try: from baser import BaseRSerdesSource, BaseRSerdesSink + from basex import BaseXSerdesSource, BaseXSerdesSink import cndm 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 import cndm finally: del sys.path[0] @@ -284,47 +286,77 @@ class TB: self.sfp_sources = [] self.sfp_sinks = [] - for ch in dut.uut.sfp_mac_inst.ch: + for ch in dut.uut.sfp_mac.sfp_mac_inst.ch: gt_inst = ch.ch_inst.gt.gt_inst - if ch.ch_inst.DATA_W.value == 64: + if dut.MAC_DATA_W.value == 16: if ch.ch_inst.CFG_LOW_LATENCY.value: - clk = 2.482 - gbx_cfg = (66, [64, 65]) - else: - clk = 2.56 + clk = 16 gbx_cfg = None + else: + clk = 16 + gbx_cfg = None + + 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]) + if ch.ch_inst.DATA_W.value == 64: + if ch.ch_inst.CFG_LOW_LATENCY.value: + clk = 2.482 + gbx_cfg = (66, [64, 65]) + else: + clk = 2.56 + gbx_cfg = None else: - clk = 3.2 - gbx_cfg = None + if ch.ch_inst.CFG_LOW_LATENCY.value: + clk = 3.102 + gbx_cfg = (66, [64, 65]) + else: + clk = 3.2 + gbx_cfg = None - cocotb.start_soon(Clock(gt_inst.tx_clk, clk, units="ns").start()) - cocotb.start_soon(Clock(gt_inst.rx_clk, clk, units="ns").start()) + 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(BaseRSerdesSource( - data=gt_inst.serdes_rx_data, - data_valid=gt_inst.serdes_rx_data_valid, - hdr=gt_inst.serdes_rx_hdr, - hdr_valid=gt_inst.serdes_rx_hdr_valid, - clock=gt_inst.rx_clk, - slip=gt_inst.serdes_rx_bitslip, - reverse=True, - gbx_cfg=gbx_cfg - )) - self.sfp_sinks.append(BaseRSerdesSink( - data=gt_inst.serdes_tx_data, - data_valid=gt_inst.serdes_tx_data_valid, - hdr=gt_inst.serdes_tx_hdr, - hdr_valid=gt_inst.serdes_tx_hdr_valid, - gbx_sync=gt_inst.serdes_tx_gbx_sync, - clock=gt_inst.tx_clk, - reverse=True, - gbx_cfg=gbx_cfg - )) + self.sfp_sources.append(BaseRSerdesSource( + data=gt_inst.serdes_rx_data, + data_valid=gt_inst.serdes_rx_data_valid, + hdr=gt_inst.serdes_rx_hdr, + hdr_valid=gt_inst.serdes_rx_hdr_valid, + clock=gt_inst.rx_clk, + slip=gt_inst.serdes_rx_bitslip, + reverse=True, + gbx_cfg=gbx_cfg + )) + self.sfp_sinks.append(BaseRSerdesSink( + data=gt_inst.serdes_tx_data, + data_valid=gt_inst.serdes_tx_data_valid, + hdr=gt_inst.serdes_tx_hdr, + hdr_valid=gt_inst.serdes_tx_hdr_valid, + gbx_sync=gt_inst.serdes_tx_gbx_sync, + clock=gt_inst.tx_clk, + reverse=True, + gbx_cfg=gbx_cfg + )) dut.sfp_npres.setimmediatevalue(0) dut.sfp_tx_fault.setimmediatevalue(0) @@ -524,7 +556,7 @@ def process_f_files(files): return list(lst.values()) -@pytest.mark.parametrize("mac_data_w", [32, 64]) +@pytest.mark.parametrize("mac_data_w", [16, 32, 64]) def test_fpga_core(request, mac_data_w): dut = "fpga_core" module = os.path.splitext(os.path.basename(__file__))[0] @@ -536,6 +568,7 @@ def test_fpga_core(request, mac_data_w): os.path.join(taxi_src_dir, "cndm", "rtl", "cndm_micro_pcie_us.f"), os.path.join(taxi_src_dir, "cndm", "rtl", "cndm_brd_ctrl_i2c.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, "axis", "rtl", "taxi_axis_async_fifo.f"), os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_reset.sv"), os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_signal.sv"),