mirror of
https://github.com/fpganinja/taxi.git
synced 2026-08-16 04:11:19 -07:00
eth: Add 100G configuration to VCU108 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.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_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
|
||||
@@ -33,6 +33,7 @@ XDC_FILES += ../syn/fpga.xdc
|
||||
XDC_FILES += ../syn/gpio.xdc
|
||||
XDC_FILES += ../syn/phy.xdc
|
||||
XDC_FILES += ../syn/qsfp.xdc
|
||||
XDC_FILES += ../syn/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
|
||||
@@ -40,7 +41,8 @@ XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
|
||||
|
||||
# IP
|
||||
IP_TCL_FILES = ../ip/sgmii_pcs_pma_0.tcl
|
||||
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.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_156.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"
|
||||
|
||||
97
src/eth/example/VCU108/fpga/fpga_25g/Makefile
Normal file
97
src/eth/example/VCU108/fpga/fpga_25g/Makefile
Normal file
@@ -0,0 +1,97 @@
|
||||
# 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.sv
|
||||
SYN_FILES += $(RTL_DIR)/fpga_core.sv
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f
|
||||
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_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_stats.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/phy.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 = ../ip/sgmii_pcs_pma_0.tcl
|
||||
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
|
||||
|
||||
# Configuration
|
||||
CONFIG_TCL_FILES = ./config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
program: $(PROJECT).bit
|
||||
echo "open_hw_manager" > program.tcl
|
||||
echo "connect_hw_server" >> program.tcl
|
||||
echo "open_hw_target" >> program.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||
echo "exit" >> program.tcl
|
||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||
|
||||
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
||||
echo "write_cfgmem -force -format mcs -size 128 -interface BPIx16 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||
echo "exit" >> generate_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||
mkdir -p rev
|
||||
COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
for x in .mcs .prm; \
|
||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(PROJECT).mcs $(PROJECT).prm
|
||||
echo "open_hw_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 {mt28gu01gaax1e-bpi-x16}] 0]" >> flash.tcl
|
||||
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.BPI_RS_PINS {25:24} [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/VCU108/fpga/fpga_25g/config.tcl
Normal file
22
src/eth/example/VCU108/fpga/fpga_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]
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2025 FPGA Ninja, LLC
|
||||
Copyright (c) 2014-2026 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
@@ -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
|
||||
)
|
||||
(
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2025 FPGA Ninja, LLC
|
||||
Copyright (c) 2014-2026 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
@@ -23,10 +23,10 @@ module fpga_core #
|
||||
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
|
||||
)
|
||||
(
|
||||
/*
|
||||
@@ -287,6 +287,8 @@ eth_mac_inst (
|
||||
);
|
||||
|
||||
// QSFP28
|
||||
localparam MAC_CNT = MAC_DATA_W > 64 ? 1 : 4;
|
||||
|
||||
assign qsfp_modsell = 1'b0;
|
||||
assign qsfp_resetl = 1'b1;
|
||||
assign qsfp_lpmode = 1'b0;
|
||||
@@ -315,10 +317,9 @@ wire qsfp_mgt_refclk_0_bufg;
|
||||
|
||||
wire qsfp_rst;
|
||||
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_qsfp_tx[4]();
|
||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_qsfp_tx_cpl[4]();
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_qsfp_rx[4]();
|
||||
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(8)) axis_qsfp_stat();
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_qsfp_tx[MAC_CNT]();
|
||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_qsfp_tx_cpl[MAC_CNT]();
|
||||
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_qsfp_rx[MAC_CNT]();
|
||||
|
||||
if (SIM) begin
|
||||
|
||||
@@ -382,268 +383,505 @@ xfcp_mod_apb_inst (
|
||||
.m_apb(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),
|
||||
.CNT(4),
|
||||
|
||||
// GT type
|
||||
.GT_TYPE("GTY"),
|
||||
// GT config
|
||||
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
||||
|
||||
// MAC/PHY config
|
||||
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
||||
.DATA_W(axis_qsfp_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(16+16),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(1),
|
||||
.STAT_PREFIX_STR('{"QSFP.1", "QSFP.2", "QSFP.3", "QSFP.4"})
|
||||
)
|
||||
qsfp_mac_inst (
|
||||
.xcvr_ctrl_clk(clk),
|
||||
.xcvr_ctrl_rst(qsfp_rst),
|
||||
// GT type
|
||||
.GT_TYPE("GTY"),
|
||||
|
||||
/*
|
||||
* 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(1),
|
||||
.STAT_TX_LEVEL(1),
|
||||
.STAT_RX_LEVEL(1),
|
||||
.STAT_ID_BASE(16+16),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(1),
|
||||
.STAT_PREFIX_STR("QSFP")
|
||||
)
|
||||
qsfp_mac_inst (
|
||||
.xcvr_ctrl_clk(clk),
|
||||
.xcvr_ctrl_rst(qsfp_rst),
|
||||
|
||||
/*
|
||||
* Common
|
||||
*/
|
||||
.xcvr_gtpowergood_out(qsfp_gtpowergood),
|
||||
.xcvr_gtrefclk00_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll0pd_in(1'b0),
|
||||
.xcvr_qpll0reset_in(1'b0),
|
||||
.xcvr_qpll0pcierate_in(3'd0),
|
||||
.xcvr_qpll0lock_out(),
|
||||
.xcvr_qpll0clk_out(),
|
||||
.xcvr_qpll0refclk_out(),
|
||||
.xcvr_gtrefclk01_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll1pd_in(1'b0),
|
||||
.xcvr_qpll1reset_in(1'b0),
|
||||
.xcvr_qpll1pcierate_in(3'd0),
|
||||
.xcvr_qpll1lock_out(),
|
||||
.xcvr_qpll1clk_out(),
|
||||
.xcvr_qpll1refclk_out(),
|
||||
/*
|
||||
* Transceiver control
|
||||
*/
|
||||
.s_apb_ctrl(gt_apb_ctrl),
|
||||
|
||||
/*
|
||||
* Serial data
|
||||
*/
|
||||
.xcvr_txp(qsfp_tx_p),
|
||||
.xcvr_txn(qsfp_tx_n),
|
||||
.xcvr_rxp(qsfp_rx_p),
|
||||
.xcvr_rxn(qsfp_rx_n),
|
||||
/*
|
||||
* Common
|
||||
*/
|
||||
.xcvr_gtpowergood_out(qsfp_gtpowergood),
|
||||
.xcvr_gtrefclk00_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll0pd_in(1'b0),
|
||||
.xcvr_qpll0lock_out(),
|
||||
.xcvr_qpll0clk_out(),
|
||||
.xcvr_qpll0refclk_out(),
|
||||
.xcvr_gtrefclk01_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll1pd_in(1'b0),
|
||||
.xcvr_qpll1lock_out(),
|
||||
.xcvr_qpll1clk_out(),
|
||||
.xcvr_qpll1refclk_out(),
|
||||
|
||||
/*
|
||||
* MAC clocks
|
||||
*/
|
||||
.rx_clk(qsfp_rx_clk),
|
||||
.rx_rst_in('{4{1'b0}}),
|
||||
.rx_rst_out(qsfp_rx_rst),
|
||||
.tx_clk(qsfp_tx_clk),
|
||||
.tx_rst_in('{4{1'b0}}),
|
||||
.tx_rst_out(qsfp_tx_rst),
|
||||
/*
|
||||
* Serial data
|
||||
*/
|
||||
.xcvr_txp(qsfp_tx_p),
|
||||
.xcvr_txn(qsfp_tx_n),
|
||||
.xcvr_rxp(qsfp_rx_p),
|
||||
.xcvr_rxn(qsfp_rx_n),
|
||||
|
||||
/*
|
||||
* Transmit interface (AXI stream)
|
||||
*/
|
||||
.s_axis_tx(axis_qsfp_tx),
|
||||
.m_axis_tx_cpl(axis_qsfp_tx_cpl),
|
||||
/*
|
||||
* MAC clocks
|
||||
*/
|
||||
.rx_clk(qsfp_rx_clk),
|
||||
.rx_rst_in('{4{1'b0}}),
|
||||
.rx_rst_out(qsfp_rx_rst),
|
||||
.tx_clk(qsfp_tx_clk),
|
||||
.tx_rst_in('{4{1'b0}}),
|
||||
.tx_rst_out(qsfp_tx_rst),
|
||||
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(axis_qsfp_rx),
|
||||
/*
|
||||
* Transmit interface (AXI stream)
|
||||
*/
|
||||
.s_axis_tx(axis_qsfp_tx[0]),
|
||||
.m_axis_tx_cpl(axis_qsfp_tx_cpl[0]),
|
||||
|
||||
/*
|
||||
* USXGMII autonegotiation
|
||||
*/
|
||||
.an_en('{4{1'b1}}),
|
||||
.an_restart('{4{1'b0}}),
|
||||
.an_speedup('{4{1'b0}}),
|
||||
.an_timeout_en('{4{1'b1}}),
|
||||
.an_usxgmii_en('{4{1'b0}}),
|
||||
.an_usxgmii_auto('{4{1'b1}}),
|
||||
.an_intr(),
|
||||
.an_running(),
|
||||
.an_complete(),
|
||||
.an_timeout(),
|
||||
.an_usxgmii_mode(),
|
||||
.an_adv_ability_usxgmii('{4{16'h1601}}),
|
||||
.an_lp_adv_ability(),
|
||||
.an_lp_usxgmii_link(),
|
||||
.an_lp_usxgmii_speed(),
|
||||
.an_res_full_duplex(),
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(axis_qsfp_rx[0]),
|
||||
|
||||
/*
|
||||
* PTP clock
|
||||
*/
|
||||
.ptp_clk(1'b0),
|
||||
.ptp_rst(1'b0),
|
||||
.ptp_sample_clk(1'b0),
|
||||
.ptp_td_sdi(1'b0),
|
||||
.tx_ptp_ts_in('{4{'0}}),
|
||||
.tx_ptp_ts_out(),
|
||||
.tx_ptp_ts_step_out(),
|
||||
.tx_ptp_locked(),
|
||||
.rx_ptp_ts_in('{4{'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('{4{1'b0}}),
|
||||
.tx_lfc_resend('{4{1'b0}}),
|
||||
.rx_lfc_en('{4{1'b0}}),
|
||||
.rx_lfc_req(),
|
||||
.rx_lfc_ack('{4{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('{4{'0}}),
|
||||
.tx_pfc_resend('{4{1'b0}}),
|
||||
.rx_pfc_en('{4{'0}}),
|
||||
.rx_pfc_req(),
|
||||
.rx_pfc_ack('{4{'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('{4{1'b0}}),
|
||||
.tx_pause_req('{4{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),
|
||||
.stat_rst(rst),
|
||||
.m_axis_stat(axis_eth_stat[1]),
|
||||
/*
|
||||
* Statistics
|
||||
*/
|
||||
.stat_clk(clk),
|
||||
.stat_rst(rst),
|
||||
.m_axis_stat(axis_eth_stat[1]),
|
||||
|
||||
/*
|
||||
* 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(qsfp_rx_status),
|
||||
.stat_rx_byte(),
|
||||
.stat_rx_pkt_len(),
|
||||
.stat_rx_pkt_fragment(),
|
||||
.stat_rx_pkt_jabber(),
|
||||
.stat_rx_pkt_ucast(),
|
||||
.stat_rx_pkt_mcast(),
|
||||
.stat_rx_pkt_bcast(),
|
||||
.stat_rx_pkt_vlan(),
|
||||
.stat_rx_pkt_good(),
|
||||
.stat_rx_pkt_bad(),
|
||||
.stat_rx_err_oversize(),
|
||||
.stat_rx_err_bad_fcs(),
|
||||
.stat_rx_err_bad_block(),
|
||||
.stat_rx_err_framing(),
|
||||
.stat_rx_err_preamble(),
|
||||
.stat_rx_fifo_drop('{4{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(qsfp_rx_status[0]),
|
||||
.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('{4{1'b1}}),
|
||||
.cfg_tx_min_pkt_len('{4{8'd60-1}}),
|
||||
.cfg_tx_max_pkt_len('{4{16'd9218-1}}),
|
||||
.cfg_tx_ifg('{4{8'd12}}),
|
||||
.cfg_tx_enable('{4{1'b1}}),
|
||||
.cfg_rx_max_pkt_len('{4{16'd9218-1}}),
|
||||
.cfg_rx_enable('{4{1'b1}}),
|
||||
.cfg_tx_prbs31_enable('{4{1'b0}}),
|
||||
.cfg_rx_prbs31_enable('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_dst_mcast('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_mcf_rx_check_eth_dst_mcast('{4{1'b1}}),
|
||||
.cfg_mcf_rx_eth_dst_ucast('{4{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_dst_ucast('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_src('{4{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_src('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_type('{4{16'h8808}}),
|
||||
.cfg_mcf_rx_opcode_lfc('{4{16'h0001}}),
|
||||
.cfg_mcf_rx_check_opcode_lfc('{4{1'b1}}),
|
||||
.cfg_mcf_rx_opcode_pfc('{4{16'h0101}}),
|
||||
.cfg_mcf_rx_check_opcode_pfc('{4{1'b1}}),
|
||||
.cfg_mcf_rx_forward('{4{1'b0}}),
|
||||
.cfg_mcf_rx_enable('{4{1'b0}}),
|
||||
.cfg_tx_lfc_eth_dst('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_lfc_eth_src('{4{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_lfc_eth_type('{4{16'h8808}}),
|
||||
.cfg_tx_lfc_opcode('{4{16'h0001}}),
|
||||
.cfg_tx_lfc_en('{4{1'b0}}),
|
||||
.cfg_tx_lfc_quanta('{4{16'hffff}}),
|
||||
.cfg_tx_lfc_refresh('{4{16'h7fff}}),
|
||||
.cfg_tx_pfc_eth_dst('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_pfc_eth_src('{4{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_pfc_eth_type('{4{16'h8808}}),
|
||||
.cfg_tx_pfc_opcode('{4{16'h0101}}),
|
||||
.cfg_tx_pfc_en('{4{1'b0}}),
|
||||
.cfg_tx_pfc_quanta('{4{'{8{16'hffff}}}}),
|
||||
.cfg_tx_pfc_refresh('{4{'{8{16'h7fff}}}}),
|
||||
.cfg_rx_lfc_opcode('{4{16'h0001}}),
|
||||
.cfg_rx_lfc_en('{4{1'b0}}),
|
||||
.cfg_rx_pfc_opcode('{4{16'h0101}}),
|
||||
.cfg_rx_pfc_en('{4{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)
|
||||
);
|
||||
|
||||
for (genvar n = 0; n < 4; n = n + 1) begin : qsfp_ch
|
||||
end else begin: mac
|
||||
|
||||
taxi_eth_mac_25g_us #(
|
||||
.SIM(SIM),
|
||||
.VENDOR(VENDOR),
|
||||
.FAMILY(FAMILY),
|
||||
|
||||
.CNT(4),
|
||||
|
||||
// GT config
|
||||
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
|
||||
|
||||
// GT type
|
||||
.GT_TYPE("GTY"),
|
||||
|
||||
// MAC/PHY config
|
||||
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
|
||||
.DATA_W(axis_qsfp_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(16+16),
|
||||
.STAT_UPDATE_PERIOD(1024),
|
||||
.STAT_STR_EN(1),
|
||||
.STAT_PREFIX_STR('{"QSFP.1", "QSFP.2", "QSFP.3", "QSFP.4"})
|
||||
)
|
||||
qsfp_mac_inst (
|
||||
.xcvr_ctrl_clk(clk),
|
||||
.xcvr_ctrl_rst(qsfp_rst),
|
||||
|
||||
/*
|
||||
* Transceiver control
|
||||
*/
|
||||
.s_apb_ctrl(gt_apb_ctrl),
|
||||
|
||||
/*
|
||||
* Common
|
||||
*/
|
||||
.xcvr_gtpowergood_out(qsfp_gtpowergood),
|
||||
.xcvr_gtrefclk00_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll0pd_in(1'b0),
|
||||
.xcvr_qpll0reset_in(1'b0),
|
||||
.xcvr_qpll0pcierate_in(3'd0),
|
||||
.xcvr_qpll0lock_out(),
|
||||
.xcvr_qpll0clk_out(),
|
||||
.xcvr_qpll0refclk_out(),
|
||||
.xcvr_gtrefclk01_in(qsfp_mgt_refclk_0),
|
||||
.xcvr_qpll1pd_in(1'b0),
|
||||
.xcvr_qpll1reset_in(1'b0),
|
||||
.xcvr_qpll1pcierate_in(3'd0),
|
||||
.xcvr_qpll1lock_out(),
|
||||
.xcvr_qpll1clk_out(),
|
||||
.xcvr_qpll1refclk_out(),
|
||||
|
||||
/*
|
||||
* Serial data
|
||||
*/
|
||||
.xcvr_txp(qsfp_tx_p),
|
||||
.xcvr_txn(qsfp_tx_n),
|
||||
.xcvr_rxp(qsfp_rx_p),
|
||||
.xcvr_rxn(qsfp_rx_n),
|
||||
|
||||
/*
|
||||
* MAC clocks
|
||||
*/
|
||||
.rx_clk(qsfp_rx_clk),
|
||||
.rx_rst_in('{4{1'b0}}),
|
||||
.rx_rst_out(qsfp_rx_rst),
|
||||
.tx_clk(qsfp_tx_clk),
|
||||
.tx_rst_in('{4{1'b0}}),
|
||||
.tx_rst_out(qsfp_tx_rst),
|
||||
|
||||
/*
|
||||
* Transmit interface (AXI stream)
|
||||
*/
|
||||
.s_axis_tx(axis_qsfp_tx),
|
||||
.m_axis_tx_cpl(axis_qsfp_tx_cpl),
|
||||
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(axis_qsfp_rx),
|
||||
|
||||
/*
|
||||
* USXGMII autonegotiation
|
||||
*/
|
||||
.an_en('{4{1'b1}}),
|
||||
.an_restart('{4{1'b0}}),
|
||||
.an_speedup('{4{1'b0}}),
|
||||
.an_timeout_en('{4{1'b1}}),
|
||||
.an_usxgmii_en('{4{1'b0}}),
|
||||
.an_usxgmii_auto('{4{1'b1}}),
|
||||
.an_intr(),
|
||||
.an_running(),
|
||||
.an_complete(),
|
||||
.an_timeout(),
|
||||
.an_usxgmii_mode(),
|
||||
.an_adv_ability_usxgmii('{4{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('{4{'0}}),
|
||||
.tx_ptp_ts_out(),
|
||||
.tx_ptp_ts_step_out(),
|
||||
.tx_ptp_locked(),
|
||||
.rx_ptp_ts_in('{4{'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('{4{1'b0}}),
|
||||
.tx_lfc_resend('{4{1'b0}}),
|
||||
.rx_lfc_en('{4{1'b0}}),
|
||||
.rx_lfc_req(),
|
||||
.rx_lfc_ack('{4{1'b0}}),
|
||||
|
||||
/*
|
||||
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
|
||||
*/
|
||||
.tx_pfc_req('{4{'0}}),
|
||||
.tx_pfc_resend('{4{1'b0}}),
|
||||
.rx_pfc_en('{4{'0}}),
|
||||
.rx_pfc_req(),
|
||||
.rx_pfc_ack('{4{'0}}),
|
||||
|
||||
/*
|
||||
* Pause interface
|
||||
*/
|
||||
.tx_lfc_pause_en('{4{1'b0}}),
|
||||
.tx_pause_req('{4{1'b0}}),
|
||||
.tx_pause_ack(),
|
||||
|
||||
/*
|
||||
* Statistics
|
||||
*/
|
||||
.stat_clk(clk),
|
||||
.stat_rst(rst),
|
||||
.m_axis_stat(axis_eth_stat[1]),
|
||||
|
||||
/*
|
||||
* 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(qsfp_rx_status),
|
||||
.stat_rx_byte(),
|
||||
.stat_rx_pkt_len(),
|
||||
.stat_rx_pkt_fragment(),
|
||||
.stat_rx_pkt_jabber(),
|
||||
.stat_rx_pkt_ucast(),
|
||||
.stat_rx_pkt_mcast(),
|
||||
.stat_rx_pkt_bcast(),
|
||||
.stat_rx_pkt_vlan(),
|
||||
.stat_rx_pkt_good(),
|
||||
.stat_rx_pkt_bad(),
|
||||
.stat_rx_err_oversize(),
|
||||
.stat_rx_err_bad_fcs(),
|
||||
.stat_rx_err_bad_block(),
|
||||
.stat_rx_err_framing(),
|
||||
.stat_rx_err_preamble(),
|
||||
.stat_rx_fifo_drop('{4{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('{4{1'b1}}),
|
||||
.cfg_tx_min_pkt_len('{4{8'd60-1}}),
|
||||
.cfg_tx_max_pkt_len('{4{16'd9218-1}}),
|
||||
.cfg_tx_ifg('{4{8'd12}}),
|
||||
.cfg_tx_enable('{4{1'b1}}),
|
||||
.cfg_rx_max_pkt_len('{4{16'd9218-1}}),
|
||||
.cfg_rx_enable('{4{1'b1}}),
|
||||
.cfg_tx_prbs31_enable('{4{1'b0}}),
|
||||
.cfg_rx_prbs31_enable('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_dst_mcast('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_mcf_rx_check_eth_dst_mcast('{4{1'b1}}),
|
||||
.cfg_mcf_rx_eth_dst_ucast('{4{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_dst_ucast('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_src('{4{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_src('{4{1'b0}}),
|
||||
.cfg_mcf_rx_eth_type('{4{16'h8808}}),
|
||||
.cfg_mcf_rx_opcode_lfc('{4{16'h0001}}),
|
||||
.cfg_mcf_rx_check_opcode_lfc('{4{1'b1}}),
|
||||
.cfg_mcf_rx_opcode_pfc('{4{16'h0101}}),
|
||||
.cfg_mcf_rx_check_opcode_pfc('{4{1'b1}}),
|
||||
.cfg_mcf_rx_forward('{4{1'b0}}),
|
||||
.cfg_mcf_rx_enable('{4{1'b0}}),
|
||||
.cfg_tx_lfc_eth_dst('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_lfc_eth_src('{4{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_lfc_eth_type('{4{16'h8808}}),
|
||||
.cfg_tx_lfc_opcode('{4{16'h0001}}),
|
||||
.cfg_tx_lfc_en('{4{1'b0}}),
|
||||
.cfg_tx_lfc_quanta('{4{16'hffff}}),
|
||||
.cfg_tx_lfc_refresh('{4{16'h7fff}}),
|
||||
.cfg_tx_pfc_eth_dst('{4{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_pfc_eth_src('{4{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_pfc_eth_type('{4{16'h8808}}),
|
||||
.cfg_tx_pfc_opcode('{4{16'h0101}}),
|
||||
.cfg_tx_pfc_en('{4{1'b0}}),
|
||||
.cfg_tx_pfc_quanta('{4{'{8{16'hffff}}}}),
|
||||
.cfg_tx_pfc_refresh('{4{'{8{16'h7fff}}}}),
|
||||
.cfg_rx_lfc_opcode('{4{16'h0001}}),
|
||||
.cfg_rx_lfc_en('{4{1'b0}}),
|
||||
.cfg_rx_pfc_opcode('{4{16'h0101}}),
|
||||
.cfg_rx_pfc_en('{4{1'b0}})
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
for (genvar n = 0; n < $size(axis_qsfp_tx); n = n + 1) begin : qsfp_ch
|
||||
|
||||
taxi_axis_async_fifo #(
|
||||
.DEPTH(16384),
|
||||
|
||||
3
src/eth/example/VCU108/fpga/syn/eth_cmac.xdc
Normal file
3
src/eth/example/VCU108/fpga/syn/eth_cmac.xdc
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
# CMACs
|
||||
set_property LOC CMAC_SITE_X0Y1 [get_cells -hierarchical -filter {NAME =~ mac.qsfp_mac_inst/cmac.cmac_inst/inst/i_taxi_eth_mac_100g_us_cmac_top/* && REF_NAME==CMAC}]
|
||||
@@ -25,6 +25,7 @@ TOPLEVEL = $(COCOTB_TOPLEVEL)
|
||||
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv
|
||||
VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f
|
||||
VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
|
||||
VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_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
|
||||
@@ -45,7 +46,7 @@ export PARAM_VENDOR := "\"XILINX\""
|
||||
export PARAM_FAMILY := "\"virtexu\""
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -20,8 +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, GmiiSource, GmiiSink
|
||||
from cocotbext.eth import XgmiiFrame
|
||||
from cocotbext.axi import AxiStreamBus
|
||||
from cocotbext.uart import UartSource, UartSink
|
||||
|
||||
try:
|
||||
@@ -57,10 +59,40 @@ class TB:
|
||||
self.qsfp_sources = []
|
||||
self.qsfp_sinks = []
|
||||
|
||||
for ch in dut.qsfp_mac_inst.ch:
|
||||
has_cmac = False
|
||||
|
||||
if dut.MAC_DATA_W.value == 512:
|
||||
inst = dut.mac.qsfp_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[0],
|
||||
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[0],
|
||||
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 dut.mac.qsfp_mac_inst.ch:
|
||||
gt_inst = ch.ch_inst.gt.gt_inst
|
||||
|
||||
if ch.ch_inst.DATA_W.value == 64:
|
||||
if has_cmac:
|
||||
clk = 3.102
|
||||
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])
|
||||
@@ -130,55 +162,10 @@ class TB:
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
|
||||
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("Multiple small packets")
|
||||
|
||||
count = 64
|
||||
|
||||
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
|
||||
|
||||
for p in pkts:
|
||||
await source.send(GmiiFrame.from_payload(p))
|
||||
|
||||
for k in range(count):
|
||||
rx_frame = await sink.recv()
|
||||
|
||||
tb.log.info("RX frame: %s", rx_frame)
|
||||
|
||||
assert rx_frame.get_payload() == pkts[k]
|
||||
assert rx_frame.check_fcs()
|
||||
assert rx_frame.error is None
|
||||
|
||||
tb.log.info("Multiple large packets")
|
||||
|
||||
count = 32
|
||||
|
||||
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
|
||||
|
||||
for p in pkts:
|
||||
await source.send(GmiiFrame.from_payload(p))
|
||||
|
||||
for k in range(count):
|
||||
rx_frame = await sink.recv()
|
||||
|
||||
tb.log.info("RX frame: %s", rx_frame)
|
||||
|
||||
assert rx_frame.get_payload() == pkts[k]
|
||||
assert rx_frame.check_fcs()
|
||||
assert rx_frame.error is None
|
||||
|
||||
tb.log.info("MAC test done")
|
||||
|
||||
|
||||
async def mac_test_25g(tb, source, sink):
|
||||
tb.log.info("Test MAC")
|
||||
|
||||
tb.log.info("Wait for block lock")
|
||||
for k in range(1200):
|
||||
await RisingEdge(tb.dut.clk)
|
||||
|
||||
sink.clear()
|
||||
|
||||
tb.log.info("Multiple small packets")
|
||||
@@ -188,7 +175,7 @@ async def mac_test_25g(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()
|
||||
@@ -205,7 +192,7 @@ async def mac_test_25g(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()
|
||||
@@ -227,14 +214,22 @@ async def run_test(dut):
|
||||
|
||||
tests = []
|
||||
|
||||
tb.log.info("Wait for block lock")
|
||||
for k in range(1200):
|
||||
await RisingEdge(tb.dut.clk)
|
||||
|
||||
tb.log.info("Start BASE-T MAC loopback test")
|
||||
|
||||
tests.append(cocotb.start_soon(mac_test(tb, tb.gmii_source, tb.gmii_sink)))
|
||||
tests.append(cocotb.start_soon(mac_test(tb, tb.gmii_source, tb.gmii_sink, GmiiFrame)))
|
||||
|
||||
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_25g(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)
|
||||
|
||||
@@ -273,6 +268,7 @@ def test_fpga_core(request, mac_data_w):
|
||||
os.path.join(rtl_dir, f"{dut}.sv"),
|
||||
os.path.join(taxi_src_dir, "eth", "rtl", "taxi_eth_mac_1g_fifo.f"),
|
||||
os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_25g_us.f"),
|
||||
os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_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"),
|
||||
|
||||
Reference in New Issue
Block a user