eth: Add 100G configuration to HTG-9200 example design

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-08-10 14:48:06 -07:00
parent b5bd7b163f
commit e24e4345d7
27 changed files with 921 additions and 367 deletions

View File

@@ -50,13 +50,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -74,7 +74,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -82,8 +82,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"

View File

@@ -50,13 +50,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -74,7 +74,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -82,8 +82,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"

View File

@@ -49,13 +49,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -73,7 +73,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -81,8 +81,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"

View File

@@ -49,13 +49,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -73,7 +73,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -81,8 +81,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"

View File

@@ -50,13 +50,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -74,7 +74,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -82,8 +82,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"

View File

@@ -50,13 +50,13 @@ CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -74,7 +74,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -82,8 +82,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,7 +8,7 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu13p-fhgb2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
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 += $(RTL_DIR)/../pll/si5341_i2c_init.sv
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_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_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_i2c_master.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.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)/io/rtl/taxi_debounce_switch.sv
# XDC files
XDC_FILES += ../syn/fpga.xdc
XDC_FILES += ../syn/gpio.xdc
XDC_FILES += ../syn/i2c.xdc
XDC_FILES += ../syn/pll.xdc
XDC_FILES += ../syn/qsfp.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)/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_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw" > 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
%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx8 -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 _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.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 {s25fl512s-spi-x1_x2_x4_x8}] 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)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -0,0 +1,22 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# 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]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu9p-flgb2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
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 += $(RTL_DIR)/../pll/si5341_i2c_init.sv
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_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_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_i2c_master.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.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)/io/rtl/taxi_debounce_switch.sv
# XDC files
XDC_FILES += ../syn/fpga.xdc
XDC_FILES += ../syn/gpio.xdc
XDC_FILES += ../syn/i2c.xdc
XDC_FILES += ../syn/pll.xdc
XDC_FILES += ../syn/qsfp.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)/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_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw" > 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
%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx8 -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 _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.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 {s25fl512s-spi-x1_x2_x4_x8}] 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)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -0,0 +1,22 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# 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]

View File

@@ -19,7 +19,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(RTL_DIR)/../pll/si5341_i2c_init.sv
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_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_apb.f
@@ -36,26 +36,28 @@ XDC_FILES += ../syn/gpio.xdc
XDC_FILES += ../syn/i2c.xdc
XDC_FILES += ../syn/pll.xdc
XDC_FILES += ../syn/qsfp.xdc
XDC_FILES += ../syn/eth_cmac_vu13p.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)/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_25g_161.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_cmace4.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -73,7 +75,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -81,8 +83,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,10 +8,10 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
dict set params MAC_DATA_W "512"
# apply parameters to top-level
set param_list {}

View File

@@ -19,7 +19,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(RTL_DIR)/../pll/si5341_i2c_init.sv
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_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_apb.f
@@ -36,26 +36,28 @@ XDC_FILES += ../syn/gpio.xdc
XDC_FILES += ../syn/i2c.xdc
XDC_FILES += ../syn/pll.xdc
XDC_FILES += ../syn/qsfp.xdc
XDC_FILES += ../syn/eth_cmac_vu9p.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)/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_25g_161.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_cmace4.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
program: $(PROJECT).bit
echo "open_hw" > 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 {$(FPGA_TOP).bit} [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
@@ -73,7 +75,7 @@ program: $(FPGA_TOP).bit
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.prm
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
@@ -81,8 +83,8 @@ flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm
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 {s25fl512s-spi-x1_x2_x4_x8}] 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 \"$(FPGA_TOP)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.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

View File

