From a7b2db9c209df5f98742e07bd88539b0a9c4bddc Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 5 Nov 2025 20:50:32 -0800 Subject: [PATCH] eth: Update Nexus K35-S/K3P-S example design to use 32-bit MACs at 10G Signed-off-by: Alex Forencich --- .../Nexus_K3P_S/fpga/fpga_K35/Makefile | 4 +-- .../Nexus_K3P_S/fpga/fpga_K35/config.tcl | 22 +++++++++++++++ .../Nexus_K3P_S/fpga/fpga_K3P/Makefile | 2 +- .../Nexus_K3P_S/fpga/fpga_K3P/config.tcl | 22 +++++++++++++++ .../Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile | 5 ++-- .../Nexus_K3P_S/fpga/fpga_K3P_10g/config.tcl | 22 +++++++++++++++ .../example/Nexus_K3P_S/fpga/rtl/fpga_core.sv | 19 +++++++++---- .../example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv | 18 ++++++++++--- .../example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv | 14 ++++++++-- .../Nexus_K3P_S/fpga/tb/fpga_core/Makefile | 3 +++ .../fpga/tb/fpga_core/test_fpga_core.py | 27 ++++++++++++++----- 11 files changed, 135 insertions(+), 23 deletions(-) create mode 100644 src/eth/example/Nexus_K3P_S/fpga/fpga_K35/config.tcl create mode 100644 src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/config.tcl create mode 100644 src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/config.tcl diff --git a/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/Makefile b/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/Makefile index d2ad263..ed7a764 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/Makefile +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/Makefile @@ -31,10 +31,10 @@ 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_25g_us_gth_10g_161.tcl +IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gth_161.tcl # Configuration -# CONFIG_TCL_FILES = ./config.tcl +CONFIG_TCL_FILES = ./config.tcl include ../common/vivado.mk diff --git a/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/config.tcl b/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/config.tcl new file mode 100644 index 0000000..cd72d45 --- /dev/null +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K35/config.tcl @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# 10G MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "32" + +# 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/eth/example/Nexus_K3P_S/fpga/fpga_K3P/Makefile b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/Makefile index da70283..5a9b746 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/Makefile +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/Makefile @@ -34,7 +34,7 @@ XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl # Configuration -# CONFIG_TCL_FILES = ./config.tcl +CONFIG_TCL_FILES = ./config.tcl include ../common/vivado.mk diff --git a/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/config.tcl b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/config.tcl new file mode 100644 index 0000000..d3508a4 --- /dev/null +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P/config.tcl @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# 10G MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "64" + +# 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/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile index 221a86f..e539a05 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile @@ -31,10 +31,10 @@ 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_25g_us_gty_10g_161.tcl +IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl # Configuration -# CONFIG_TCL_FILES = ./config.tcl +CONFIG_TCL_FILES = ./config.tcl include ../common/vivado.mk @@ -86,4 +86,3 @@ flash: $(PROJECT).mcs $(PROJECT).prm 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/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/config.tcl b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/config.tcl new file mode 100644 index 0000000..cd72d45 --- /dev/null +++ b/src/eth/example/Nexus_K3P_S/fpga/fpga_K3P_10g/config.tcl @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# 10G MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "32" + +# 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/eth/example/Nexus_K3P_S/fpga/rtl/fpga_core.sv b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_core.sv index 278d6e3..9e9197d 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_core.sv +++ b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_core.sv @@ -17,9 +17,16 @@ Authors: */ module fpga_core # ( + // simulation (set to avoid vendor primitives) parameter logic SIM = 1'b0, + // vendor ("GENERIC", "XILINX", "ALTERA") parameter string VENDOR = "XILINX", - parameter string FAMILY = "kintexuplus" + // device family + parameter string FAMILY = "kintexuplus", + // 10G/25G MAC configuration + parameter logic CFG_LOW_LATENCY = 1'b1, + parameter logic COMBINED_MAC_PCS = 1'b1, + parameter MAC_DATA_W = 64 ) ( /* @@ -78,9 +85,9 @@ assign sfp_mgt_refclk_out = sfp_mgt_refclk_bufg; wire sfp_rst; -taxi_axis_if #(.DATA_W(64), .ID_W(8)) axis_sfp_tx[2](); +taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8)) 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(64), .ID_W(8)) axis_sfp_rx[2](); +taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8)) axis_sfp_rx[2](); 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(8)) axis_sfp_stat(); if (SIM) begin @@ -142,7 +149,7 @@ taxi_eth_mac_25g_us #( .CNT(2), // GT config - .CFG_LOW_LATENCY(1), + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), // GT type .GT_TYPE(FAMILY == "kintexu" ? "GTH" : "GTY"), @@ -151,7 +158,9 @@ taxi_eth_mac_25g_us #( .GT_TX_POLARITY('1), .GT_RX_POLARITY('0), - // MAC/PHY parameters + // MAC/PHY config + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .DATA_W(MAC_DATA_W), .PADDING_EN(1'b1), .DIC_EN(1'b1), .MIN_FRAME_LEN(64), diff --git a/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv index 7d493ef..0530d64 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv +++ b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv @@ -17,9 +17,16 @@ Authors: */ module fpga # ( + // simulation (set to avoid vendor primitives) parameter logic SIM = 1'b0, + // vendor ("GENERIC", "XILINX", "ALTERA") parameter string VENDOR = "XILINX", - parameter string FAMILY = "kintexu" + // device family + parameter string FAMILY = "kintexu", + // 10G/25G MAC configuration + parameter logic CFG_LOW_LATENCY = 1'b1, + parameter logic COMBINED_MAC_PCS = 1'b1, + parameter MAC_DATA_W = 32 ) ( /* @@ -64,12 +71,12 @@ wire mmcm_clkfb; IBUFGDS #( .DIFF_TERM("FALSE"), - .IBUF_LOW_PWR("FALSE") + .IBUF_LOW_PWR("FALSE") ) clk_100mhz_ibufg_inst ( .O (clk_100mhz_ibufg), .I (clk_100mhz_p), - .IB (clk_100mhz_n) + .IB (clk_100mhz_n) ); // MMCM instance @@ -168,7 +175,10 @@ sync_reset_125mhz_inst ( fpga_core #( .SIM(SIM), .VENDOR(VENDOR), - .FAMILY(FAMILY) + .FAMILY(FAMILY), + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .MAC_DATA_W(MAC_DATA_W) ) core_inst ( /* diff --git a/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv index 250e8e7..e48a1f2 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv +++ b/src/eth/example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv @@ -17,9 +17,16 @@ Authors: */ module fpga # ( + // simulation (set to avoid vendor primitives) parameter logic SIM = 1'b0, + // vendor ("GENERIC", "XILINX", "ALTERA") parameter string VENDOR = "XILINX", - parameter string FAMILY = "kintexuplus" + // device family + parameter string FAMILY = "kintexuplus", + // 10G/25G MAC configuration + parameter logic CFG_LOW_LATENCY = 1'b1, + parameter logic COMBINED_MAC_PCS = 1'b1, + parameter MAC_DATA_W = 64 ) ( /* @@ -152,7 +159,10 @@ sync_reset_125mhz_inst ( fpga_core #( .SIM(SIM), .VENDOR(VENDOR), - .FAMILY(FAMILY) + .FAMILY(FAMILY), + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .MAC_DATA_W(MAC_DATA_W) ) core_inst ( /* diff --git a/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile b/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile index d6308b1..58d63c1 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile +++ b/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile @@ -38,6 +38,9 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES))) export PARAM_SIM := "1'b1" export PARAM_VENDOR := "\"XILINX\"" export PARAM_FAMILY := "\"kintexuplus\"" +export PARAM_CFG_LOW_LATENCY := "1'b1" +export PARAM_COMBINED_MAC_PCS := "1'b1" +export PARAM_MAC_DATA_W := "64" ifeq ($(SIM), icarus) PLUSARGS += -fst diff --git a/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py b/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py index 2c5b1e2..11dd018 100644 --- a/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/eth/example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py @@ -13,6 +13,7 @@ import logging import os import sys +import pytest import cocotb_test.simulator import cocotb @@ -49,12 +50,20 @@ class TB: for ch in dut.sfp_mac_inst.ch: gt_inst = ch.ch_inst.gt.gt_inst - if ch.ch_inst.CFG_LOW_LATENCY.value: - clk = 2.482 - 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 = 2.56 - 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()) @@ -108,6 +117,8 @@ async def mac_test(tb, source, sink): for k in range(1200): await RisingEdge(tb.dut.clk_125mhz) + sink.clear() + tb.log.info("Multiple small packets") count = 64 @@ -186,7 +197,8 @@ def process_f_files(files): return list(lst.values()) -def test_fpga_core(request): +@pytest.mark.parametrize("mac_data_w", [32, 64]) +def test_fpga_core(request, mac_data_w): dut = "fpga_core" module = os.path.splitext(os.path.basename(__file__))[0] toplevel = dut @@ -206,6 +218,9 @@ def test_fpga_core(request): parameters['SIM'] = "1'b1" parameters['VENDOR'] = "\"XILINX\"" parameters['FAMILY'] = "\"kintexuplus\"" + parameters['CFG_LOW_LATENCY'] = "1'b1" + parameters['COMBINED_MAC_PCS'] = "1'b1" + parameters['MAC_DATA_W'] = mac_data_w extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}