mirror of
https://github.com/fpganinja/taxi.git
synced 2026-08-15 03:41:24 -07:00
eth: Add 100G configuration to NT200A01/XT200A02 example design
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -19,7 +19,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
|
||||
SYN_FILES = $(RTL_DIR)/fpga_nt200a01.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(RTL_DIR)/../pll/si5340_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)/lss/rtl/taxi_i2c_master.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
|
||||
@@ -29,13 +29,15 @@ SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
|
||||
XDC_FILES += ../syn/NT200A01/fpga.xdc
|
||||
XDC_FILES += ../syn/NT200A01/gpio.xdc
|
||||
XDC_FILES += ../syn/NT200A01/qsfp.xdc
|
||||
XDC_FILES += ../syn/NT200A01/eth_cmac.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_322.tcl
|
||||
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_cmace3.tcl
|
||||
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_100g_us_gty_322.tcl
|
||||
|
||||
# Configuration
|
||||
CONFIG_TCL_FILES = config.tcl
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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"
|
||||
|
||||
159
src/eth/example/NT200A02/fpga/fpga_NT200A01_25g/Makefile
Normal file
159
src/eth/example/NT200A02/fpga/fpga_NT200A01_25g/Makefile
Normal file
@@ -0,0 +1,159 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcvu095-ffva2104-2-e
|
||||
FPGA_TOP = fpga
|
||||
FPGA_ARCH = virtexu
|
||||
|
||||
RTL_DIR = ../rtl
|
||||
LIB_DIR = ../lib
|
||||
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = $(RTL_DIR)/fpga_nt200a01.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(RTL_DIR)/../pll/si5340_i2c_init.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/lss/rtl/taxi_i2c_master.sv
|
||||
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
|
||||
|
||||
# XDC files
|
||||
XDC_FILES += ../syn/NT200A01/fpga.xdc
|
||||
XDC_FILES += ../syn/NT200A01/gpio.xdc
|
||||
XDC_FILES += ../syn/NT200A01/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_322.tcl
|
||||
|
||||
# Configuration
|
||||
CONFIG_TCL_FILES = config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
%_fallback.bit: %.bit
|
||||
echo "open_project $*.xpr" > generate_fallback_bit.tcl
|
||||
echo "open_run impl_1" >> generate_fallback_bit.tcl
|
||||
echo "startgroup" >> generate_fallback_bit.tcl
|
||||
echo "set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]" >> generate_fallback_bit.tcl
|
||||
echo "endgroup" >> generate_fallback_bit.tcl
|
||||
echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl
|
||||
echo "undo" >> generate_fallback_bit.tcl
|
||||
echo "exit" >> generate_fallback_bit.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl
|
||||
mkdir -p rev
|
||||
EXT=bit; COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \
|
||||
echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT";
|
||||
|
||||
program: $(FPGA_TOP).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 {$(FPGA_TOP).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
|
||||
|
||||
%.mcs %.prm: %.bit
|
||||
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx4 -loadbit {up 0x00000000 $*.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;
|
||||
|
||||
%_fallback.mcs %_fallback.prm: %_fallback.bit
|
||||
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx4 -loadbit {up 0x03000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl
|
||||
echo "exit" >> generate_fallback_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_fallback_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 $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done;
|
||||
|
||||
%_full.mcs %_full.prm: %_fallback.bit %.bit
|
||||
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx4 -loadbit {up 0x00000000 $*.bit up 0x03000000 $*_fallback.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl
|
||||
echo "exit" >> generate_full_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_full_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 $*_full$$x rev/$*_full_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_full_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||
echo "open_hw_manager" > 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 {mt25ql512-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 \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).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
|
||||
|
||||
flash%: $(FPGA_TOP)%.mcs $(FPGA_TOP)%.prm
|
||||
echo "open_hw_manager" > 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 {mt25ql512-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 \"$(FPGA_TOP)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)$*.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
|
||||
22
src/eth/example/NT200A02/fpga/fpga_NT200A01_25g/config.tcl
Normal file
22
src/eth/example/NT200A02/fpga/fpga_NT200A01_25g/config.tcl
Normal 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]
|
||||
@@ -19,7 +19,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
|
||||
SYN_FILES = $(RTL_DIR)/fpga_nt200a02.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(RTL_DIR)/../pll/si5340_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)/lss/rtl/taxi_i2c_master.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
|
||||
@@ -29,13 +29,15 @@ SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
|
||||
XDC_FILES += ../syn/NT200A02/fpga.xdc
|
||||
XDC_FILES += ../syn/NT200A02/gpio.xdc
|
||||
XDC_FILES += ../syn/NT200A02/qsfp.xdc
|
||||
XDC_FILES += ../syn/NT200A02/eth_cmac.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_322.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_322.tcl
|
||||
|
||||
# Configuration
|
||||
CONFIG_TCL_FILES = config.tcl
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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"
|
||||
|
||||
159
src/eth/example/NT200A02/fpga/fpga_NT200A02_25g/Makefile
Normal file
159
src/eth/example/NT200A02/fpga/fpga_NT200A02_25g/Makefile
Normal file
@@ -0,0 +1,159 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcvu5p-flva2104-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_nt200a02.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(RTL_DIR)/../pll/si5340_i2c_init.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/lss/rtl/taxi_i2c_master.sv
|
||||
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
|
||||
|
||||
# XDC files
|
||||
XDC_FILES += ../syn/NT200A02/fpga.xdc
|
||||
XDC_FILES += ../syn/NT200A02/gpio.xdc
|
||||
XDC_FILES += ../syn/NT200A02/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_322.tcl
|
||||
|
||||
# Configuration
|
||||
CONFIG_TCL_FILES = config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
%_fallback.bit: %.bit
|
||||
echo "open_project $*.xpr" > generate_fallback_bit.tcl
|
||||
echo "open_run impl_1" >> generate_fallback_bit.tcl
|
||||
echo "startgroup" >> generate_fallback_bit.tcl
|
||||
echo "set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]" >> generate_fallback_bit.tcl
|
||||
echo "endgroup" >> generate_fallback_bit.tcl
|
||||
echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl
|
||||
echo "undo" >> generate_fallback_bit.tcl
|
||||
echo "exit" >> generate_fallback_bit.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl
|
||||
mkdir -p rev
|
||||
EXT=bit; COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \
|
||||
echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT";
|
||||
|
||||
program: $(FPGA_TOP).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 {$(FPGA_TOP).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
|
||||
|
||||
%.mcs %.prm: %.bit
|
||||
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.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;
|
||||
|
||||
%_fallback.mcs %_fallback.prm: %_fallback.bit
|
||||
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x0C000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl
|
||||
echo "exit" >> generate_fallback_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_fallback_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 $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done;
|
||||
|
||||
%_full.mcs %_full.prm: %_fallback.bit %.bit
|
||||
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit up 0x0C000000 $*_fallback.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl
|
||||
echo "exit" >> generate_full_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_full_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 $*_full$$x rev/$*_full_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_full_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||
echo "open_hw_manager" > 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 {mt25qu02g-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 \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).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
|
||||
|
||||
flash%: $(FPGA_TOP)%.mcs $(FPGA_TOP)%.prm
|
||||
echo "open_hw_manager" > 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 {mt25qu02g-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 \"$(FPGA_TOP)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)$*.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
|
||||
22
src/eth/example/NT200A02/fpga/fpga_NT200A02_25g/config.tcl
Normal file
22
src/eth/example/NT200A02/fpga/fpga_NT200A02_25g/config.tcl
Normal 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]
|
||||
@@ -28,11 +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
|
||||
)
|
||||
(
|
||||
/*
|
||||
@@ -79,30 +78,43 @@ assign eth_port_i2c_scl_o = '1;
|
||||
assign eth_port_i2c_sda_o = '1;
|
||||
|
||||
// QSFP28
|
||||
localparam MAC_CNT = MAC_DATA_W > 64 ? GTY_QUAD_CNT : GTY_CNT;
|
||||
|
||||
assign eth_port_resetl = '1;
|
||||
assign eth_port_lpmode = '0;
|
||||
|
||||
wire eth_gty_tx_clk[GTY_CNT];
|
||||
wire eth_gty_tx_rst[GTY_CNT];
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) eth_gty_axis_tx[GTY_CNT]();
|
||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) eth_gty_axis_tx_cpl[GTY_CNT]();
|
||||
wire eth_gty_tx_clk[MAC_CNT];
|
||||
wire eth_gty_tx_rst[MAC_CNT];
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) eth_gty_axis_tx[MAC_CNT]();
|
||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) eth_gty_axis_tx_cpl[MAC_CNT]();
|
||||
|
||||
wire eth_gty_rx_clk[GTY_CNT];
|
||||
wire eth_gty_rx_rst[GTY_CNT];
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) eth_gty_axis_rx[GTY_CNT]();
|
||||
wire eth_gty_rx_clk[MAC_CNT];
|
||||
wire eth_gty_rx_rst[MAC_CNT];
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) eth_gty_axis_rx[MAC_CNT]();
|
||||
|
||||
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[GTY_QUAD_CNT]();
|
||||
|
||||
wire eth_gty_rx_status[GTY_CNT];
|
||||
wire eth_gty_rx_status[MAC_CNT];
|
||||
|
||||
assign qsfp_led[0][0] = eth_gty_rx_status[0];
|
||||
assign qsfp_led[0][1] = eth_gty_rx_status[1];
|
||||
assign qsfp_led[0][2] = eth_gty_rx_status[2];
|
||||
assign qsfp_led[0][3] = eth_gty_rx_status[3];
|
||||
assign qsfp_led[1][0] = eth_gty_rx_status[4];
|
||||
assign qsfp_led[1][1] = eth_gty_rx_status[5];
|
||||
assign qsfp_led[1][2] = eth_gty_rx_status[6];
|
||||
assign qsfp_led[1][3] = eth_gty_rx_status[7];
|
||||
if (MAC_CNT == 2) begin
|
||||
assign qsfp_led[0][0] = eth_gty_rx_status[0];
|
||||
assign qsfp_led[0][1] = 1'b0;
|
||||
assign qsfp_led[0][2] = 1'b0;
|
||||
assign qsfp_led[0][3] = 1'b0;
|
||||
assign qsfp_led[1][0] = eth_gty_rx_status[1];
|
||||
assign qsfp_led[1][1] = 1'b0;
|
||||
assign qsfp_led[1][2] = 1'b0;
|
||||
assign qsfp_led[1][3] = 1'b0;
|
||||
end else begin
|
||||
assign qsfp_led[0][0] = eth_gty_rx_status[0];
|
||||
assign qsfp_led[0][1] = eth_gty_rx_status[1];
|
||||
assign qsfp_led[0][2] = eth_gty_rx_status[2];
|
||||
assign qsfp_led[0][3] = eth_gty_rx_status[3];
|
||||
assign qsfp_led[1][0] = eth_gty_rx_status[4];
|
||||
assign qsfp_led[1][1] = eth_gty_rx_status[5];
|
||||
assign qsfp_led[1][2] = eth_gty_rx_status[6];
|
||||
assign qsfp_led[1][3] = eth_gty_rx_status[7];
|
||||
end
|
||||
|
||||
wire [GTY_QUAD_CNT-1:0] eth_gty_gtpowergood;
|
||||
|
||||
@@ -173,6 +185,7 @@ localparam logic [8*8-1:0] STAT_PREFIX_STR_QSFP1[4] = '{"QSFP1.1", "QSFP1.2", "Q
|
||||
|
||||
for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gt_quad
|
||||
|
||||
localparam CLK = n;
|
||||
localparam CNT = 4;
|
||||
|
||||
taxi_apb_if #(
|
||||
@@ -181,274 +194,515 @@ for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gt_quad
|
||||
)
|
||||
gt_apb_ctrl();
|
||||
|
||||
taxi_eth_mac_25g_us #(
|
||||
.SIM(SIM),
|
||||
.VENDOR(VENDOR),
|
||||
.FAMILY(FAMILY),
|
||||
if (MAC_DATA_W == 512) begin: mac
|
||||
|
||||
.CNT(4),
|
||||
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),
|
||||
|
||||
// GT parameters
|
||||
.GT_TX_POLARITY(n == 0 ? 4'b0101 : 4'b0001),
|
||||
.GT_RX_POLARITY(n == 0 ? 4'b1011 : 4'b0011),
|
||||
// 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(0),
|
||||
.STAT_TX_LEVEL(1),
|
||||
.STAT_RX_LEVEL(1),
|
||||
.STAT_ID_BASE(n*CNT*(16+16)),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(0),
|
||||
.STAT_PREFIX_STR(n == 0 ? STAT_PREFIX_STR_QSFP0 : STAT_PREFIX_STR_QSFP1)
|
||||
)
|
||||
mac_inst (
|
||||
.xcvr_ctrl_clk(clk_125mhz),
|
||||
.xcvr_ctrl_rst(eth_gty_rst[n]),
|
||||
// GT parameters
|
||||
.GT_TX_POLARITY(n == 0 ? 4'b0101 : 4'b0001),
|
||||
.GT_RX_POLARITY(n == 0 ? 4'b1011 : 4'b0011),
|
||||
|
||||
/*
|
||||
* Transceiver control
|
||||
*/
|
||||
.s_apb_ctrl(gt_apb_ctrl),
|
||||
// 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(0),
|
||||
.STAT_TX_LEVEL(1),
|
||||
.STAT_RX_LEVEL(1),
|
||||
.STAT_ID_BASE(n*CNT*(16+16)),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(0),
|
||||
.STAT_PREFIX_STR(n == 0 ? "QSFP0" : "QSFP1")
|
||||
)
|
||||
mac_inst (
|
||||
.xcvr_ctrl_clk(clk_125mhz),
|
||||
.xcvr_ctrl_rst(eth_gty_rst[CLK]),
|
||||
|
||||
/*
|
||||
* Common
|
||||
*/
|
||||
.xcvr_gtpowergood_out(eth_gty_gtpowergood[n]),
|
||||
.xcvr_gtrefclk00_in(eth_gty_mgt_refclk[n]),
|
||||
.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[n]),
|
||||
.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(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]),
|
||||
/*
|
||||
* 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(),
|
||||
|
||||
/*
|
||||
* 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]),
|
||||
/*
|
||||
* 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]),
|
||||
|
||||
/*
|
||||
* 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]),
|
||||
/*
|
||||
* 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]),
|
||||
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(eth_gty_axis_rx[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]),
|
||||
|
||||
/*
|
||||
* 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(),
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(eth_gty_axis_rx[n]),
|
||||
|
||||
/*
|
||||
* 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(),
|
||||
/*
|
||||
* 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(),
|
||||
|
||||
/*
|
||||
* 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}}),
|
||||
/*
|
||||
* 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),
|
||||
|
||||
/*
|
||||
* 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}}),
|
||||
/*
|
||||
* 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),
|
||||
|
||||
/*
|
||||
* Pause interface
|
||||
*/
|
||||
.tx_lfc_pause_en('{CNT{1'b0}}),
|
||||
.tx_pause_req('{CNT{1'b0}}),
|
||||
.tx_pause_ack(),
|
||||
/*
|
||||
* Pause interface
|
||||
*/
|
||||
.tx_lfc_pause_en(1'b0),
|
||||
.tx_pause_req(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*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(),
|
||||
/*
|
||||
* 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(),
|
||||
|
||||
/*
|
||||
* 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}})
|
||||
);
|
||||
/*
|
||||
* 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)
|
||||
);
|
||||
|
||||
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"),
|
||||
|
||||
// GT parameters
|
||||
.GT_TX_POLARITY(n == 0 ? 4'b0101 : 4'b0001),
|
||||
.GT_RX_POLARITY(n == 0 ? 4'b1011 : 4'b0011),
|
||||
|
||||
// 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(0),
|
||||
.STAT_TX_LEVEL(1),
|
||||
.STAT_RX_LEVEL(1),
|
||||
.STAT_ID_BASE(n*CNT*(16+16)),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(0),
|
||||
.STAT_PREFIX_STR(n == 0 ? STAT_PREFIX_STR_QSFP0 : STAT_PREFIX_STR_QSFP1)
|
||||
)
|
||||
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 : qsfp_ch
|
||||
for (genvar n = 0; n < $size(eth_gty_axis_tx); n = n + 1) begin : gty_ch
|
||||
|
||||
taxi_axis_async_fifo #(
|
||||
.DEPTH(16384),
|
||||
|
||||
@@ -23,10 +23,10 @@ module fpga #
|
||||
parameter string VENDOR = "XILINX",
|
||||
// device family
|
||||
parameter string FAMILY = "virtexu",
|
||||
// 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
|
||||
)
|
||||
(
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
)
|
||||
(
|
||||
/*
|
||||
|
||||
4
src/eth/example/NT200A02/fpga/syn/NT200A01/eth_cmac.xdc
Normal file
4
src/eth/example/NT200A02/fpga/syn/NT200A01/eth_cmac.xdc
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
# CMACs
|
||||
set_property LOC CMAC_SITE_X0Y2 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[0].mac.* && REF_NAME==CMAC}]
|
||||
set_property LOC CMAC_SITE_X0Y3 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[1].mac.* && REF_NAME==CMAC}]
|
||||
4
src/eth/example/NT200A02/fpga/syn/NT200A02/eth_cmac.xdc
Normal file
4
src/eth/example/NT200A02/fpga/syn/NT200A02/eth_cmac.xdc
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
# CMACs
|
||||
set_property LOC CMACE4_X0Y4 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[0].mac.* && REF_NAME==CMACE4}]
|
||||
set_property LOC CMACE4_X0Y5 [get_cells -hierarchical -filter {NAME =~ core_inst/gt_quad[1].mac.* && REF_NAME==CMACE4}]
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2020-2026 FPGA Ninja, LLC
|
||||
# Copyright (c) 2020-2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
@@ -24,6 +24,7 @@ MODULE = $(COCOTB_TEST_MODULES)
|
||||
TOPLEVEL = $(COCOTB_TOPLEVEL)
|
||||
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).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)/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
|
||||
@@ -44,7 +45,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
|
||||
|
||||
@@ -9,7 +9,6 @@ Authors:
|
||||
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@@ -21,7 +20,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
|
||||
|
||||
try:
|
||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||
@@ -49,47 +51,78 @@ class TB:
|
||||
for clk in dut.eth_gty_mgt_refclk_p:
|
||||
cocotb.start_soon(Clock(clk, 3.102, 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
|
||||
))
|
||||
|
||||
async def init(self):
|
||||
|
||||
@@ -109,13 +142,9 @@ class TB:
|
||||
await RisingEdge(self.dut.clk_125mhz)
|
||||
|
||||
|
||||
async def mac_test(tb, source, sink):
|
||||
async def mac_test(tb, source, sink, frame_type=GmiiFrame):
|
||||
tb.log.info("Test MAC")
|
||||
|
||||
tb.log.info("Wait for block lock")
|
||||
for k in range(1200):
|
||||
await RisingEdge(tb.dut.clk_125mhz)
|
||||
|
||||
sink.clear()
|
||||
|
||||
tb.log.info("Multiple small packets")
|
||||
@@ -125,7 +154,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()
|
||||
@@ -142,7 +171,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()
|
||||
@@ -164,12 +193,18 @@ async def run_test(dut):
|
||||
|
||||
tests = []
|
||||
|
||||
tb.log.info("Start BASE-T MAC loopback test")
|
||||
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)
|
||||
|
||||
@@ -198,7 +233,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]
|
||||
@@ -207,6 +242,7 @@ def test_fpga_core(request, mac_data_w):
|
||||
verilog_sources = [
|
||||
os.path.join(rtl_dir, f"{dut}.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, "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"),
|
||||
|
||||
Reference in New Issue
Block a user