@@ -8,10 +8,10 @@
set params [dict create]
# 10G MAC configuration
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
dict set params MAC_DATA_W "512"
# apply parameters to top-level
set param_list {}

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2021-2025 FPGA Ninja, LLC
Copyright (c) 2021-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
@@ -23,10 +23,10 @@ module fpga #
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// 10G/25G MAC configuration
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
parameter MAC_DATA_W = 512
)
(
/*

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2021-2025 FPGA Ninja, LLC
Copyright (c) 2021-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
@@ -23,7 +23,7 @@ module fpga #
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// 10G/25G MAC configuration
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2021-2025 FPGA Ninja, LLC
Copyright (c) 2021-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
@@ -28,10 +28,10 @@ module fpga_core #
parameter GTY_QUAD_CNT = PORT_CNT,
parameter GTY_CNT = GTY_QUAD_CNT*4,
parameter GTY_CLK_CNT = GTY_QUAD_CNT,
// 10G/25G MAC configuration
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
parameter MAC_DATA_W = 512
)
(
/*
@@ -408,286 +408,533 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gt_quad
.m_apb(gt_apb_ctrl)
);
taxi_eth_mac_25g_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
if (MAC_DATA_W == 512) begin: mac
.CNT(CNT),
taxi_eth_mac_100g_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// GT config
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.GT_CNT(CNT),
// GT type
.GT_TYPE("GTY"),
// GT config
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
// MAC/PHY config
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.DATA_W(eth_gty_axis_tx[0].DATA_W),
.USXGMII_EN(COMBINED_MAC_PCS),
.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(n*CNT*(16+16)),
.STAT_UPDATE_PERIOD(1024),
.STAT_STR_EN(1),
.STAT_PREFIX_STR(
n == 0 ? STAT_PREFIX_STR_QSFP1 :
n == 1 ? STAT_PREFIX_STR_QSFP2 :
n == 2 ? STAT_PREFIX_STR_QSFP3 :
n == 3 ? STAT_PREFIX_STR_QSFP4 :
n == 4 ? STAT_PREFIX_STR_QSFP5 :
n == 5 ? STAT_PREFIX_STR_QSFP6 :
n == 6 ? STAT_PREFIX_STR_QSFP7 :
n == 7 ? STAT_PREFIX_STR_QSFP8 :
n == 8 ? STAT_PREFIX_STR_QSFP9 :
n == 9 ? STAT_PREFIX_STR_QSFP10 :
n == 10 ? STAT_PREFIX_STR_QSFP11 :
n == 11 ? STAT_PREFIX_STR_QSFP12 :
n == 12 ? STAT_PREFIX_STR_QSFP13 :
n == 13 ? STAT_PREFIX_STR_QSFP14 :
STAT_PREFIX_STR_QSFP15
// GT type
.GT_TYPE("GTY"),
// MAC/PHY config
.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),
.TX_SERDES_PIPELINE(1),
.RX_SERDES_PIPELINE(1),
.STAT_EN(1),
.STAT_TX_LEVEL(1),
.STAT_RX_LEVEL(1),
.STAT_ID_BASE(n*CNT*(16+16)),
.STAT_UPDATE_PERIOD(1024),
.STAT_STR_EN(1),
.STAT_PREFIX_STR(
n == 0 ? "QSFP1" :
n == 1 ? "QSFP2" :
n == 2 ? "QSFP3" :
n == 3 ? "QSFP4" :
n == 4 ? "QSFP5" :
n == 5 ? "QSFP6" :
n == 6 ? "QSFP7" :
n == 7 ? "QSFP8" :
"QSFP9"
)
)
)
mac_inst (
.xcvr_ctrl_clk(clk_125mhz),
.xcvr_ctrl_rst(eth_gty_rst[CLK]),
mac_inst (
.xcvr_ctrl_clk(clk_125mhz),
.xcvr_ctrl_rst(eth_gty_rst[CLK]),
/*
* Transceiver control
*/
.s_apb_ctrl(gt_apb_ctrl),
/*
* Transceiver control
*/
.s_apb_ctrl(gt_apb_ctrl),
/*
* Common
*/
.xcvr_gtpowergood_out(eth_gty_gtpowergood[n]),
.xcvr_gtrefclk00_in(eth_gty_mgt_refclk[CLK]),
.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(eth_gty_mgt_refclk[CLK]),
.xcvr_qpll1pd_in(1'b0),
.xcvr_qpll1reset_in(1'b0),
.xcvr_qpll1pcierate_in(3'd0),
.xcvr_qpll1lock_out(),
.xcvr_qpll1clk_out(),
.xcvr_qpll1refclk_out(),
/*
* Common
*/
.xcvr_gtpowergood_out(eth_gty_gtpowergood[n]),
.xcvr_gtrefclk00_in(eth_gty_mgt_refclk[CLK]),
.xcvr_qpll0pd_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0clk_out(),
.xcvr_qpll0refclk_out(),
.xcvr_gtrefclk01_in(eth_gty_mgt_refclk[CLK]),
.xcvr_qpll1pd_in(1'b0),
.xcvr_qpll1lock_out(),
.xcvr_qpll1clk_out(),
.xcvr_qpll1refclk_out(),
/*
* Serial data
*/
.xcvr_txp(eth_gty_tx_p[n*CNT +: CNT]),
.xcvr_txn(eth_gty_tx_n[n*CNT +: CNT]),
.xcvr_rxp(eth_gty_rx_p[n*CNT +: CNT]),
.xcvr_rxn(eth_gty_rx_n[n*CNT +: CNT]),
/*
* Serial data
*/
.xcvr_txp(eth_gty_tx_p[n*CNT +: CNT]),
.xcvr_txn(eth_gty_tx_n[n*CNT +: CNT]),
.xcvr_rxp(eth_gty_rx_p[n*CNT +: CNT]),
.xcvr_rxn(eth_gty_rx_n[n*CNT +: CNT]),
/*
* MAC clocks
*/
.rx_clk(eth_gty_rx_clk[n*CNT +: CNT]),
.rx_rst_in('{CNT{1'b0}}),
.rx_rst_out(eth_gty_rx_rst[n*CNT +: CNT]),
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
.tx_rst_in('{CNT{1'b0}}),
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
/*
* MAC clocks
*/
.rx_clk(eth_gty_rx_clk[n]),
.rx_rst_in(1'b0),
.rx_rst_out(eth_gty_rx_rst[n]),
.tx_clk(eth_gty_tx_clk[n]),
.tx_rst_in(1'b0),
.tx_rst_out(eth_gty_tx_rst[n]),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(eth_gty_axis_tx[n*CNT +: CNT]),
.m_axis_tx_cpl(eth_gty_axis_tx_cpl[n*CNT +: CNT]),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(eth_gty_axis_tx[n]),
.m_axis_tx_cpl(eth_gty_axis_tx_cpl[n]),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(eth_gty_axis_rx[n*CNT +: CNT]),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(eth_gty_axis_rx[n]),
/*
* USXGMII autonegotiation
*/
.an_en('{CNT{1'b1}}),
.an_restart('{CNT{1'b0}}),
.an_speedup('{CNT{1'b0}}),
.an_timeout_en('{CNT{1'b1}}),
.an_usxgmii_en('{CNT{1'b0}}),
.an_usxgmii_auto('{CNT{1'b1}}),
.an_intr(),
.an_running(),
.an_complete(),
.an_timeout(),
.an_usxgmii_mode(),
.an_adv_ability_usxgmii('{CNT{16'h1601}}),
.an_lp_adv_ability(),
.an_lp_usxgmii_link(),
.an_lp_usxgmii_speed(),
.an_res_full_duplex(),
/*
* PTP clock
*/
.ptp_clk(1'b0),
.ptp_rst(1'b0),
.ptp_sample_clk(1'b0),
.ptp_td_sdi(1'b0),
.tx_ptp_ts_in('0),
.tx_ptp_ts_out(),
.tx_ptp_ts_step_out(),
.tx_ptp_locked(),
.rx_ptp_ts_in('0),
.rx_ptp_ts_out(),
.rx_ptp_ts_step_out(),
.rx_ptp_locked(),
/*
* PTP clock
*/
.ptp_clk(1'b0),
.ptp_rst(1'b0),
.ptp_sample_clk(1'b0),
.ptp_td_sdi(1'b0),
.tx_ptp_ts_in('{CNT{'0}}),
.tx_ptp_ts_out(),
.tx_ptp_ts_step_out(),
.tx_ptp_locked(),
.rx_ptp_ts_in('{CNT{'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(1'b0),
.tx_lfc_resend(1'b0),
.rx_lfc_en(1'b0),
.rx_lfc_req(),
.rx_lfc_ack(1'b0),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
*/
.tx_lfc_req('{CNT{1'b0}}),
.tx_lfc_resend('{CNT{1'b0}}),
.rx_lfc_en('{CNT{1'b0}}),
.rx_lfc_req(),
.rx_lfc_ack('{CNT{1'b0}}),
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
.tx_pfc_req('0),
.tx_pfc_resend(1'b0),
.rx_pfc_en('0),
.rx_pfc_req(),
.rx_pfc_ack('0),
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
.tx_pfc_req('{CNT{'0}}),
.tx_pfc_resend('{CNT{1'b0}}),
.rx_pfc_en('{CNT{'0}}),
.rx_pfc_req(),
.rx_pfc_ack('{CNT{'0}}),
/*
* Pause interface
*/
.tx_lfc_pause_en(1'b0),
.tx_pause_req(1'b0),
.tx_pause_ack(),
/*
* Pause interface
*/
.tx_lfc_pause_en('{CNT{1'b0}}),
.tx_pause_req('{CNT{1'b0}}),
.tx_pause_ack(),
/*
* Statistics
*/
.stat_clk(clk_125mhz),
.stat_rst(rst_125mhz),
.m_axis_stat(axis_eth_stat[n]),
/*
* Statistics
*/
.stat_clk(clk_125mhz),
.stat_rst(rst_125mhz),
.m_axis_stat(axis_eth_stat[n]),
/*
* 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(eth_gty_rx_status[n]),
.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(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(),
/*
* 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(eth_gty_rx_status[n*CNT +: CNT]),
.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('{CNT{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),
.cfg_tx_prbs31_enable(1'b0),
.cfg_rx_prbs31_enable(1'b0),
.cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01),
.cfg_mcf_rx_check_eth_dst_mcast(1'b1),
.cfg_mcf_rx_eth_dst_ucast(48'd0),
.cfg_mcf_rx_check_eth_dst_ucast(1'b0),
.cfg_mcf_rx_eth_src(48'd0),
.cfg_mcf_rx_check_eth_src(1'b0),
.cfg_mcf_rx_eth_type(16'h8808),
.cfg_mcf_rx_opcode_lfc(16'h0001),
.cfg_mcf_rx_check_opcode_lfc(1'b1),
.cfg_mcf_rx_opcode_pfc(16'h0101),
.cfg_mcf_rx_check_opcode_pfc(1'b1),
.cfg_mcf_rx_forward(1'b0),
.cfg_mcf_rx_enable(1'b0),
.cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01),
.cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C),
.cfg_tx_lfc_eth_type(16'h8808),
.cfg_tx_lfc_opcode(16'h0001),
.cfg_tx_lfc_en(1'b0),
.cfg_tx_lfc_quanta(16'hffff),
.cfg_tx_lfc_refresh(16'h7fff),
.cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01),
.cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C),
.cfg_tx_pfc_eth_type(16'h8808),
.cfg_tx_pfc_opcode(16'h0101),
.cfg_tx_pfc_en(1'b0),
.cfg_tx_pfc_quanta('{8{16'hffff}}),
.cfg_tx_pfc_refresh('{8{16'h7fff}}),
.cfg_rx_lfc_opcode(16'h0001),
.cfg_rx_lfc_en(1'b0),
.cfg_rx_pfc_opcode(16'h0101),
.cfg_rx_pfc_en(1'b0)
);
/*
* Configuration
*/
.cfg_tx_pad_en('{CNT{1'b1}}),
.cfg_tx_min_pkt_len('{CNT{8'd60-1}}),
.cfg_tx_max_pkt_len('{CNT{16'd9218-1}}),
.cfg_tx_ifg('{CNT{8'd12}}),
.cfg_tx_enable('{CNT{1'b1}}),
.cfg_rx_max_pkt_len('{CNT{16'd9218-1}}),
.cfg_rx_enable('{CNT{1'b1}}),
.cfg_tx_prbs31_enable('{CNT{1'b0}}),
.cfg_rx_prbs31_enable('{CNT{1'b0}}),
.cfg_mcf_rx_eth_dst_mcast('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_mcf_rx_check_eth_dst_mcast('{CNT{1'b1}}),
.cfg_mcf_rx_eth_dst_ucast('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_dst_ucast('{CNT{1'b0}}),
.cfg_mcf_rx_eth_src('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_src('{CNT{1'b0}}),
.cfg_mcf_rx_eth_type('{CNT{16'h8808}}),
.cfg_mcf_rx_opcode_lfc('{CNT{16'h0001}}),
.cfg_mcf_rx_check_opcode_lfc('{CNT{1'b1}}),
.cfg_mcf_rx_opcode_pfc('{CNT{16'h0101}}),
.cfg_mcf_rx_check_opcode_pfc('{CNT{1'b1}}),
.cfg_mcf_rx_forward('{CNT{1'b0}}),
.cfg_mcf_rx_enable('{CNT{1'b0}}),
.cfg_tx_lfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_lfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_lfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_lfc_opcode('{CNT{16'h0001}}),
.cfg_tx_lfc_en('{CNT{1'b0}}),
.cfg_tx_lfc_quanta('{CNT{16'hffff}}),
.cfg_tx_lfc_refresh('{CNT{16'h7fff}}),
.cfg_tx_pfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_pfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_pfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_pfc_opcode('{CNT{16'h0101}}),
.cfg_tx_pfc_en('{CNT{1'b0}}),
.cfg_tx_pfc_quanta('{CNT{'{8{16'hffff}}}}),
.cfg_tx_pfc_refresh('{CNT{'{8{16'h7fff}}}}),
.cfg_rx_lfc_opcode('{CNT{16'h0001}}),
.cfg_rx_lfc_en('{CNT{1'b0}}),
.cfg_rx_pfc_opcode('{CNT{16'h0101}}),
.cfg_rx_pfc_en('{CNT{1'b0}})
);
end else begin: mac
taxi_eth_mac_25g_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
.CNT(CNT),
// GT config
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
// GT type
.GT_TYPE("GTY"),
// MAC/PHY config
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.DATA_W(eth_gty_axis_tx[0].DATA_W),
.USXGMII_EN(COMBINED_MAC_PCS),
.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(n*CNT*(16+16)),
.STAT_UPDATE_PERIOD(1024),
.STAT_STR_EN(1),
.STAT_PREFIX_STR(
n == 0 ? STAT_PREFIX_STR_QSFP1 :
n == 1 ? STAT_PREFIX_STR_QSFP2 :
n == 2 ? STAT_PREFIX_STR_QSFP3 :
n == 3 ? STAT_PREFIX_STR_QSFP4 :
n == 4 ? STAT_PREFIX_STR_QSFP5 :
n == 5 ? STAT_PREFIX_STR_QSFP6 :
n == 6 ? STAT_PREFIX_STR_QSFP7 :
n == 7 ? STAT_PREFIX_STR_QSFP8 :
n == 8 ? STAT_PREFIX_STR_QSFP9 :
n == 9 ? STAT_PREFIX_STR_QSFP10 :
n == 10 ? STAT_PREFIX_STR_QSFP11 :
n == 11 ? STAT_PREFIX_STR_QSFP12 :
n == 12 ? STAT_PREFIX_STR_QSFP13 :
n == 13 ? STAT_PREFIX_STR_QSFP14 :
STAT_PREFIX_STR_QSFP15
)
)
mac_inst (
.xcvr_ctrl_clk(clk_125mhz),
.xcvr_ctrl_rst(eth_gty_rst[CLK]),
/*
* Transceiver control
*/
.s_apb_ctrl(gt_apb_ctrl),
/*
* Common
*/
.xcvr_gtpowergood_out(eth_gty_gtpowergood[n]),
.xcvr_gtrefclk00_in(eth_gty_mgt_refclk[CLK]),
.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(eth_gty_mgt_refclk[CLK]),
.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(eth_gty_tx_p[n*CNT +: CNT]),
.xcvr_txn(eth_gty_tx_n[n*CNT +: CNT]),
.xcvr_rxp(eth_gty_rx_p[n*CNT +: CNT]),
.xcvr_rxn(eth_gty_rx_n[n*CNT +: CNT]),
/*
* MAC clocks
*/
.rx_clk(eth_gty_rx_clk[n*CNT +: CNT]),
.rx_rst_in('{CNT{1'b0}}),
.rx_rst_out(eth_gty_rx_rst[n*CNT +: CNT]),
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
.tx_rst_in('{CNT{1'b0}}),
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(eth_gty_axis_tx[n*CNT +: CNT]),
.m_axis_tx_cpl(eth_gty_axis_tx_cpl[n*CNT +: CNT]),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(eth_gty_axis_rx[n*CNT +: CNT]),
/*
* USXGMII autonegotiation
*/
.an_en('{CNT{1'b1}}),
.an_restart('{CNT{1'b0}}),
.an_speedup('{CNT{1'b0}}),
.an_timeout_en('{CNT{1'b1}}),
.an_usxgmii_en('{CNT{1'b0}}),
.an_usxgmii_auto('{CNT{1'b1}}),
.an_intr(),
.an_running(),
.an_complete(),
.an_timeout(),
.an_usxgmii_mode(),
.an_adv_ability_usxgmii('{CNT{16'h1601}}),
.an_lp_adv_ability(),
.an_lp_usxgmii_link(),
.an_lp_usxgmii_speed(),
.an_res_full_duplex(),
/*
* PTP clock
*/
.ptp_clk(1'b0),
.ptp_rst(1'b0),
.ptp_sample_clk(1'b0),
.ptp_td_sdi(1'b0),
.tx_ptp_ts_in('{CNT{'0}}),
.tx_ptp_ts_out(),
.tx_ptp_ts_step_out(),
.tx_ptp_locked(),
.rx_ptp_ts_in('{CNT{'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('{CNT{1'b0}}),
.tx_lfc_resend('{CNT{1'b0}}),
.rx_lfc_en('{CNT{1'b0}}),
.rx_lfc_req(),
.rx_lfc_ack('{CNT{1'b0}}),
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
.tx_pfc_req('{CNT{'0}}),
.tx_pfc_resend('{CNT{1'b0}}),
.rx_pfc_en('{CNT{'0}}),
.rx_pfc_req(),
.rx_pfc_ack('{CNT{'0}}),
/*
* Pause interface
*/
.tx_lfc_pause_en('{CNT{1'b0}}),
.tx_pause_req('{CNT{1'b0}}),
.tx_pause_ack(),
/*
* Statistics
*/
.stat_clk(clk_125mhz),
.stat_rst(rst_125mhz),
.m_axis_stat(axis_eth_stat[n]),
/*
* 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(eth_gty_rx_status[n*CNT +: CNT]),
.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('{CNT{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('{CNT{1'b1}}),
.cfg_tx_min_pkt_len('{CNT{8'd60-1}}),
.cfg_tx_max_pkt_len('{CNT{16'd9218-1}}),
.cfg_tx_ifg('{CNT{8'd12}}),
.cfg_tx_enable('{CNT{1'b1}}),
.cfg_rx_max_pkt_len('{CNT{16'd9218-1}}),
.cfg_rx_enable('{CNT{1'b1}}),
.cfg_tx_prbs31_enable('{CNT{1'b0}}),
.cfg_rx_prbs31_enable('{CNT{1'b0}}),
.cfg_mcf_rx_eth_dst_mcast('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_mcf_rx_check_eth_dst_mcast('{CNT{1'b1}}),
.cfg_mcf_rx_eth_dst_ucast('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_dst_ucast('{CNT{1'b0}}),
.cfg_mcf_rx_eth_src('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_src('{CNT{1'b0}}),
.cfg_mcf_rx_eth_type('{CNT{16'h8808}}),
.cfg_mcf_rx_opcode_lfc('{CNT{16'h0001}}),
.cfg_mcf_rx_check_opcode_lfc('{CNT{1'b1}}),
.cfg_mcf_rx_opcode_pfc('{CNT{16'h0101}}),
.cfg_mcf_rx_check_opcode_pfc('{CNT{1'b1}}),
.cfg_mcf_rx_forward('{CNT{1'b0}}),
.cfg_mcf_rx_enable('{CNT{1'b0}}),
.cfg_tx_lfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_lfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_lfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_lfc_opcode('{CNT{16'h0001}}),
.cfg_tx_lfc_en('{CNT{1'b0}}),
.cfg_tx_lfc_quanta('{CNT{16'hffff}}),
.cfg_tx_lfc_refresh('{CNT{16'h7fff}}),
.cfg_tx_pfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_pfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_pfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_pfc_opcode('{CNT{16'h0101}}),
.cfg_tx_pfc_en('{CNT{1'b0}}),
.cfg_tx_pfc_quanta('{CNT{'{8{16'hffff}}}}),
.cfg_tx_pfc_refresh('{CNT{'{8{16'h7fff}}}}),
.cfg_rx_lfc_opcode('{CNT{16'h0001}}),
.cfg_rx_lfc_en('{CNT{1'b0}}),
.cfg_rx_pfc_opcode('{CNT{16'h0101}}),
.cfg_rx_pfc_en('{CNT{1'b0}})
);
end
end
for (genvar n = 0; n < GTY_CNT; n = n + 1) begin : gty_ch
for (genvar n = 0; n < $size(eth_gty_axis_tx); n = n + 1) begin : gty_ch
taxi_axis_async_fifo #(
.DEPTH(16384),

View File

@@ -0,0 +1,11 @@
# CMACs
set_property LOC CMACE4_X0Y10 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[0].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y9 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[1].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y8 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[2].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y7 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[3].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y6 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[4].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y5 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[5].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y4 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[6].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y3 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[7].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y2 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[8].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]

View File

@@ -0,0 +1,11 @@
# CMACs
set_property LOC CMACE4_X0Y8 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[0].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y7 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[1].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y6 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[2].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y5 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[3].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y4 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[4].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y3 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[5].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y2 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[6].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y1 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[7].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]
set_property LOC CMACE4_X0Y0 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[8].mac.mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMACE4}]

View File

@@ -25,6 +25,7 @@ TOPLEVEL = $(COCOTB_TOPLEVEL)
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv
VERILOG_SOURCES += $(RTL_DIR)/../pll/si5341_i2c_init.sv
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_100g_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_apb.f
@@ -51,7 +52,7 @@ export PARAM_GTY_CNT := $(shell echo $$(( 4 * $(PARAM_GTY_QUAD_CNT) )))
export PARAM_GTY_CLK_CNT := $(PARAM_GTY_QUAD_CNT)
export PARAM_CFG_LOW_LATENCY := "1'b1"
export PARAM_COMBINED_MAC_PCS := "1'b1"
export PARAM_MAC_DATA_W := "64"
export PARAM_MAC_DATA_W := "512"
ifeq ($(SIM), icarus)
PLUSARGS += -fst

View File

@@ -2,7 +2,7 @@
# SPDX-License-Identifier: MIT
"""
Copyright (c) 2020-2025 FPGA Ninja, LLC
Copyright (c) 2020-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
@@ -21,7 +21,10 @@ import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, Combine
from cocotbext.eth import EthMacFrame, EthMac
from cocotbext.eth import GmiiFrame
from cocotbext.eth import XgmiiFrame
from cocotbext.axi import AxiStreamBus
from cocotbext.uart import UartSource, UartSink
try:
@@ -53,47 +56,78 @@ class TB:
for clk in dut.eth_gty_mgt_refclk_p:
cocotb.start_soon(Clock(clk, 6.206, units="ns").start())
for ch in itertools.chain.from_iterable([inst.mac_inst.ch for inst in dut.gt_quad]):
gt_inst = ch.ch_inst.gt.gt_inst
has_cmac = False
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:
if ch.ch_inst.CFG_LOW_LATENCY.value:
for quad in dut.gt_quad:
if dut.MAC_DATA_W.value == 512:
inst = quad.mac.mac_inst
has_cmac = True
mac = EthMac(
tx_clk=inst.ch[0].ch_inst.gt.gt_inst.gt_txoutclk,
tx_rst=inst.tx_rst_out,
tx_bus=AxiStreamBus.from_entity(inst.cmac.cmac_axis_tx),
# tx_ptp_time=inst.tx_ptp_ts_out,
# tx_ptp_ts=inst.tx_ptp_ts,
# tx_ptp_ts_tag=inst.tx_ptp_ts_tag,
# tx_ptp_ts_valid=inst.tx_ptp_ts_valid,
rx_clk=inst.ch[0].ch_inst.gt.gt_inst.gt_rxoutclk,
rx_rst=inst.rx_rst_out,
rx_bus=AxiStreamBus.from_entity(inst.cmac.cmac_axis_rx),
# rx_ptp_time=inst.rx_ptp_ts_out,
ifg=12, speed=100e9
)
self.qsfp_sources.append(mac.rx)
self.qsfp_sinks.append(mac.tx)
for ch in quad.mac.mac_inst.ch:
gt_inst = ch.ch_inst.gt.gt_inst
if has_cmac:
clk = 3.102
gbx_cfg = (66, [64, 65])
cocotb.start_soon(Clock(gt_inst.gt_txoutclk, clk, units="ns").start())
cocotb.start_soon(Clock(gt_inst.gt_rxoutclk, clk, units="ns").start())
continue
elif 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.qsfp_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.qsfp_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.qsfp_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.qsfp_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.i2c_scl_i.setimmediatevalue(1)
dut.i2c_sda_i.setimmediatevalue(1)
@@ -120,12 +154,9 @@ class TB:
await RisingEdge(self.dut.clk_125mhz)
async def mac_test(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_125mhz)
async def mac_test(tb, source, sink, frame_type=GmiiFrame):
tb.log.info("Test MAC")
sink.clear()
@@ -136,7 +167,7 @@ async def mac_test(tb, source, sink):
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
for p in pkts:
await source.send(XgmiiFrame.from_payload(p))
await source.send(frame_type.from_payload(p))
for k in range(count):
rx_frame = await sink.recv()
@@ -153,7 +184,7 @@ async def mac_test(tb, source, sink):
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
for p in pkts:
await source.send(XgmiiFrame.from_payload(p))
await source.send(frame_type.from_payload(p))
for k in range(count):
rx_frame = await sink.recv()
@@ -175,10 +206,18 @@ async def run_test(dut):
tests = []
tb.log.info("Wait for block lock")
for k in range(1200):
await RisingEdge(dut.clk_125mhz)
ft = XgmiiFrame
if dut.MAC_DATA_W.value == 512:
ft = EthMacFrame
for k in range(len(tb.qsfp_sources)):
tb.log.info("Start QSFP %d MAC loopback test", k)
tests.append(cocotb.start_soon(mac_test(tb, tb.qsfp_sources[k], tb.qsfp_sinks[k])))
tests.append(cocotb.start_soon(mac_test(tb, tb.qsfp_sources[k], tb.qsfp_sinks[k], ft)))
await Combine(*tests)
@@ -207,7 +246,7 @@ def process_f_files(files):
return list(lst.values())
@pytest.mark.parametrize("mac_data_w", [32, 64])
@pytest.mark.parametrize("mac_data_w", [32, 64, 512])
def test_fpga_core(request, mac_data_w):
dut = "fpga_core"
module = os.path.splitext(os.path.basename(__file__))[0]
@@ -217,6 +256,7 @@ def test_fpga_core(request, mac_data_w):
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(rtl_dir, "..", "pll", "si5341_i2c_init.sv"),
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_100g_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_apb.f"),