1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

Add 25G mqnic design for Cisco Nexus K3P-Q

This commit is contained in:
Alex Forencich 2022-05-09 14:02:13 -07:00
parent ba9ef590b7
commit 9653caf09b
24 changed files with 6028 additions and 0 deletions

View File

@ -26,6 +26,7 @@ Corundum currently supports devices from both Xilinx and Intel, on boards from s
* Dini Group DNPCIe_40G_KU_LL_2QSFP (Xilinx Kintex UltraScale XCKU040)
* Cisco Nexus K35-S (Xilinx Kintex UltraScale XCKU035)
* Cisco Nexus K3P-S (Xilinx Kintex UltraScale+ XCKU3P)
* Cisco Nexus K3P-Q (Xilinx Kintex UltraScale+ XCKU3P)
* Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P)
* NetFPGA SUME (Xilinx Virtex 7 XC7V690T)
* BittWare XUP-P3R (Xilinx Virtex UltraScale+ XCVU9P)

View File

@ -20,6 +20,7 @@ This section details PCIe form-factor targets, which interface with a separate h
Dini Group DNPCIe_40G_KU_LL_2QSFP XCKU040-2FFVA1156E 0x17df1a00
Cisco Nexus K35-S XCKU035-2FBVA676E 0x1ce40003
Cisco Nexus K3P-S XCKU3P-2FFVB676E 0x1ce40009
Cisco Nexus K3P-Q XCKU3P-2FFVB676E 0x1ce4000a
Silicom fb2CG\@KU15P XCKU15P-2FFVE1760E 0x1c2ca00e
Digilent NetFPGA SUME XC7V690T-3FFG1761 0x10ee7028
BittWare XUP-P3R XCVU9P-2FLGB2104E 0x12ba9823
@ -44,6 +45,7 @@ This section details PCIe form-factor targets, which interface with a separate h
DNPCIe_40G_KU_LL_2QSFP Gen 3 x8 2x QSFP+ 4 GB DDR4 2400 (512M x72) \-
Nexus K35-S Gen 3 x8 2x SFP+ \- \-
Nexus K3P-S Gen 3 x8 2x SFP28 4 GB DDR4 (1G x32) \-
Nexus K3P-Q Gen 3 x8 2x QSFP28 8 GB DDR4 (1G x72) \-
fb2CG\@KU15P Gen 3 x16 2x QSFP28 16 GB DDR4 2400 (4x 512M x72) \-
NetFPGA SUME Gen 3 x8 4x SFP+ 8 GB DDR3 1866 (2x 512M x64) \-
XUP-P3R Gen 3 x16 4x QSFP28 4x DDR4 2400 DIMM (4x x72) \-
@ -68,6 +70,7 @@ This section details PCIe form-factor targets, which interface with a separate h
DNPCIe_40G_KU_LL_2QSFP Y N :sup:`3` Y
Nexus K35-S N :sup:`3` Y Y
Nexus K3P-S N :sup:`3` Y Y
Nexus K3P-Q Y Y Y
fb2CG\@KU15P Y Y Y
NetFPGA SUME Y N :sup:`7` N :sup:`8`
XUP-P3R Y Y Y
@ -107,6 +110,8 @@ This section details PCIe form-factor targets, which interface with a separate h
Nexus K35-S mqnic/fpga/fpga 2x1 256/2K 10G RR
Nexus K3P-S mqnic/fpga_25g/fpga 2x1 256/8K 25G RR
Nexus K3P-S mqnic/fpga_25g/fpga_10g 2x1 256/8K 10G RR
Nexus K3P-Q mqnic/fpga_25g/fpga 2x1 256/8K 25G RR
Nexus K3P-Q mqnic/fpga_25g/fpga_10g 2x1 256/8K 10G RR
fb2CG\@KU15P mqnic/fpga_25g/fpga 2x1 256/8K 25G RR
fb2CG\@KU15P mqnic/fpga_25g/fpga_10g 2x1 256/8K 10G RR
fb2CG\@KU15P mqnic/fpga_25g/fpga_tdma 2x1 256/256 25G TDMA

View File

@ -18,6 +18,7 @@ Corundum currently supports devices from both Xilinx and Intel, on boards from s
* Dini Group DNPCIe_40G_KU_LL_2QSFP (Xilinx Kintex UltraScale XCKU040)
* Cisco Nexus K35-S (Xilinx Kintex UltraScale XCKU035)
* Cisco Nexus K3P-S (Xilinx Kintex UltraScale+ XCKU3P)
* Cisco Nexus K3P-Q (Xilinx Kintex UltraScale+ XCKU3P)
* Silicom fb2CG\@KU15P (Xilinx Kintex UltraScale+ XCKU15P)
* NetFPGA SUME (Xilinx Virtex 7 XC7V690T)
* BittWare XUP-P3R (Xilinx Virtex UltraScale+ XCVU9P)

View File

@ -0,0 +1,18 @@
# Corundum mqnic for Cisco Nexus K3P-Q
## Introduction
This design targets the Cisco Nexus K3P-Q FPGA board.
* FPGA: xcku3p-ffvb676-2-e
* PHY: 25G BASE-R PHY IP core and internal GTY transceiver
## How to build
Run make to build. Ensure that the Xilinx Vivado toolchain components are in PATH.
Run make to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled.
## How to test
Run make program to program the Nexus K3P-Q board with Vivado. Then load the driver with insmod mqnic.ko. Check dmesg for output from driver initialization.

View File

@ -0,0 +1 @@
../../../app/

View File

@ -0,0 +1,4 @@
# Timing constraints for FPGA boot logic
set_property ASYNC_REG TRUE [get_cells "fpga_boot_sync_reg_0_reg fpga_boot_sync_reg_1_reg"]
set_false_path -to [get_pins "fpga_boot_sync_reg_0_reg/D"]

View File

@ -0,0 +1,126 @@
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - space-separated list of source files
# INC_FILES - space-separated list of include files
# XDC_FILES - space-separated list of timing constraint files
# XCI_FILES - space-separated list of IP XCI files
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: fpga vivado tmpclean clean distclean
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include ../$(CONFIG)
SYN_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(SYN_FILES))) $(filter /% ./%,$(SYN_FILES))
INC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(INC_FILES))) $(filter /% ./%,$(INC_FILES))
XCI_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XCI_FILES))) $(filter /% ./%,$(XCI_FILES))
IP_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(IP_TCL_FILES))) $(filter /% ./%,$(IP_TCL_FILES))
CONFIG_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(CONFIG_TCL_FILES))) $(filter /% ./%,$(CONFIG_TCL_FILES))
ifdef XDC_FILES
XDC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XDC_FILES))) $(filter /% ./%,$(XDC_FILES))
else
XDC_FILES_REL = $(FPGA_TOP).xdc
endif
###################################################################
# Main Targets
#
# all: build everything
# clean: remove output files and project files
###################################################################
all: fpga
fpga: $(FPGA_TOP).bit
vivado: $(FPGA_TOP).xpr
vivado $(FPGA_TOP).xpr
tmpclean::
-rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
-rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
clean:: tmpclean
-rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
distclean:: clean
-rm -rf rev
###################################################################
# Target implementations
###################################################################
# Vivado project file
create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL)
rm -rf defines.v
touch defines.v
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
echo "create_project -force -part $(FPGA_PART) $(FPGA_TOP)" > $@
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@
for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done
for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
update_config.tcl: $(CONFIG_TCL_FILES_REL) $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
echo "open_project -quiet $(FPGA_TOP).xpr" > $@
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
$(FPGA_TOP).xpr: create_project.tcl update_config.tcl
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
# synthesis run
%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
echo "open_project $*.xpr" > run_synth.tcl
echo "reset_run synth_1" >> run_synth.tcl
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
echo "wait_on_run synth_1" >> run_synth.tcl
vivado -nojournal -nolog -mode batch -source run_synth.tcl
# implementation run
%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp
echo "open_project $*.xpr" > run_impl.tcl
echo "reset_run impl_1" >> run_impl.tcl
echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl
echo "wait_on_run impl_1" >> run_impl.tcl
vivado -nojournal -nolog -mode batch -source run_impl.tcl
# bit file
%.bit: %.runs/impl_1/%_routed.dcp
echo "open_project $*.xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force $*.bit" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
mkdir -p rev
EXT=bit; COUNT=100; \
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
do COUNT=$$((COUNT+1)); done; \
cp $@ rev/$*_rev$$COUNT.$$EXT; \
echo "Output: rev/$*_rev$$COUNT.$$EXT";

View File

@ -0,0 +1,189 @@
# XDC constraints for the Cisco Nexus K3P-Q
# part: xcku3p-ffvb676-2-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 72.9 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 10 MHz TXCO
#set_property -dict {LOC E13 IOSTANDARD LVCMOS33} [get_ports clk_10mhz]
#create_clock -period 100 -name clk_100mhz [get_ports clk_10mhz]
# LEDs
set_property -dict {LOC AB15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {qsfp_0_led_green}]
set_property -dict {LOC AC14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {qsfp_0_led_orange}]
set_property -dict {LOC AA15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {qsfp_1_led_green}]
set_property -dict {LOC AB14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {qsfp_1_led_orange}]
set_property -dict {LOC C12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led_green}]
set_property -dict {LOC C13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led_red}]
set_false_path -to [get_ports {qsfp_0_led_green qsfp_0_led_orange qsfp_1_led_green qsfp_1_led_orange sma_led_green sma_led_orange}]
set_output_delay 0 [get_ports {qsfp_0_led_green qsfp_0_led_orange qsfp_1_led_green qsfp_1_led_orange sma_led_green sma_led_orange}]
# GPIO
#set_property -dict {LOC IOSTANDARD LVCMOS18} [get_ports gpio[0]]
#set_property -dict {LOC IOSTANDARD LVCMOS18} [get_ports gpio[1]]
#set_property -dict {LOC IOSTANDARD LVCMOS18} [get_ports gpio[2]]
#set_property -dict {LOC IOSTANDARD LVCMOS18} [get_ports gpio[3]]
#set_property -dict {LOC IOSTANDARD LVCMOS18} [get_ports gpio[4]]
# SMA
set_property -dict {LOC AD15 IOSTANDARD LVCMOS33} [get_ports sma_in]
set_property -dict {LOC AF14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports sma_out]
set_property -dict {LOC AD14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sma_out_en]
set_property -dict {LOC AB16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sma_term_en]
set_false_path -to [get_ports {sma_out sma_out_en sma_term_en}]
set_output_delay 0 [get_ports {sma_out sma_out_en sma_term_en}]
set_false_path -from [get_ports {sma_in}]
set_input_delay 0 [get_ports {sma_in}]
# Config
#set_property -dict {LOC C14 IOSTANDARD LVCMOS33} [get_ports ddr_npres]
# QSFP28 Interfaces
set_property -dict {LOC M2 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_226 GTYE4_CHANNEL_X0Y8 / GTYE4_COMMON_X0Y2
set_property -dict {LOC M1 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_226 GTYE4_CHANNEL_X0Y8 / GTYE4_COMMON_X0Y2
set_property -dict {LOC N5 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_226 GTYE4_CHANNEL_X0Y8 / GTYE4_COMMON_X0Y2
set_property -dict {LOC N4 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_226 GTYE4_CHANNEL_X0Y8 / GTYE4_COMMON_X0Y2
set_property -dict {LOC K2 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_226 GTYE4_CHANNEL_X0Y9 / GTYE4_COMMON_X0Y2
set_property -dict {LOC K1 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_226 GTYE4_CHANNEL_X0Y9 / GTYE4_COMMON_X0Y2
set_property -dict {LOC L5 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_226 GTYE4_CHANNEL_X0Y9 / GTYE4_COMMON_X0Y2
set_property -dict {LOC L4 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_226 GTYE4_CHANNEL_X0Y9 / GTYE4_COMMON_X0Y2
set_property -dict {LOC F2 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP3_226 GTYE4_CHANNEL_X0Y11 / GTYE4_COMMON_X0Y2
set_property -dict {LOC F1 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN3_226 GTYE4_CHANNEL_X0Y11 / GTYE4_COMMON_X0Y2
set_property -dict {LOC G5 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP3_226 GTYE4_CHANNEL_X0Y11 / GTYE4_COMMON_X0Y2
set_property -dict {LOC G4 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN3_226 GTYE4_CHANNEL_X0Y11 / GTYE4_COMMON_X0Y2
set_property -dict {LOC H2 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP2_226 GTYE4_CHANNEL_X0Y10 / GTYE4_COMMON_X0Y2
set_property -dict {LOC H1 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN2_226 GTYE4_CHANNEL_X0Y10 / GTYE4_COMMON_X0Y2
set_property -dict {LOC J5 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP2_226 GTYE4_CHANNEL_X0Y10 / GTYE4_COMMON_X0Y2
set_property -dict {LOC J4 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN2_226 GTYE4_CHANNEL_X0Y10 / GTYE4_COMMON_X0Y2
set_property -dict {LOC W16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_0_modsell]
set_property -dict {LOC Y15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_0_resetl]
set_property -dict {LOC W14 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_modprsl]
set_property -dict {LOC W15 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_intl]
set_property -dict {LOC Y13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_0_lpmode]
set_property -dict {LOC AC13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_0_i2c_sda]
set_property -dict {LOC Y16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_0_i2c_scl]
set_false_path -to [get_ports {qsfp_0_modsell qsfp_0_resetl qsfp_0_lpmode}]
set_output_delay 0 [get_ports {qsfp_0_modsell qsfp_0_resetl qsfp_0_lpmode}]
set_false_path -from [get_ports {qsfp_0_modprsl qsfp_0_intl}]
set_input_delay 0 [get_ports {qsfp_0_modprsl qsfp_0_intl}]
set_false_path -to [get_ports {qsfp_0_i2c_sda qsfp_0_i2c_scl}]
set_output_delay 0 [get_ports {qsfp_0_i2c_sda qsfp_0_i2c_scl}]
set_false_path -from [get_ports {qsfp_0_i2c_sda qsfp_0_i2c_scl}]
set_input_delay 0 [get_ports {qsfp_0_i2c_sda qsfp_0_i2c_scl}]
set_property -dict {LOC D2 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC D1 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC F7 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC F6 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC C4 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_227 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC C3 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_227 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC E5 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_227 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC E4 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_227 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC A4 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC A3 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC B7 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC B6 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC B2 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP2_227 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC B1 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN2_227 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC D7 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP2_227 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC D6 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN2_227 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC AA14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_1_modsell]
set_property -dict {LOC AE13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_1_resetl]
set_property -dict {LOC A13 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_modprsl]
set_property -dict {LOC A14 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_intl]
set_property -dict {LOC B14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_1_lpmode]
set_property -dict {LOC AD13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_1_i2c_sda]
set_property -dict {LOC AF13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_1_i2c_scl]
# 161.1328125 MHz MGT reference clock
set_property -dict {LOC K7 } [get_ports qsfp_mgt_refclk_p] ;# MGTREFCLK0P_227 from X2
set_property -dict {LOC K6 } [get_ports qsfp_mgt_refclk_n] ;# MGTREFCLK0N_227 from X2
create_clock -period 6.206 -name qsfp_mgt_refclk [get_ports qsfp_mgt_refclk_p]
set_false_path -to [get_ports {qsfp_1_modsell qsfp_1_resetl qsfp_1_lpmode}]
set_output_delay 0 [get_ports {qsfp_1_modsell qsfp_1_resetl qsfp_1_lpmode}]
set_false_path -from [get_ports {qsfp_1_modprsl qsfp_1_intl}]
set_input_delay 0 [get_ports {qsfp_1_modprsl qsfp_1_intl}]
set_false_path -to [get_ports {qsfp_1_i2c_sda qsfp_1_i2c_scl}]
set_output_delay 0 [get_ports {qsfp_1_i2c_sda qsfp_1_i2c_scl}]
set_false_path -from [get_ports {qsfp_1_i2c_sda qsfp_1_i2c_scl}]
set_input_delay 0 [get_ports {qsfp_1_i2c_sda qsfp_1_i2c_scl}]
# I2C interface
set_property -dict {LOC W12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
set_property -dict {LOC W13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC V7 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_225
set_property -dict {LOC V6 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_225
set_property -dict {LOC T19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p]
# QSPI flash
set_property -dict {LOC H11 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_clk}]
set_property -dict {LOC H9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_dq[0]}]
set_property -dict {LOC J9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_dq[1]}]
set_property -dict {LOC J10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_dq[2]}]
set_property -dict {LOC J11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_dq[3]}]
set_property -dict {LOC K9 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_0_cs}]
set_property -dict {LOC K10 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
set_false_path -to [get_ports {qspi_clk qspi_dq[*] qspi_0_cs qspi_1_cs}]
set_output_delay 0 [get_ports {qspi_clk qspi_dq[*] qspi_0_cs qspi_1_cs}]
set_false_path -from [get_ports {qspi_dq[*]}]
set_input_delay 0 [get_ports {qspi_dq[*]}]

View File

@ -0,0 +1,191 @@
# FPGA settings
FPGA_PART = xcku3p-ffvb676-2-e
FPGA_TOP = fpga
FPGA_ARCH = kintexuplus
# Files for synthesis
SYN_FILES = rtl/fpga.v
SYN_FILES += rtl/fpga_core.v
SYN_FILES += rtl/sync_signal.v
SYN_FILES += rtl/common/mqnic_core_pcie_us.v
SYN_FILES += rtl/common/mqnic_core_pcie.v
SYN_FILES += rtl/common/mqnic_core.v
SYN_FILES += rtl/common/mqnic_interface.v
SYN_FILES += rtl/common/mqnic_interface_tx.v
SYN_FILES += rtl/common/mqnic_interface_rx.v
SYN_FILES += rtl/common/mqnic_port.v
SYN_FILES += rtl/common/mqnic_port_tx.v
SYN_FILES += rtl/common/mqnic_port_rx.v
SYN_FILES += rtl/common/mqnic_egress.v
SYN_FILES += rtl/common/mqnic_ingress.v
SYN_FILES += rtl/common/mqnic_l2_egress.v
SYN_FILES += rtl/common/mqnic_l2_ingress.v
SYN_FILES += rtl/common/mqnic_rx_queue_map.v
SYN_FILES += rtl/common/mqnic_ptp.v
SYN_FILES += rtl/common/mqnic_ptp_clock.v
SYN_FILES += rtl/common/mqnic_ptp_perout.v
SYN_FILES += rtl/common/mqnic_port_map_phy_xgmii.v
SYN_FILES += rtl/common/cpl_write.v
SYN_FILES += rtl/common/cpl_op_mux.v
SYN_FILES += rtl/common/desc_fetch.v
SYN_FILES += rtl/common/desc_op_mux.v
SYN_FILES += rtl/common/event_mux.v
SYN_FILES += rtl/common/queue_manager.v
SYN_FILES += rtl/common/cpl_queue_manager.v
SYN_FILES += rtl/common/tx_fifo.v
SYN_FILES += rtl/common/rx_fifo.v
SYN_FILES += rtl/common/tx_req_mux.v
SYN_FILES += rtl/common/tx_engine.v
SYN_FILES += rtl/common/rx_engine.v
SYN_FILES += rtl/common/tx_checksum.v
SYN_FILES += rtl/common/rx_hash.v
SYN_FILES += rtl/common/rx_checksum.v
SYN_FILES += rtl/common/rb_drp.v
SYN_FILES += rtl/common/eth_xcvr_phy_10g_gty_wrapper.v
SYN_FILES += rtl/common/eth_xcvr_phy_10g_gty_quad_wrapper.v
SYN_FILES += rtl/common/stats_counter.v
SYN_FILES += rtl/common/stats_collect.v
SYN_FILES += rtl/common/stats_pcie_if.v
SYN_FILES += rtl/common/stats_pcie_tlp.v
SYN_FILES += rtl/common/stats_dma_if_pcie.v
SYN_FILES += rtl/common/stats_dma_latency.v
SYN_FILES += rtl/common/mqnic_tx_scheduler_block_rr.v
SYN_FILES += rtl/common/tx_scheduler_rr.v
SYN_FILES += rtl/common/tdma_scheduler.v
SYN_FILES += rtl/common/tdma_ber.v
SYN_FILES += rtl/common/tdma_ber_ch.v
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
SYN_FILES += lib/eth/rtl/lfsr.v
SYN_FILES += lib/eth/rtl/ptp_clock.v
SYN_FILES += lib/eth/rtl/ptp_clock_cdc.v
SYN_FILES += lib/eth/rtl/ptp_perout.v
SYN_FILES += lib/axi/rtl/axil_interconnect.v
SYN_FILES += lib/axi/rtl/axil_crossbar.v
SYN_FILES += lib/axi/rtl/axil_crossbar_addr.v
SYN_FILES += lib/axi/rtl/axil_crossbar_rd.v
SYN_FILES += lib/axi/rtl/axil_crossbar_wr.v
SYN_FILES += lib/axi/rtl/axil_reg_if.v
SYN_FILES += lib/axi/rtl/axil_reg_if_rd.v
SYN_FILES += lib/axi/rtl/axil_reg_if_wr.v
SYN_FILES += lib/axi/rtl/axil_register_rd.v
SYN_FILES += lib/axi/rtl/axil_register_wr.v
SYN_FILES += lib/axi/rtl/arbiter.v
SYN_FILES += lib/axi/rtl/priority_encoder.v
SYN_FILES += lib/axis/rtl/axis_adapter.v
SYN_FILES += lib/axis/rtl/axis_arb_mux.v
SYN_FILES += lib/axis/rtl/axis_async_fifo.v
SYN_FILES += lib/axis/rtl/axis_async_fifo_adapter.v
SYN_FILES += lib/axis/rtl/axis_demux.v
SYN_FILES += lib/axis/rtl/axis_fifo.v
SYN_FILES += lib/axis/rtl/axis_fifo_adapter.v
SYN_FILES += lib/axis/rtl/axis_pipeline_fifo.v
SYN_FILES += lib/axis/rtl/axis_register.v
SYN_FILES += lib/axis/rtl/sync_reset.v
SYN_FILES += lib/pcie/rtl/pcie_axil_master.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v
SYN_FILES += lib/pcie/rtl/dma_if_mux.v
SYN_FILES += lib/pcie/rtl/dma_if_mux_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_mux_wr.v
SYN_FILES += lib/pcie/rtl/dma_if_desc_mux.v
SYN_FILES += lib/pcie/rtl/dma_ram_demux_rd.v
SYN_FILES += lib/pcie/rtl/dma_ram_demux_wr.v
SYN_FILES += lib/pcie/rtl/dma_psdpram.v
SYN_FILES += lib/pcie/rtl/dma_client_axis_sink.v
SYN_FILES += lib/pcie/rtl/dma_client_axis_source.v
SYN_FILES += lib/pcie/rtl/pcie_us_if.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v
SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v
SYN_FILES += lib/pcie/rtl/pcie_us_msi.v
SYN_FILES += lib/pcie/rtl/pulse_merge.v
# XDC files
XDC_FILES = fpga.xdc
XDC_FILES += boot.xdc
XDC_FILES += lib/axis/syn/vivado/axis_async_fifo.tcl
XDC_FILES += lib/axis/syn/vivado/sync_reset.tcl
XDC_FILES += lib/eth/syn/vivado/ptp_clock_cdc.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_port.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_ptp_clock.tcl
XDC_FILES += ../../../common/syn/vivado/rb_drp.tcl
XDC_FILES += ../../../common/syn/vivado/eth_xcvr_phy_10g_gty_wrapper.tcl
XDC_FILES += ../../../common/syn/vivado/tdma_ber_ch.tcl
# IP
IP_TCL_FILES = ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += ip/eth_xcvr_gty.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
echo "open_hw" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl
echo "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 32 -interface BPIx16 -loadbit {up 0x00800000 $*.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: $(FPGA_TOP).mcs $(FPGA_TOP).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {s29gl256p-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 \"$(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.BPI_RS_PINS {24:23} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@ -0,0 +1,280 @@
# Copyright 2021, The Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of The Regents of the University of California.
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4A63093]
set fw_id [expr 0x00000000]
set fw_ver $tag_ver
set board_vendor_id [expr 0x1ce4]
set board_device_id [expr 0x000a]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
# FW ID block
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Transceiver configuration
set eth_xcvr_freerun_freq {125}
set eth_xcvr_line_rate {25.78125}
set eth_xcvr_sec_line_rate {10.3125}
set eth_xcvr_refclk_freq {161.1328125}
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_rx_eq_mode {DFE}
# Structural configuration
dict set params IF_COUNT "2"
dict set params PORTS_PER_IF "1"
dict set params SCHED_PER_IF [dict get $params PORTS_PER_IF]
dict set params PORT_MASK "0"
# PTP configuration
dict set params PTP_CLOCK_PIPELINE "0"
dict set params PTP_CLOCK_CDC_PIPELINE "0"
dict set params PTP_PORT_CDC_PIPELINE "0"
dict set params PTP_PEROUT_ENABLE "1"
dict set params PTP_PEROUT_COUNT "1"
# Queue manager configuration
dict set params EVENT_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_QUEUE_OP_TABLE_SIZE "32"
dict set params RX_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params TX_QUEUE_OP_TABLE_SIZE]
dict set params RX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params RX_QUEUE_OP_TABLE_SIZE]
dict set params EVENT_QUEUE_INDEX_WIDTH "5"
dict set params TX_QUEUE_INDEX_WIDTH "13"
dict set params RX_QUEUE_INDEX_WIDTH "8"
dict set params TX_CPL_QUEUE_INDEX_WIDTH [dict get $params TX_QUEUE_INDEX_WIDTH]
dict set params RX_CPL_QUEUE_INDEX_WIDTH [dict get $params RX_QUEUE_INDEX_WIDTH]
dict set params EVENT_QUEUE_PIPELINE "3"
dict set params TX_QUEUE_PIPELINE [expr 3+([dict get $params TX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params TX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params RX_QUEUE_PIPELINE [expr 3+([dict get $params RX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params RX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params TX_CPL_QUEUE_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params RX_CPL_QUEUE_PIPELINE [dict get $params RX_QUEUE_PIPELINE]
# TX and RX engine configuration
dict set params TX_DESC_TABLE_SIZE "32"
dict set params RX_DESC_TABLE_SIZE "32"
# Scheduler configuration
dict set params TX_SCHEDULER_OP_TABLE_SIZE [dict get $params TX_DESC_TABLE_SIZE]
dict set params TX_SCHEDULER_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params TDMA_INDEX_WIDTH "6"
# Interface configuration
dict set params PTP_TS_ENABLE "1"
dict set params TX_CPL_FIFO_DEPTH "32"
dict set params TX_CHECKSUM_ENABLE "1"
dict set params RX_RSS_ENABLE "1"
dict set params RX_HASH_ENABLE "1"
dict set params RX_CHECKSUM_ENABLE "1"
dict set params TX_FIFO_DEPTH "32768"
dict set params RX_FIFO_DEPTH "32768"
dict set params MAX_TX_SIZE "9214"
dict set params MAX_RX_SIZE "9214"
dict set params TX_RAM_SIZE "32768"
dict set params RX_RAM_SIZE "32768"
# Application block configuration
dict set params APP_ID "32'h00000000"
dict set params APP_ENABLE "0"
dict set params APP_CTRL_ENABLE "1"
dict set params APP_DMA_ENABLE "1"
dict set params APP_AXIS_DIRECT_ENABLE "1"
dict set params APP_AXIS_SYNC_ENABLE "1"
dict set params APP_AXIS_IF_ENABLE "1"
dict set params APP_STAT_ENABLE "1"
# DMA interface configuration
dict set params DMA_IMM_ENABLE "0"
dict set params DMA_IMM_WIDTH "32"
dict set params DMA_LEN_WIDTH "16"
dict set params DMA_TAG_WIDTH "16"
dict set params RAM_ADDR_WIDTH [expr int(ceil(log(max([dict get $params TX_RAM_SIZE], [dict get $params RX_RAM_SIZE]))/log(2)))]
dict set params RAM_PIPELINE "2"
# PCIe interface configuration
dict set params PCIE_TAG_COUNT "64"
dict set params PCIE_DMA_READ_OP_TABLE_SIZE [dict get $params PCIE_TAG_COUNT]
dict set params PCIE_DMA_READ_TX_LIMIT "16"
dict set params PCIE_DMA_READ_TX_FC_ENABLE "1"
dict set params PCIE_DMA_WRITE_OP_TABLE_SIZE "16"
dict set params PCIE_DMA_WRITE_TX_LIMIT "3"
dict set params PCIE_DMA_WRITE_TX_FC_ENABLE "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_WIDTH "32"
dict set params AXIL_CTRL_ADDR_WIDTH "24"
# AXI lite interface configuration (application control)
dict set params AXIL_APP_CTRL_DATA_WIDTH [dict get $params AXIL_CTRL_DATA_WIDTH]
dict set params AXIL_APP_CTRL_ADDR_WIDTH "24"
# Ethernet interface configuration
dict set params AXIS_ETH_SYNC_DATA_WIDTH_DOUBLE [expr max($eth_xcvr_line_rate, $eth_xcvr_sec_line_rate) > 16]
dict set params AXIS_ETH_TX_PIPELINE "0"
dict set params AXIS_ETH_TX_FIFO_PIPELINE "2"
dict set params AXIS_ETH_TX_TS_PIPELINE "0"
dict set params AXIS_ETH_RX_PIPELINE "0"
dict set params AXIS_ETH_RX_FIFO_PIPELINE "2"
# Statistics counter subsystem
dict set params STAT_ENABLE "1"
dict set params STAT_DMA_ENABLE "1"
dict set params STAT_PCIE_ENABLE "1"
dict set params STAT_INC_WIDTH "24"
dict set params STAT_ID_WIDTH "12"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs
set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]
dict set params AXIS_PCIE_KEEP_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH]/32]
dict set params AXIS_PCIE_RC_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 75 : 161]
dict set params AXIS_PCIE_RQ_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 62 : 137]
dict set params AXIS_PCIE_CQ_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 85 : 183]
dict set params AXIS_PCIE_CC_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 33 : 81]
dict set params RQ_SEQ_NUM_WIDTH [expr [dict get $params AXIS_PCIE_RQ_USER_WIDTH] == 60 ? 4 : 6]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_WIDTH]
# Application BAR (BAR 2)
configure_bar $pcie 0 2 [expr [dict get $params APP_ENABLE] ? [dict get $params AXIL_APP_CTRL_ADDR_WIDTH] : 0]
# Transceiver configuration
set xcvr_config [dict create]
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
if {$eth_xcvr_sec_line_rate != 0} {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
} else {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
}
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
set_property -dict $xcvr_config [get_ips eth_xcvr_gty_full]
set_property -dict $xcvr_config [get_ips eth_xcvr_gty_channel]
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
# set_property generic $param_list [current_fileset]
set_property generic $param_list [get_filesets sources_1]

View File

@ -0,0 +1,191 @@
# FPGA settings
FPGA_PART = xcku3p-ffvb676-2-e
FPGA_TOP = fpga
FPGA_ARCH = kintexuplus
# Files for synthesis
SYN_FILES = rtl/fpga.v
SYN_FILES += rtl/fpga_core.v
SYN_FILES += rtl/sync_signal.v
SYN_FILES += rtl/common/mqnic_core_pcie_us.v
SYN_FILES += rtl/common/mqnic_core_pcie.v
SYN_FILES += rtl/common/mqnic_core.v
SYN_FILES += rtl/common/mqnic_interface.v
SYN_FILES += rtl/common/mqnic_interface_tx.v
SYN_FILES += rtl/common/mqnic_interface_rx.v
SYN_FILES += rtl/common/mqnic_port.v
SYN_FILES += rtl/common/mqnic_port_tx.v
SYN_FILES += rtl/common/mqnic_port_rx.v
SYN_FILES += rtl/common/mqnic_egress.v
SYN_FILES += rtl/common/mqnic_ingress.v
SYN_FILES += rtl/common/mqnic_l2_egress.v
SYN_FILES += rtl/common/mqnic_l2_ingress.v
SYN_FILES += rtl/common/mqnic_rx_queue_map.v
SYN_FILES += rtl/common/mqnic_ptp.v
SYN_FILES += rtl/common/mqnic_ptp_clock.v
SYN_FILES += rtl/common/mqnic_ptp_perout.v
SYN_FILES += rtl/common/mqnic_port_map_phy_xgmii.v
SYN_FILES += rtl/common/cpl_write.v
SYN_FILES += rtl/common/cpl_op_mux.v
SYN_FILES += rtl/common/desc_fetch.v
SYN_FILES += rtl/common/desc_op_mux.v
SYN_FILES += rtl/common/event_mux.v
SYN_FILES += rtl/common/queue_manager.v
SYN_FILES += rtl/common/cpl_queue_manager.v
SYN_FILES += rtl/common/tx_fifo.v
SYN_FILES += rtl/common/rx_fifo.v
SYN_FILES += rtl/common/tx_req_mux.v
SYN_FILES += rtl/common/tx_engine.v
SYN_FILES += rtl/common/rx_engine.v
SYN_FILES += rtl/common/tx_checksum.v
SYN_FILES += rtl/common/rx_hash.v
SYN_FILES += rtl/common/rx_checksum.v
SYN_FILES += rtl/common/rb_drp.v
SYN_FILES += rtl/common/eth_xcvr_phy_10g_gty_wrapper.v
SYN_FILES += rtl/common/eth_xcvr_phy_10g_gty_quad_wrapper.v
SYN_FILES += rtl/common/stats_counter.v
SYN_FILES += rtl/common/stats_collect.v
SYN_FILES += rtl/common/stats_pcie_if.v
SYN_FILES += rtl/common/stats_pcie_tlp.v
SYN_FILES += rtl/common/stats_dma_if_pcie.v
SYN_FILES += rtl/common/stats_dma_latency.v
SYN_FILES += rtl/common/mqnic_tx_scheduler_block_rr.v
SYN_FILES += rtl/common/tx_scheduler_rr.v
SYN_FILES += rtl/common/tdma_scheduler.v
SYN_FILES += rtl/common/tdma_ber.v
SYN_FILES += rtl/common/tdma_ber_ch.v
SYN_FILES += lib/eth/rtl/eth_mac_10g.v
SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v
SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v
SYN_FILES += lib/eth/rtl/eth_phy_10g.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_watchdog.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v
SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v
SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v
SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v
SYN_FILES += lib/eth/rtl/lfsr.v
SYN_FILES += lib/eth/rtl/ptp_clock.v
SYN_FILES += lib/eth/rtl/ptp_clock_cdc.v
SYN_FILES += lib/eth/rtl/ptp_perout.v
SYN_FILES += lib/axi/rtl/axil_interconnect.v
SYN_FILES += lib/axi/rtl/axil_crossbar.v
SYN_FILES += lib/axi/rtl/axil_crossbar_addr.v
SYN_FILES += lib/axi/rtl/axil_crossbar_rd.v
SYN_FILES += lib/axi/rtl/axil_crossbar_wr.v
SYN_FILES += lib/axi/rtl/axil_reg_if.v
SYN_FILES += lib/axi/rtl/axil_reg_if_rd.v
SYN_FILES += lib/axi/rtl/axil_reg_if_wr.v
SYN_FILES += lib/axi/rtl/axil_register_rd.v
SYN_FILES += lib/axi/rtl/axil_register_wr.v
SYN_FILES += lib/axi/rtl/arbiter.v
SYN_FILES += lib/axi/rtl/priority_encoder.v
SYN_FILES += lib/axis/rtl/axis_adapter.v
SYN_FILES += lib/axis/rtl/axis_arb_mux.v
SYN_FILES += lib/axis/rtl/axis_async_fifo.v
SYN_FILES += lib/axis/rtl/axis_async_fifo_adapter.v
SYN_FILES += lib/axis/rtl/axis_demux.v
SYN_FILES += lib/axis/rtl/axis_fifo.v
SYN_FILES += lib/axis/rtl/axis_fifo_adapter.v
SYN_FILES += lib/axis/rtl/axis_pipeline_fifo.v
SYN_FILES += lib/axis/rtl/axis_register.v
SYN_FILES += lib/axis/rtl/sync_reset.v
SYN_FILES += lib/pcie/rtl/pcie_axil_master.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v
SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v
SYN_FILES += lib/pcie/rtl/dma_if_mux.v
SYN_FILES += lib/pcie/rtl/dma_if_mux_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_mux_wr.v
SYN_FILES += lib/pcie/rtl/dma_if_desc_mux.v
SYN_FILES += lib/pcie/rtl/dma_ram_demux_rd.v
SYN_FILES += lib/pcie/rtl/dma_ram_demux_wr.v
SYN_FILES += lib/pcie/rtl/dma_psdpram.v
SYN_FILES += lib/pcie/rtl/dma_client_axis_sink.v
SYN_FILES += lib/pcie/rtl/dma_client_axis_source.v
SYN_FILES += lib/pcie/rtl/pcie_us_if.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v
SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v
SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v
SYN_FILES += lib/pcie/rtl/pcie_us_msi.v
SYN_FILES += lib/pcie/rtl/pulse_merge.v
# XDC files
XDC_FILES = fpga.xdc
XDC_FILES += boot.xdc
XDC_FILES += lib/axis/syn/vivado/axis_async_fifo.tcl
XDC_FILES += lib/axis/syn/vivado/sync_reset.tcl
XDC_FILES += lib/eth/syn/vivado/ptp_clock_cdc.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_port.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_ptp_clock.tcl
XDC_FILES += ../../../common/syn/vivado/rb_drp.tcl
XDC_FILES += ../../../common/syn/vivado/eth_xcvr_phy_10g_gty_wrapper.tcl
XDC_FILES += ../../../common/syn/vivado/tdma_ber_ch.tcl
# IP
IP_TCL_FILES = ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += ip/eth_xcvr_gty.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
echo "open_hw" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl
echo "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 32 -interface BPIx16 -loadbit {up 0x00800000 $*.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: $(FPGA_TOP).mcs $(FPGA_TOP).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {s29gl256p-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 \"$(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.BPI_RS_PINS {24:23} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@ -0,0 +1,280 @@
# Copyright 2021, The Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of The Regents of the University of California.
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4A63093]
set fw_id [expr 0x00000000]
set fw_ver $tag_ver
set board_vendor_id [expr 0x1ce4]
set board_device_id [expr 0x000a]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0x1001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_vendor_id $board_vendor_id
set pcie_subsystem_device_id $board_device_id
# FW ID block
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%02x%02x%02x%02x" {*}[split $fw_ver .-] 0 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%02x%02x%02x%02x" {*}[split $board_ver .-] 0 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# Transceiver configuration
set eth_xcvr_freerun_freq {125}
set eth_xcvr_line_rate {10.3125}
set eth_xcvr_sec_line_rate {0}
set eth_xcvr_refclk_freq {161.1328125}
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_rx_eq_mode {DFE}
# Structural configuration
dict set params IF_COUNT "2"
dict set params PORTS_PER_IF "1"
dict set params SCHED_PER_IF [dict get $params PORTS_PER_IF]
dict set params PORT_MASK "0"
# PTP configuration
dict set params PTP_CLOCK_PIPELINE "0"
dict set params PTP_CLOCK_CDC_PIPELINE "0"
dict set params PTP_PORT_CDC_PIPELINE "0"
dict set params PTP_PEROUT_ENABLE "1"
dict set params PTP_PEROUT_COUNT "1"
# Queue manager configuration
dict set params EVENT_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_QUEUE_OP_TABLE_SIZE "32"
dict set params RX_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params TX_QUEUE_OP_TABLE_SIZE]
dict set params RX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params RX_QUEUE_OP_TABLE_SIZE]
dict set params EVENT_QUEUE_INDEX_WIDTH "5"
dict set params TX_QUEUE_INDEX_WIDTH "13"
dict set params RX_QUEUE_INDEX_WIDTH "8"
dict set params TX_CPL_QUEUE_INDEX_WIDTH [dict get $params TX_QUEUE_INDEX_WIDTH]
dict set params RX_CPL_QUEUE_INDEX_WIDTH [dict get $params RX_QUEUE_INDEX_WIDTH]
dict set params EVENT_QUEUE_PIPELINE "3"
dict set params TX_QUEUE_PIPELINE [expr 3+([dict get $params TX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params TX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params RX_QUEUE_PIPELINE [expr 3+([dict get $params RX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params RX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params TX_CPL_QUEUE_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params RX_CPL_QUEUE_PIPELINE [dict get $params RX_QUEUE_PIPELINE]
# TX and RX engine configuration
dict set params TX_DESC_TABLE_SIZE "32"
dict set params RX_DESC_TABLE_SIZE "32"
# Scheduler configuration
dict set params TX_SCHEDULER_OP_TABLE_SIZE [dict get $params TX_DESC_TABLE_SIZE]
dict set params TX_SCHEDULER_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params TDMA_INDEX_WIDTH "6"
# Interface configuration
dict set params PTP_TS_ENABLE "1"
dict set params TX_CPL_FIFO_DEPTH "32"
dict set params TX_CHECKSUM_ENABLE "1"
dict set params RX_RSS_ENABLE "1"
dict set params RX_HASH_ENABLE "1"
dict set params RX_CHECKSUM_ENABLE "1"
dict set params TX_FIFO_DEPTH "32768"
dict set params RX_FIFO_DEPTH "32768"
dict set params MAX_TX_SIZE "9214"
dict set params MAX_RX_SIZE "9214"
dict set params TX_RAM_SIZE "32768"
dict set params RX_RAM_SIZE "32768"
# Application block configuration
dict set params APP_ID "32'h00000000"
dict set params APP_ENABLE "0"
dict set params APP_CTRL_ENABLE "1"
dict set params APP_DMA_ENABLE "1"
dict set params APP_AXIS_DIRECT_ENABLE "1"
dict set params APP_AXIS_SYNC_ENABLE "1"
dict set params APP_AXIS_IF_ENABLE "1"
dict set params APP_STAT_ENABLE "1"
# DMA interface configuration
dict set params DMA_IMM_ENABLE "0"
dict set params DMA_IMM_WIDTH "32"
dict set params DMA_LEN_WIDTH "16"
dict set params DMA_TAG_WIDTH "16"
dict set params RAM_ADDR_WIDTH [expr int(ceil(log(max([dict get $params TX_RAM_SIZE], [dict get $params RX_RAM_SIZE]))/log(2)))]
dict set params RAM_PIPELINE "2"
# PCIe interface configuration
dict set params PCIE_TAG_COUNT "64"
dict set params PCIE_DMA_READ_OP_TABLE_SIZE [dict get $params PCIE_TAG_COUNT]
dict set params PCIE_DMA_READ_TX_LIMIT "16"
dict set params PCIE_DMA_READ_TX_FC_ENABLE "1"
dict set params PCIE_DMA_WRITE_OP_TABLE_SIZE "16"
dict set params PCIE_DMA_WRITE_TX_LIMIT "3"
dict set params PCIE_DMA_WRITE_TX_FC_ENABLE "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_WIDTH "32"
dict set params AXIL_CTRL_ADDR_WIDTH "24"
# AXI lite interface configuration (application control)
dict set params AXIL_APP_CTRL_DATA_WIDTH [dict get $params AXIL_CTRL_DATA_WIDTH]
dict set params AXIL_APP_CTRL_ADDR_WIDTH "24"
# Ethernet interface configuration
dict set params AXIS_ETH_SYNC_DATA_WIDTH_DOUBLE [expr max($eth_xcvr_line_rate, $eth_xcvr_sec_line_rate) > 16]
dict set params AXIS_ETH_TX_PIPELINE "0"
dict set params AXIS_ETH_TX_FIFO_PIPELINE "2"
dict set params AXIS_ETH_TX_TS_PIPELINE "0"
dict set params AXIS_ETH_RX_PIPELINE "0"
dict set params AXIS_ETH_RX_FIFO_PIPELINE "2"
# Statistics counter subsystem
dict set params STAT_ENABLE "1"
dict set params STAT_DMA_ENABLE "1"
dict set params STAT_PCIE_ENABLE "1"
dict set params STAT_INC_WIDTH "24"
dict set params STAT_ID_WIDTH "12"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# PCIe IDs
set_property CONFIG.vendor_id [format "%04x" $pcie_vendor_id] $pcie
set_property CONFIG.PF0_DEVICE_ID [format "%04x" $pcie_device_id] $pcie
set_property CONFIG.PF0_CLASS_CODE [format "%06x" $pcie_class_code] $pcie
set_property CONFIG.PF0_REVISION_ID [format "%02x" $pcie_revision_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_VENDOR_ID [format "%04x" $pcie_subsystem_vendor_id] $pcie
set_property CONFIG.PF0_SUBSYSTEM_ID [format "%04x" $pcie_subsystem_device_id] $pcie
# Internal interface settings
dict set params AXIS_PCIE_DATA_WIDTH [regexp -all -inline -- {[0-9]+} [get_property CONFIG.axisten_if_width $pcie]]
dict set params AXIS_PCIE_KEEP_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH]/32]
dict set params AXIS_PCIE_RC_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 75 : 161]
dict set params AXIS_PCIE_RQ_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 62 : 137]
dict set params AXIS_PCIE_CQ_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 85 : 183]
dict set params AXIS_PCIE_CC_USER_WIDTH [expr [dict get $params AXIS_PCIE_DATA_WIDTH] < 512 ? 33 : 81]
dict set params RQ_SEQ_NUM_WIDTH [expr [dict get $params AXIS_PCIE_RQ_USER_WIDTH] == 60 ? 4 : 6]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_WIDTH]
# Application BAR (BAR 2)
configure_bar $pcie 0 2 [expr [dict get $params APP_ENABLE] ? [dict get $params AXIL_APP_CTRL_ADDR_WIDTH] : 0]
# Transceiver configuration
set xcvr_config [dict create]
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
if {$eth_xcvr_sec_line_rate != 0} {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
} else {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
}
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
set_property -dict $xcvr_config [get_ips eth_xcvr_gty_full]
set_property -dict $xcvr_config [get_ips eth_xcvr_gty_channel]
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
# set_property generic $param_list [current_fileset]
set_property generic $param_list [get_filesets sources_1]

View File

@ -0,0 +1,129 @@
# Copyright 2022, The Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of The Regents of the University of California.
set base_name {eth_xcvr_gty}
set preset {GTY-10GBASE-R}
set freerun_freq {125}
set line_rate {25.78125}
set sec_line_rate {10.3125}
set refclk_freq {161.1328125}
set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}]
set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}]
set user_data_width {64}
set int_data_width $user_data_width
set rx_eq_mode {DFE}
set extra_ports [list]
set extra_pll_ports [list]
# DRP connections
lappend extra_ports drpclk_in drpaddr_in drpdi_in drpen_in drpwe_in drpdo_out drprdy_out
lappend extra_pll_ports drpclk_common_in drpaddr_common_in drpdi_common_in drpen_common_in drpwe_common_in drpdo_common_out drprdy_common_out
# PLL reset and power down
lappend extra_pll_ports qpll0reset_in qpll1reset_in
lappend extra_pll_ports qpll0pd_in qpll1pd_in
# PLL clocking
lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out
lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out
# channel reset
lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txresetdone_out txpmaresetdone_out
lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxresetdone_out rxpmaresetdone_out
# channel power down
lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in
# channel clock selection
lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in
# channel polarity
lappend extra_ports txpolarity_in rxpolarity_in
# channel TX driver
lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in
# channel CDR
lappend extra_ports rxcdrlock_out rxcdrhold_in
# channel EQ
lappend extra_ports rxlpmen_in
# channel digital monitor
lappend extra_ports dmonitorout_out
# channel PRBS
lappend extra_ports txprbsforceerr_in txprbssel_in rxprbscntreset_in rxprbssel_in rxprbserr_out rxprbslocked_out
# channel eye scan
lappend extra_ports eyescandataerror_out
# channel loopback
lappend extra_ports loopback_in
set config [dict create]
dict set config TX_LINE_RATE $line_rate
dict set config TX_REFCLK_FREQUENCY $refclk_freq
dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn
dict set config TX_USER_DATA_WIDTH $user_data_width
dict set config TX_INT_DATA_WIDTH $int_data_width
dict set config RX_LINE_RATE $line_rate
dict set config RX_REFCLK_FREQUENCY $refclk_freq
dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn
dict set config RX_USER_DATA_WIDTH $user_data_width
dict set config RX_INT_DATA_WIDTH $int_data_width
dict set config RX_EQ_MODE $rx_eq_mode
if {$sec_line_rate != 0} {
dict set config SECONDARY_QPLL_ENABLE true
dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn
dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate
dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $refclk_freq
} else {
dict set config SECONDARY_QPLL_ENABLE false
}
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
dict set config LOCATE_COMMON {CORE}
dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN}
dict set config LOCATE_TX_USER_CLOCKING {CORE}
dict set config LOCATE_RX_USER_CLOCKING {CORE}
dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE}
dict set config FREERUN_FREQUENCY $freerun_freq
dict set config DISABLE_LOC_XDC {1}
proc create_gtwizard_ip {name preset config} {
create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name
set ip [get_ips $name]
set_property CONFIG.preset $preset $ip
set config_list {}
dict for {name value} $config {
lappend config_list "CONFIG.${name}" $value
}
set_property -dict $config_list $ip
}
# variant with channel and common
dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports]
dict set config LOCATE_COMMON {CORE}
create_gtwizard_ip "${base_name}_full" $preset $config
# variant with channel only
dict set config ENABLE_OPTIONAL_PORTS $extra_ports
dict set config LOCATE_COMMON {EXAMPLE_DESIGN}
create_gtwizard_ip "${base_name}_channel" $preset $config

View File

@ -0,0 +1,26 @@
create_ip -name pcie4_uscale_plus -vendor xilinx.com -library ip -module_name pcie4_uscale_plus_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \
CONFIG.AXISTEN_IF_RC_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {256_bit} \
CONFIG.extended_tag_field {true} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {1001} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.PF0_SUBSYSTEM_ID {000a} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} \
CONFIG.pf0_bar0_64bit {true} \
CONFIG.pf0_bar0_prefetchable {true} \
CONFIG.pf0_bar0_scale {Megabytes} \
CONFIG.pf0_bar0_size {16} \
CONFIG.vendor_id {1234} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.mode_selection {Advanced} \
CONFIG.en_gt_selection {true} \
CONFIG.select_quad {GTY_Quad_225} \
] [get_ips pcie4_uscale_plus_0]

View File

@ -0,0 +1 @@
../../../lib/

View File

@ -0,0 +1 @@
../../../../common/rtl/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/*
Copyright (c) 2014-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog-2001
`resetall
`timescale 1 ns / 1 ps
`default_nettype none
/*
* Synchronizes an asyncronous signal to a given clock by using a pipeline of
* two registers.
*/
module sync_signal #(
parameter WIDTH=1, // width of the input and output signals
parameter N=2 // depth of synchronizer
)(
input wire clk,
input wire [WIDTH-1:0] in,
output wire [WIDTH-1:0] out
);
reg [WIDTH-1:0] sync_reg[N-1:0];
/*
* The synchronized output is the last register in the pipeline.
*/
assign out = sync_reg[N-1];
integer k;
always @(posedge clk) begin
sync_reg[0] <= in;
for (k = 1; k < N; k = k + 1) begin
sync_reg[k] <= sync_reg[k-1];
end
end
endmodule
`resetall

View File

@ -0,0 +1,443 @@
# Copyright 2020-2021, The Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of The Regents of the University of California.
TOPLEVEL_LANG = verilog
SIM ?= icarus
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
DUT = fpga_core
TOPLEVEL = $(DUT)
MODULE = test_$(DUT)
VERILOG_SOURCES += ../../rtl/$(DUT).v
VERILOG_SOURCES += ../../rtl/common/mqnic_core_pcie_us.v
VERILOG_SOURCES += ../../rtl/common/mqnic_core_pcie.v
VERILOG_SOURCES += ../../rtl/common/mqnic_core.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface_tx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface_rx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port_tx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port_rx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_egress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ingress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_l2_egress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_l2_ingress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_rx_queue_map.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp_clock.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp_perout.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port_map_phy_xgmii.v
VERILOG_SOURCES += ../../rtl/common/cpl_write.v
VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v
VERILOG_SOURCES += ../../rtl/common/desc_fetch.v
VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v
VERILOG_SOURCES += ../../rtl/common/event_mux.v
VERILOG_SOURCES += ../../rtl/common/queue_manager.v
VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v
VERILOG_SOURCES += ../../rtl/common/tx_fifo.v
VERILOG_SOURCES += ../../rtl/common/rx_fifo.v
VERILOG_SOURCES += ../../rtl/common/tx_req_mux.v
VERILOG_SOURCES += ../../rtl/common/tx_engine.v
VERILOG_SOURCES += ../../rtl/common/rx_engine.v
VERILOG_SOURCES += ../../rtl/common/tx_checksum.v
VERILOG_SOURCES += ../../rtl/common/rx_hash.v
VERILOG_SOURCES += ../../rtl/common/rx_checksum.v
VERILOG_SOURCES += ../../rtl/common/rb_drp.v
VERILOG_SOURCES += ../../rtl/common/stats_counter.v
VERILOG_SOURCES += ../../rtl/common/stats_collect.v
VERILOG_SOURCES += ../../rtl/common/stats_pcie_if.v
VERILOG_SOURCES += ../../rtl/common/stats_pcie_tlp.v
VERILOG_SOURCES += ../../rtl/common/stats_dma_if_pcie.v
VERILOG_SOURCES += ../../rtl/common/stats_dma_latency.v
VERILOG_SOURCES += ../../rtl/common/mqnic_tx_scheduler_block_rr.v
VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v
VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v
VERILOG_SOURCES += ../../rtl/common/tdma_ber.v
VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v
VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v
VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v
VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_crossbar.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_crossbar_addr.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_crossbar_rd.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_crossbar_wr.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_reg_if.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_reg_if_rd.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_reg_if_wr.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_register_rd.v
VERILOG_SOURCES += ../../lib/axi/rtl/axil_register_wr.v
VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_demux.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo_adapter.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_pipeline_fifo.v
VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_desc_mux.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_ram_demux_rd.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_ram_demux_wr.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rc.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rq.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cc.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cq.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v
VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v
# module parameters
# Structural configuration
export PARAM_IF_COUNT ?= 2
export PARAM_PORTS_PER_IF ?= 1
export PARAM_SCHED_PER_IF ?= $(PARAM_PORTS_PER_IF)
export PARAM_PORT_MASK ?= 0
# PTP configuration
export PARAM_PTP_CLK_PERIOD_NS_NUM = 1024
export PARAM_PTP_CLK_PERIOD_NS_DENOM = 165
export PARAM_PTP_CLOCK_PIPELINE ?= 0
export PARAM_PTP_CLOCK_CDC_PIPELINE ?= 0
export PARAM_PTP_USE_SAMPLE_CLOCK ?= 1
export PARAM_PTP_PORT_CDC_PIPELINE ?= 0
export PARAM_PTP_PEROUT_ENABLE ?= 1
export PARAM_PTP_PEROUT_COUNT ?= 1
# Queue manager configuration
export PARAM_EVENT_QUEUE_OP_TABLE_SIZE ?= 32
export PARAM_TX_QUEUE_OP_TABLE_SIZE ?= 32
export PARAM_RX_QUEUE_OP_TABLE_SIZE ?= 32
export PARAM_TX_CPL_QUEUE_OP_TABLE_SIZE ?= $(PARAM_TX_QUEUE_OP_TABLE_SIZE)
export PARAM_RX_CPL_QUEUE_OP_TABLE_SIZE ?= $(PARAM_RX_QUEUE_OP_TABLE_SIZE)
export PARAM_EVENT_QUEUE_INDEX_WIDTH ?= 5
export PARAM_TX_QUEUE_INDEX_WIDTH ?= 13
export PARAM_RX_QUEUE_INDEX_WIDTH ?= 8
export PARAM_TX_CPL_QUEUE_INDEX_WIDTH ?= $(PARAM_TX_QUEUE_INDEX_WIDTH)
export PARAM_RX_CPL_QUEUE_INDEX_WIDTH ?= $(PARAM_RX_QUEUE_INDEX_WIDTH)
export PARAM_EVENT_QUEUE_PIPELINE ?= 3
export PARAM_TX_QUEUE_PIPELINE ?= $(shell python -c "print(3 + max($(PARAM_TX_QUEUE_INDEX_WIDTH)-12, 0))")
export PARAM_RX_QUEUE_PIPELINE ?= $(shell python -c "print(3 + max($(PARAM_RX_QUEUE_INDEX_WIDTH)-12, 0))")
export PARAM_TX_CPL_QUEUE_PIPELINE ?= $(PARAM_TX_QUEUE_PIPELINE)
export PARAM_RX_CPL_QUEUE_PIPELINE ?= $(PARAM_RX_QUEUE_PIPELINE)
# TX and RX engine configuration
export PARAM_TX_DESC_TABLE_SIZE ?= 32
export PARAM_RX_DESC_TABLE_SIZE ?= 32
# Scheduler configuration
export PARAM_TX_SCHEDULER_OP_TABLE_SIZE ?= $(PARAM_TX_DESC_TABLE_SIZE)
export PARAM_TX_SCHEDULER_PIPELINE ?= $(PARAM_TX_QUEUE_PIPELINE)
export PARAM_TDMA_INDEX_WIDTH ?= 6
# Interface configuration
export PARAM_PTP_TS_ENABLE ?= 1
export PARAM_TX_CPL_FIFO_DEPTH ?= 32
export PARAM_TX_CHECKSUM_ENABLE ?= 1
export PARAM_RX_RSS_ENABLE ?= 1
export PARAM_RX_HASH_ENABLE ?= 1
export PARAM_RX_CHECKSUM_ENABLE ?= 1
export PARAM_TX_FIFO_DEPTH ?= 32768
export PARAM_RX_FIFO_DEPTH ?= 32768
export PARAM_MAX_TX_SIZE ?= 9214
export PARAM_MAX_RX_SIZE ?= 9214
export PARAM_TX_RAM_SIZE ?= 32768
export PARAM_RX_RAM_SIZE ?= 32768
# Application block configuration
export PARAM_APP_ID ?= $(shell echo $$((16#00000000)) )
export PARAM_APP_ENABLE ?= 0
export PARAM_APP_CTRL_ENABLE ?= 1
export PARAM_APP_DMA_ENABLE ?= 1
export PARAM_APP_AXIS_DIRECT_ENABLE ?= 1
export PARAM_APP_AXIS_SYNC_ENABLE ?= 1
export PARAM_APP_AXIS_IF_ENABLE ?= 1
export PARAM_APP_STAT_ENABLE ?= 1
# DMA interface configuration
export PARAM_DMA_IMM_ENABLE ?= 0
export PARAM_DMA_IMM_WIDTH ?= 32
export PARAM_DMA_LEN_WIDTH ?= 16
export PARAM_DMA_TAG_WIDTH ?= 16
export PARAM_RAM_ADDR_WIDTH ?= $(shell python -c "print((max($(PARAM_TX_RAM_SIZE), $(PARAM_RX_RAM_SIZE))-1).bit_length())")
export PARAM_RAM_PIPELINE ?= 2
# PCIe interface configuration
export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256
export PARAM_PF_COUNT ?= 1
export PARAM_VF_COUNT ?= 0
export PARAM_PCIE_TAG_COUNT ?= 64
export PARAM_PCIE_DMA_READ_OP_TABLE_SIZE ?= $(PARAM_PCIE_TAG_COUNT)
export PARAM_PCIE_DMA_READ_TX_LIMIT ?= 16
export PARAM_PCIE_DMA_READ_TX_FC_ENABLE ?= 1
export PARAM_PCIE_DMA_WRITE_OP_TABLE_SIZE ?= 16
export PARAM_PCIE_DMA_WRITE_TX_LIMIT ?= 3
export PARAM_PCIE_DMA_WRITE_TX_FC_ENABLE ?= 1
# AXI lite interface configuration (control)
export PARAM_AXIL_CTRL_DATA_WIDTH ?= 32
export PARAM_AXIL_CTRL_ADDR_WIDTH ?= 24
# AXI lite interface configuration (application control)
export PARAM_AXIL_APP_CTRL_DATA_WIDTH ?= $(PARAM_AXIL_CTRL_DATA_WIDTH)
export PARAM_AXIL_APP_CTRL_ADDR_WIDTH ?= 24
# Ethernet interface configuration
export PARAM_AXIS_ETH_TX_PIPELINE ?= 0
export PARAM_AXIS_ETH_TX_FIFO_PIPELINE ?= 2
export PARAM_AXIS_ETH_TX_TS_PIPELINE ?= 0
export PARAM_AXIS_ETH_RX_PIPELINE ?= 0
export PARAM_AXIS_ETH_RX_FIFO_PIPELINE ?= 2
# Statistics counter subsystem
export PARAM_STAT_ENABLE ?= 1
export PARAM_STAT_DMA_ENABLE ?= 1
export PARAM_STAT_PCIE_ENABLE ?= 1
export PARAM_STAT_INC_WIDTH ?= 24
export PARAM_STAT_ID_WIDTH ?= 12
ifeq ($(SIM), icarus)
PLUSARGS += -fst
COMPILE_ARGS += -P $(TOPLEVEL).IF_COUNT=$(PARAM_IF_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).PORTS_PER_IF=$(PARAM_PORTS_PER_IF)
COMPILE_ARGS += -P $(TOPLEVEL).SCHED_PER_IF=$(PARAM_SCHED_PER_IF)
COMPILE_ARGS += -P $(TOPLEVEL).PORT_MASK=$(PARAM_PORT_MASK)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_CLK_PERIOD_NS_NUM=$(PARAM_PTP_CLK_PERIOD_NS_NUM)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_CLK_PERIOD_NS_DENOM=$(PARAM_PTP_CLK_PERIOD_NS_DENOM)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_CLOCK_CDC_PIPELINE=$(PARAM_PTP_CLOCK_CDC_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_PORT_CDC_PIPELINE=$(PARAM_PTP_PORT_CDC_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_QUEUE_OP_TABLE_SIZE=$(PARAM_TX_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_QUEUE_OP_TABLE_SIZE=$(PARAM_RX_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_CPL_QUEUE_OP_TABLE_SIZE=$(PARAM_TX_CPL_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_CPL_QUEUE_OP_TABLE_SIZE=$(PARAM_RX_CPL_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_INDEX_WIDTH=$(PARAM_EVENT_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).TX_QUEUE_INDEX_WIDTH=$(PARAM_TX_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RX_QUEUE_INDEX_WIDTH=$(PARAM_RX_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).TX_CPL_QUEUE_INDEX_WIDTH=$(PARAM_TX_CPL_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RX_CPL_QUEUE_INDEX_WIDTH=$(PARAM_RX_CPL_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).EVENT_QUEUE_PIPELINE=$(PARAM_EVENT_QUEUE_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_QUEUE_PIPELINE=$(PARAM_TX_QUEUE_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_QUEUE_PIPELINE=$(PARAM_RX_QUEUE_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_CPL_QUEUE_PIPELINE=$(PARAM_TX_CPL_QUEUE_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_CPL_QUEUE_PIPELINE=$(PARAM_RX_CPL_QUEUE_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_DESC_TABLE_SIZE=$(PARAM_TX_DESC_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_DESC_TABLE_SIZE=$(PARAM_RX_DESC_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_SCHEDULER_OP_TABLE_SIZE=$(PARAM_TX_SCHEDULER_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_SCHEDULER_PIPELINE=$(PARAM_TX_SCHEDULER_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).TDMA_INDEX_WIDTH=$(PARAM_TDMA_INDEX_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).PTP_TS_ENABLE=$(PARAM_PTP_TS_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_CPL_FIFO_DEPTH=$(PARAM_TX_CPL_FIFO_DEPTH)
COMPILE_ARGS += -P $(TOPLEVEL).TX_CHECKSUM_ENABLE=$(PARAM_TX_CHECKSUM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_RSS_ENABLE=$(PARAM_RX_RSS_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_HASH_ENABLE=$(PARAM_RX_HASH_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_CHECKSUM_ENABLE=$(PARAM_RX_CHECKSUM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_FIFO_DEPTH=$(PARAM_TX_FIFO_DEPTH)
COMPILE_ARGS += -P $(TOPLEVEL).RX_FIFO_DEPTH=$(PARAM_RX_FIFO_DEPTH)
COMPILE_ARGS += -P $(TOPLEVEL).MAX_TX_SIZE=$(PARAM_MAX_TX_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).MAX_RX_SIZE=$(PARAM_MAX_RX_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).TX_RAM_SIZE=$(PARAM_TX_RAM_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).RX_RAM_SIZE=$(PARAM_RX_RAM_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_ID=$(PARAM_APP_ID)
COMPILE_ARGS += -P $(TOPLEVEL).APP_ENABLE=$(PARAM_APP_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_CTRL_ENABLE=$(PARAM_APP_CTRL_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_DMA_ENABLE=$(PARAM_APP_DMA_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_AXIS_DIRECT_ENABLE=$(PARAM_APP_AXIS_DIRECT_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_AXIS_SYNC_ENABLE=$(PARAM_APP_AXIS_SYNC_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_AXIS_IF_ENABLE=$(PARAM_APP_AXIS_IF_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).APP_STAT_ENABLE=$(PARAM_APP_STAT_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).DMA_IMM_ENABLE=$(PARAM_DMA_IMM_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).DMA_IMM_WIDTH=$(PARAM_DMA_IMM_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).DMA_LEN_WIDTH=$(PARAM_DMA_LEN_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).DMA_TAG_WIDTH=$(PARAM_DMA_TAG_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_ADDR_WIDTH=$(PARAM_RAM_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).PF_COUNT=$(PARAM_PF_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).VF_COUNT=$(PARAM_VF_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_READ_OP_TABLE_SIZE=$(PARAM_PCIE_DMA_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_READ_TX_LIMIT=$(PARAM_PCIE_DMA_READ_TX_LIMIT)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_READ_TX_FC_ENABLE=$(PARAM_PCIE_DMA_READ_TX_FC_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_WRITE_OP_TABLE_SIZE=$(PARAM_PCIE_DMA_WRITE_OP_TABLE_SIZE)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_WRITE_TX_LIMIT=$(PARAM_PCIE_DMA_WRITE_TX_LIMIT)
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_DMA_WRITE_TX_FC_ENABLE=$(PARAM_PCIE_DMA_WRITE_TX_FC_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIL_CTRL_DATA_WIDTH=$(PARAM_AXIL_CTRL_DATA_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).AXIL_CTRL_ADDR_WIDTH=$(PARAM_AXIL_CTRL_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).AXIL_APP_CTRL_DATA_WIDTH=$(PARAM_AXIL_APP_CTRL_DATA_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).AXIL_APP_CTRL_ADDR_WIDTH=$(PARAM_AXIL_APP_CTRL_ADDR_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_TX_PIPELINE=$(PARAM_AXIS_ETH_TX_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_TX_FIFO_PIPELINE=$(PARAM_AXIS_ETH_TX_FIFO_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_TX_TS_PIPELINE=$(PARAM_AXIS_ETH_TX_TS_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_RX_PIPELINE=$(PARAM_AXIS_ETH_RX_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_RX_FIFO_PIPELINE=$(PARAM_AXIS_ETH_RX_FIFO_PIPELINE)
COMPILE_ARGS += -P $(TOPLEVEL).STAT_ENABLE=$(PARAM_STAT_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).STAT_DMA_ENABLE=$(PARAM_STAT_DMA_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).STAT_PCIE_ENABLE=$(PARAM_STAT_PCIE_ENABLE)
COMPILE_ARGS += -P $(TOPLEVEL).STAT_INC_WIDTH=$(PARAM_STAT_INC_WIDTH)
COMPILE_ARGS += -P $(TOPLEVEL).STAT_ID_WIDTH=$(PARAM_STAT_ID_WIDTH)
ifeq ($(WAVES), 1)
VERILOG_SOURCES += iverilog_dump.v
COMPILE_ARGS += -s iverilog_dump
endif
else ifeq ($(SIM), verilator)
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
COMPILE_ARGS += -GIF_COUNT=$(PARAM_IF_COUNT)
COMPILE_ARGS += -GPORTS_PER_IF=$(PARAM_PORTS_PER_IF)
COMPILE_ARGS += -GSCHED_PER_IF=$(PARAM_SCHED_PER_IF)
COMPILE_ARGS += -GPORT_MASK=$(PARAM_PORT_MASK)
COMPILE_ARGS += -GPTP_CLK_PERIOD_NS_NUM=$(PARAM_PTP_CLK_PERIOD_NS_NUM)
COMPILE_ARGS += -GPTP_CLK_PERIOD_NS_DENOM=$(PARAM_PTP_CLK_PERIOD_NS_DENOM)
COMPILE_ARGS += -GPTP_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_PIPELINE)
COMPILE_ARGS += -GPTP_CLOCK_CDC_PIPELINE=$(PARAM_PTP_CLOCK_CDC_PIPELINE)
COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK)
COMPILE_ARGS += -GPTP_PORT_CDC_PIPELINE=$(PARAM_PTP_PORT_CDC_PIPELINE)
COMPILE_ARGS += -GPTP_PEROUT_ENABLE=$(PARAM_PTP_PEROUT_ENABLE)
COMPILE_ARGS += -GPTP_PEROUT_COUNT=$(PARAM_PTP_PEROUT_COUNT)
COMPILE_ARGS += -GEVENT_QUEUE_OP_TABLE_SIZE=$(PARAM_EVENT_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -GTX_QUEUE_OP_TABLE_SIZE=$(PARAM_TX_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -GRX_QUEUE_OP_TABLE_SIZE=$(PARAM_RX_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -GTX_CPL_QUEUE_OP_TABLE_SIZE=$(PARAM_TX_CPL_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -GRX_CPL_QUEUE_OP_TABLE_SIZE=$(PARAM_RX_CPL_QUEUE_OP_TABLE_SIZE)
COMPILE_ARGS += -GEVENT_QUEUE_INDEX_WIDTH=$(PARAM_EVENT_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -GTX_QUEUE_INDEX_WIDTH=$(PARAM_TX_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -GRX_QUEUE_INDEX_WIDTH=$(PARAM_RX_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -GTX_CPL_QUEUE_INDEX_WIDTH=$(PARAM_TX_CPL_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -GRX_CPL_QUEUE_INDEX_WIDTH=$(PARAM_RX_CPL_QUEUE_INDEX_WIDTH)
COMPILE_ARGS += -GEVENT_QUEUE_PIPELINE=$(PARAM_EVENT_QUEUE_PIPELINE)
COMPILE_ARGS += -GTX_QUEUE_PIPELINE=$(PARAM_TX_QUEUE_PIPELINE)
COMPILE_ARGS += -GRX_QUEUE_PIPELINE=$(PARAM_RX_QUEUE_PIPELINE)
COMPILE_ARGS += -GTX_CPL_QUEUE_PIPELINE=$(PARAM_TX_CPL_QUEUE_PIPELINE)
COMPILE_ARGS += -GRX_CPL_QUEUE_PIPELINE=$(PARAM_RX_CPL_QUEUE_PIPELINE)
COMPILE_ARGS += -GTX_DESC_TABLE_SIZE=$(PARAM_TX_DESC_TABLE_SIZE)
COMPILE_ARGS += -GRX_DESC_TABLE_SIZE=$(PARAM_RX_DESC_TABLE_SIZE)
COMPILE_ARGS += -GTX_SCHEDULER_OP_TABLE_SIZE=$(PARAM_TX_SCHEDULER_OP_TABLE_SIZE)
COMPILE_ARGS += -GTX_SCHEDULER_PIPELINE=$(PARAM_TX_SCHEDULER_PIPELINE)
COMPILE_ARGS += -GTDMA_INDEX_WIDTH=$(PARAM_TDMA_INDEX_WIDTH)
COMPILE_ARGS += -GPTP_TS_ENABLE=$(PARAM_PTP_TS_ENABLE)
COMPILE_ARGS += -GTX_CPL_FIFO_DEPTH=$(PARAM_TX_CPL_FIFO_DEPTH)
COMPILE_ARGS += -GTX_CHECKSUM_ENABLE=$(PARAM_TX_CHECKSUM_ENABLE)
COMPILE_ARGS += -GRX_RSS_ENABLE=$(PARAM_RX_RSS_ENABLE)
COMPILE_ARGS += -GRX_HASH_ENABLE=$(PARAM_RX_HASH_ENABLE)
COMPILE_ARGS += -GRX_CHECKSUM_ENABLE=$(PARAM_RX_CHECKSUM_ENABLE)
COMPILE_ARGS += -GTX_FIFO_DEPTH=$(PARAM_TX_FIFO_DEPTH)
COMPILE_ARGS += -GRX_FIFO_DEPTH=$(PARAM_RX_FIFO_DEPTH)
COMPILE_ARGS += -GMAX_TX_SIZE=$(PARAM_MAX_TX_SIZE)
COMPILE_ARGS += -GMAX_RX_SIZE=$(PARAM_MAX_RX_SIZE)
COMPILE_ARGS += -GTX_RAM_SIZE=$(PARAM_TX_RAM_SIZE)
COMPILE_ARGS += -GRX_RAM_SIZE=$(PARAM_RX_RAM_SIZE)
COMPILE_ARGS += -GAPP_ID=$(PARAM_APP_ID)
COMPILE_ARGS += -GAPP_ENABLE=$(PARAM_APP_ENABLE)
COMPILE_ARGS += -GAPP_CTRL_ENABLE=$(PARAM_APP_CTRL_ENABLE)
COMPILE_ARGS += -GAPP_DMA_ENABLE=$(PARAM_APP_DMA_ENABLE)
COMPILE_ARGS += -GAPP_AXIS_DIRECT_ENABLE=$(PARAM_APP_AXIS_DIRECT_ENABLE)
COMPILE_ARGS += -GAPP_AXIS_SYNC_ENABLE=$(PARAM_APP_AXIS_SYNC_ENABLE)
COMPILE_ARGS += -GAPP_AXIS_IF_ENABLE=$(PARAM_APP_AXIS_IF_ENABLE)
COMPILE_ARGS += -GAPP_STAT_ENABLE=$(PARAM_APP_STAT_ENABLE)
COMPILE_ARGS += -GDMA_IMM_ENABLE=$(PARAM_DMA_IMM_ENABLE)
COMPILE_ARGS += -GDMA_IMM_WIDTH=$(PARAM_DMA_IMM_WIDTH)
COMPILE_ARGS += -GDMA_LEN_WIDTH=$(PARAM_DMA_LEN_WIDTH)
COMPILE_ARGS += -GDMA_TAG_WIDTH=$(PARAM_DMA_TAG_WIDTH)
COMPILE_ARGS += -GRAM_ADDR_WIDTH=$(PARAM_RAM_ADDR_WIDTH)
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH)
COMPILE_ARGS += -GPF_COUNT=$(PARAM_PF_COUNT)
COMPILE_ARGS += -GVF_COUNT=$(PARAM_VF_COUNT)
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
COMPILE_ARGS += -GPCIE_DMA_READ_OP_TABLE_SIZE=$(PARAM_PCIE_DMA_READ_OP_TABLE_SIZE)
COMPILE_ARGS += -GPCIE_DMA_READ_TX_LIMIT=$(PARAM_PCIE_DMA_READ_TX_LIMIT)
COMPILE_ARGS += -GPCIE_DMA_READ_TX_FC_ENABLE=$(PARAM_PCIE_DMA_READ_TX_FC_ENABLE)
COMPILE_ARGS += -GPCIE_DMA_WRITE_OP_TABLE_SIZE=$(PARAM_PCIE_DMA_WRITE_OP_TABLE_SIZE)
COMPILE_ARGS += -GPCIE_DMA_WRITE_TX_LIMIT=$(PARAM_PCIE_DMA_WRITE_TX_LIMIT)
COMPILE_ARGS += -GPCIE_DMA_WRITE_TX_FC_ENABLE=$(PARAM_PCIE_DMA_WRITE_TX_FC_ENABLE)
COMPILE_ARGS += -GAXIL_CTRL_DATA_WIDTH=$(PARAM_AXIL_CTRL_DATA_WIDTH)
COMPILE_ARGS += -GAXIL_CTRL_ADDR_WIDTH=$(PARAM_AXIL_CTRL_ADDR_WIDTH)
COMPILE_ARGS += -GAXIL_APP_CTRL_DATA_WIDTH=$(PARAM_AXIL_APP_CTRL_DATA_WIDTH)
COMPILE_ARGS += -GAXIL_APP_CTRL_ADDR_WIDTH=$(PARAM_AXIL_APP_CTRL_ADDR_WIDTH)
COMPILE_ARGS += -GAXIS_ETH_TX_PIPELINE=$(PARAM_AXIS_ETH_TX_PIPELINE)
COMPILE_ARGS += -GAXIS_ETH_TX_FIFO_PIPELINE=$(PARAM_AXIS_ETH_TX_FIFO_PIPELINE)
COMPILE_ARGS += -GAXIS_ETH_TX_TS_PIPELINE=$(PARAM_AXIS_ETH_TX_TS_PIPELINE)
COMPILE_ARGS += -GAXIS_ETH_RX_PIPELINE=$(PARAM_AXIS_ETH_RX_PIPELINE)
COMPILE_ARGS += -GAXIS_ETH_RX_FIFO_PIPELINE=$(PARAM_AXIS_ETH_RX_FIFO_PIPELINE)
COMPILE_ARGS += -GSTAT_ENABLE=$(PARAM_STAT_ENABLE)
COMPILE_ARGS += -GSTAT_DMA_ENABLE=$(PARAM_STAT_DMA_ENABLE)
COMPILE_ARGS += -GSTAT_PCIE_ENABLE=$(PARAM_STAT_PCIE_ENABLE)
COMPILE_ARGS += -GSTAT_INC_WIDTH=$(PARAM_STAT_INC_WIDTH)
COMPILE_ARGS += -GSTAT_ID_WIDTH=$(PARAM_STAT_ID_WIDTH)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
iverilog_dump.v:
echo 'module iverilog_dump();' > $@
echo 'initial begin' >> $@
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
echo 'end' >> $@
echo 'endmodule' >> $@
clean::
@rm -rf iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1 @@
../../../../../common/tb/mqnic.py

View File

@ -0,0 +1,872 @@
"""
Copyright 2020-2021, The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of The Regents of the University of California.
"""
import logging
import os
import sys
import scapy.utils
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
import cocotb_test.simulator
import cocotb
from cocotb.log import SimLog
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.axi import AxiStreamBus
from cocotbext.eth import XgmiiSource, XgmiiSink
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice
try:
import mqnic
except ImportError:
# attempt import from current directory
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
try:
import mqnic
finally:
del sys.path[0]
class TB(object):
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
# PCIe
self.rc = RootComplex()
self.rc.max_payload_size = 0x1 # 256 bytes
self.rc.max_read_request_size = 0x2 # 512 bytes
self.dev = UltraScalePlusPcieDevice(
# configuration options
pcie_generation=3,
pcie_link_width=8,
user_clk_frequency=250e6,
alignment="dword",
cq_cc_straddle=False,
rq_rc_straddle=False,
rc_4tlp_straddle=False,
enable_pf1=False,
enable_client_tag=True,
enable_extended_tag=True,
enable_parity=False,
enable_rx_msg_interface=False,
enable_sriov=False,
enable_extended_configuration=False,
enable_pf0_msi=True,
enable_pf1_msi=False,
# signals
# Clock and Reset Interface
user_clk=dut.clk_250mhz,
user_reset=dut.rst_250mhz,
# user_lnk_up
# sys_clk
# sys_clk_gt
# sys_reset
# phy_rdy_out
# Requester reQuest Interface
rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"),
pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0,
pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0,
pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1,
pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1,
# pcie_rq_tag0
# pcie_rq_tag1
# pcie_rq_tag_av
# pcie_rq_tag_vld0
# pcie_rq_tag_vld1
# Requester Completion Interface
rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"),
# Completer reQuest Interface
cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"),
# pcie_cq_np_req
# pcie_cq_np_req_count
# Completer Completion Interface
cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"),
# Transmit Flow Control Interface
# pcie_tfc_nph_av=dut.pcie_tfc_nph_av,
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
# Configuration Management Interface
cfg_mgmt_addr=dut.cfg_mgmt_addr,
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
cfg_mgmt_write=dut.cfg_mgmt_write,
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
cfg_mgmt_read=dut.cfg_mgmt_read,
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
# cfg_mgmt_debug_access
# Configuration Status Interface
# cfg_phy_link_down
# cfg_phy_link_status
# cfg_negotiated_width
# cfg_current_speed
cfg_max_payload=dut.cfg_max_payload,
cfg_max_read_req=dut.cfg_max_read_req,
# cfg_function_status
# cfg_vf_status
# cfg_function_power_state
# cfg_vf_power_state
# cfg_link_power_state
# cfg_err_cor_out
# cfg_err_nonfatal_out
# cfg_err_fatal_out
# cfg_local_error_out
# cfg_local_error_valid
# cfg_rx_pm_state
# cfg_tx_pm_state
# cfg_ltssm_state
# cfg_rcb_status
# cfg_obff_enable
# cfg_pl_status_change
# cfg_tph_requester_enable
# cfg_tph_st_mode
# cfg_vf_tph_requester_enable
# cfg_vf_tph_st_mode
# Configuration Received Message Interface
# cfg_msg_received
# cfg_msg_received_data
# cfg_msg_received_type
# Configuration Transmit Message Interface
# cfg_msg_transmit
# cfg_msg_transmit_type
# cfg_msg_transmit_data
# cfg_msg_transmit_done
# Configuration Flow Control Interface
cfg_fc_ph=dut.cfg_fc_ph,
cfg_fc_pd=dut.cfg_fc_pd,
cfg_fc_nph=dut.cfg_fc_nph,
cfg_fc_npd=dut.cfg_fc_npd,
cfg_fc_cplh=dut.cfg_fc_cplh,
cfg_fc_cpld=dut.cfg_fc_cpld,
cfg_fc_sel=dut.cfg_fc_sel,
# Configuration Control Interface
# cfg_hot_reset_in
# cfg_hot_reset_out
# cfg_config_space_enable
# cfg_dsn
# cfg_bus_number
# cfg_ds_port_number
# cfg_ds_bus_number
# cfg_ds_device_number
# cfg_ds_function_number
# cfg_power_state_change_ack
# cfg_power_state_change_interrupt
cfg_err_cor_in=dut.status_error_cor,
cfg_err_uncor_in=dut.status_error_uncor,
# cfg_flr_in_process
# cfg_flr_done
# cfg_vf_flr_in_process
# cfg_vf_flr_func_num
# cfg_vf_flr_done
# cfg_pm_aspm_l1_entry_reject
# cfg_pm_aspm_tx_l0s_entry_disable
# cfg_req_pm_transition_l23_ready
# cfg_link_training_enable
# Configuration Interrupt Controller Interface
# cfg_interrupt_int
# cfg_interrupt_sent
# cfg_interrupt_pending
cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable,
cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable,
cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update,
cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data,
# cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select,
cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int,
cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status,
cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable,
# cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num,
cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent,
cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail,
# cfg_interrupt_msix_enable
# cfg_interrupt_msix_mask
# cfg_interrupt_msix_vf_enable
# cfg_interrupt_msix_vf_mask
# cfg_interrupt_msix_address
# cfg_interrupt_msix_data
# cfg_interrupt_msix_int
# cfg_interrupt_msix_vec_pending
# cfg_interrupt_msix_vec_pending_status
cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr,
cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present,
cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type,
# cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag,
# cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number,
# Configuration Extend Interface
# cfg_ext_read_received
# cfg_ext_write_received
# cfg_ext_register_number
# cfg_ext_function_number
# cfg_ext_write_data
# cfg_ext_write_byte_enable
# cfg_ext_read_data
# cfg_ext_read_data_valid
)
# self.dev.log.setLevel(logging.DEBUG)
self.rc.make_port().connect(self.dev)
self.driver = mqnic.Driver()
self.dev.functions[0].msi_cap.msi_multiple_message_capable = 5
self.dev.functions[0].configure_bar(0, 2**len(dut.core_inst.core_pcie_inst.axil_ctrl_araddr), ext=True, prefetch=True)
if hasattr(dut.core_inst.core_pcie_inst, 'pcie_app_ctrl'):
self.dev.functions[0].configure_bar(2, 2**len(dut.core_inst.core_pcie_inst.axil_app_ctrl_araddr), ext=True, prefetch=True)
cocotb.start_soon(Clock(dut.ptp_clk, 6.206, units="ns").start())
dut.ptp_rst.setimmediatevalue(0)
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
# Ethernet
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_0, 2.56, units="ns").start())
self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_0, 2.56, units="ns").start())
self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_1, 2.56, units="ns").start())
self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_1, 2.56, units="ns").start())
self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_2, 2.56, units="ns").start())
self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_2, 2.56, units="ns").start())
self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_3, 2.56, units="ns").start())
self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_3, 2.56, units="ns").start())
self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_0, 2.56, units="ns").start())
self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_0, 2.56, units="ns").start())
self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_1, 2.56, units="ns").start())
self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_1, 2.56, units="ns").start())
self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_2, 2.56, units="ns").start())
self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_2, 2.56, units="ns").start())
self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_3, 2.56, units="ns").start())
self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_3, 2.56, units="ns").start())
self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3)
dut.qsfp_0_rx_status_0.setimmediatevalue(1)
dut.qsfp_0_rx_status_1.setimmediatevalue(1)
dut.qsfp_0_rx_status_2.setimmediatevalue(1)
dut.qsfp_0_rx_status_3.setimmediatevalue(1)
dut.qsfp_1_rx_status_0.setimmediatevalue(1)
dut.qsfp_1_rx_status_1.setimmediatevalue(1)
dut.qsfp_1_rx_status_2.setimmediatevalue(1)
dut.qsfp_1_rx_status_3.setimmediatevalue(1)
cocotb.start_soon(Clock(dut.qsfp_0_drp_clk, 8, units="ns").start())
dut.qsfp_0_drp_rst.setimmediatevalue(0)
dut.qsfp_0_drp_do.setimmediatevalue(0)
dut.qsfp_0_drp_rdy.setimmediatevalue(0)
dut.qsfp_0_rx_error_count_0.setimmediatevalue(0)
dut.qsfp_0_rx_error_count_1.setimmediatevalue(0)
dut.qsfp_0_rx_error_count_2.setimmediatevalue(0)
dut.qsfp_0_rx_error_count_3.setimmediatevalue(0)
cocotb.start_soon(Clock(dut.qsfp_1_drp_clk, 8, units="ns").start())
dut.qsfp_1_drp_rst.setimmediatevalue(0)
dut.qsfp_1_drp_do.setimmediatevalue(0)
dut.qsfp_1_drp_rdy.setimmediatevalue(0)
dut.qsfp_1_rx_error_count_0.setimmediatevalue(0)
dut.qsfp_1_rx_error_count_1.setimmediatevalue(0)
dut.qsfp_1_rx_error_count_2.setimmediatevalue(0)
dut.qsfp_1_rx_error_count_3.setimmediatevalue(0)
dut.qsfp_0_modprsl.setimmediatevalue(0)
dut.qsfp_0_intl.setimmediatevalue(1)
dut.qsfp_0_i2c_scl_i.setimmediatevalue(1)
dut.qsfp_0_i2c_sda_i.setimmediatevalue(1)
dut.qsfp_1_modprsl.setimmediatevalue(0)
dut.qsfp_1_intl.setimmediatevalue(1)
dut.qsfp_1_i2c_scl_i.setimmediatevalue(1)
dut.qsfp_1_i2c_sda_i.setimmediatevalue(1)
dut.sma_in.setimmediatevalue(0)
dut.eeprom_i2c_scl_i.setimmediatevalue(1)
dut.eeprom_i2c_sda_i.setimmediatevalue(1)
dut.qspi_dq_i.setimmediatevalue(0)
self.loopback_enable = False
cocotb.start_soon(self._run_loopback())
async def init(self):
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0)
await RisingEdge(self.dut.clk_250mhz)
await RisingEdge(self.dut.clk_250mhz)
self.dut.ptp_rst.setimmediatevalue(1)
self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1)
self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1)
self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1)
self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1)
self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1)
self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1)
self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1)
self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1)
self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1)
self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1)
self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1)
self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1)
self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1)
self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1)
self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1)
self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1)
await FallingEdge(self.dut.rst_250mhz)
await Timer(100, 'ns')
await RisingEdge(self.dut.clk_250mhz)
await RisingEdge(self.dut.clk_250mhz)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0)
await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True)
async def _run_loopback(self):
while True:
await RisingEdge(self.dut.clk_250mhz)
if self.loopback_enable:
if not self.qsfp_0_0_sink.empty():
await self.qsfp_0_0_source.send(await self.qsfp_0_0_sink.recv())
if not self.qsfp_0_1_sink.empty():
await self.qsfp_0_1_source.send(await self.qsfp_0_1_sink.recv())
if not self.qsfp_0_2_sink.empty():
await self.qsfp_0_2_source.send(await self.qsfp_0_2_sink.recv())
if not self.qsfp_0_3_sink.empty():
await self.qsfp_0_3_source.send(await self.qsfp_0_3_sink.recv())
if not self.qsfp_1_0_sink.empty():
await self.qsfp_1_0_source.send(await self.qsfp_1_0_sink.recv())
if not self.qsfp_1_1_sink.empty():
await self.qsfp_1_1_source.send(await self.qsfp_1_1_sink.recv())
if not self.qsfp_1_2_sink.empty():
await self.qsfp_1_2_source.send(await self.qsfp_1_2_sink.recv())
if not self.qsfp_1_3_sink.empty():
await self.qsfp_1_3_source.send(await self.qsfp_1_3_sink.recv())
@cocotb.test()
async def run_test_nic(dut):
tb = TB(dut)
await tb.init()
tb.log.info("Init driver")
await tb.driver.init_pcie_dev(tb.rc, tb.dev.functions[0].pcie_id)
await tb.driver.interfaces[0].open()
# await tb.driver.interfaces[1].open()
# enable queues
tb.log.info("Enable queues")
await tb.driver.interfaces[0].sched_blocks[0].schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001)
for k in range(tb.driver.interfaces[0].tx_queue_count):
await tb.driver.interfaces[0].sched_blocks[0].schedulers[0].hw_regs.write_dword(4*k, 0x00000003)
# wait for all writes to complete
await tb.driver.hw_regs.read_dword(0)
tb.log.info("Init complete")
tb.log.info("Send and receive single packet")
data = bytearray([x % 256 for x in range(1024)])
await tb.driver.interfaces[0].start_xmit(data, 0)
pkt = await tb.qsfp_0_0_sink.recv()
tb.log.info("Packet: %s", pkt)
await tb.qsfp_0_0_source.send(pkt)
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
# await tb.driver.interfaces[1].start_xmit(data, 0)
# pkt = await tb.qsfp_1_0_sink.recv()
# tb.log.info("Packet: %s", pkt)
# await tb.qsfp_1_0_source.send(pkt)
# pkt = await tb.driver.interfaces[1].recv()
# tb.log.info("Packet: %s", pkt)
# assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
tb.log.info("RX and TX checksum tests")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
ip = IP(src='192.168.1.100', dst='192.168.1.101')
udp = UDP(sport=1, dport=2)
test_pkt = eth / ip / udp / payload
test_pkt2 = test_pkt.copy()
test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP]))
await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6)
pkt = await tb.qsfp_0_0_sink.recv()
tb.log.info("Packet: %s", pkt)
await tb.qsfp_0_0_source.send(pkt)
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
assert Ether(pkt.data).build() == test_pkt.build()
tb.log.info("Queue mapping offset test")
data = bytearray([x % 256 for x in range(1024)])
tb.loopback_enable = True
for k in range(4):
await tb.driver.interfaces[0].set_rx_queue_map_offset(0, k)
await tb.driver.interfaces[0].start_xmit(data, 0)
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
assert pkt.queue == k
tb.loopback_enable = False
await tb.driver.interfaces[0].set_rx_queue_map_offset(0, 0)
tb.log.info("Queue mapping RSS mask test")
await tb.driver.interfaces[0].set_rx_queue_map_rss_mask(0, 0x00000003)
tb.loopback_enable = True
queues = set()
for k in range(64):
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
ip = IP(src='192.168.1.100', dst='192.168.1.101')
udp = UDP(sport=1, dport=k+0)
test_pkt = eth / ip / udp / payload
test_pkt2 = test_pkt.copy()
test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP]))
await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6)
for k in range(64):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
queues.add(pkt.queue)
assert len(queues) == 4
tb.loopback_enable = False
await tb.driver.interfaces[0].set_rx_queue_map_rss_mask(0, 0)
tb.log.info("Multiple small packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await tb.driver.interfaces[0].start_xmit(p, 0)
for k in range(count):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.data == pkts[k]
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
tb.loopback_enable = False
tb.log.info("Multiple large packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await tb.driver.interfaces[0].start_xmit(p, 0)
for k in range(count):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.data == pkts[k]
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
tb.loopback_enable = False
await RisingEdge(dut.clk_250mhz)
await RisingEdge(dut.clk_250mhz)
# cocotb-test
tests_dir = os.path.dirname(__file__)
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
app_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'app'))
axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl'))
pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl'))
def test_fpga_core(request):
dut = "fpga_core"
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = dut
verilog_sources = [
os.path.join(rtl_dir, f"{dut}.v"),
os.path.join(rtl_dir, "common", "mqnic_core_pcie_us.v"),
os.path.join(rtl_dir, "common", "mqnic_core_pcie.v"),
os.path.join(rtl_dir, "common", "mqnic_core.v"),
os.path.join(rtl_dir, "common", "mqnic_interface.v"),
os.path.join(rtl_dir, "common", "mqnic_interface_tx.v"),
os.path.join(rtl_dir, "common", "mqnic_interface_rx.v"),
os.path.join(rtl_dir, "common", "mqnic_port.v"),
os.path.join(rtl_dir, "common", "mqnic_port_tx.v"),
os.path.join(rtl_dir, "common", "mqnic_port_rx.v"),
os.path.join(rtl_dir, "common", "mqnic_egress.v"),
os.path.join(rtl_dir, "common", "mqnic_ingress.v"),
os.path.join(rtl_dir, "common", "mqnic_l2_egress.v"),
os.path.join(rtl_dir, "common", "mqnic_l2_ingress.v"),
os.path.join(rtl_dir, "common", "mqnic_rx_queue_map.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp_clock.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp_perout.v"),
os.path.join(rtl_dir, "common", "mqnic_port_map_phy_xgmii.v"),
os.path.join(rtl_dir, "common", "cpl_write.v"),
os.path.join(rtl_dir, "common", "cpl_op_mux.v"),
os.path.join(rtl_dir, "common", "desc_fetch.v"),
os.path.join(rtl_dir, "common", "desc_op_mux.v"),
os.path.join(rtl_dir, "common", "event_mux.v"),
os.path.join(rtl_dir, "common", "queue_manager.v"),
os.path.join(rtl_dir, "common", "cpl_queue_manager.v"),
os.path.join(rtl_dir, "common", "tx_fifo.v"),
os.path.join(rtl_dir, "common", "rx_fifo.v"),
os.path.join(rtl_dir, "common", "tx_req_mux.v"),
os.path.join(rtl_dir, "common", "tx_engine.v"),
os.path.join(rtl_dir, "common", "rx_engine.v"),
os.path.join(rtl_dir, "common", "tx_checksum.v"),
os.path.join(rtl_dir, "common", "rx_hash.v"),
os.path.join(rtl_dir, "common", "rx_checksum.v"),
os.path.join(rtl_dir, "common", "rb_drp.v"),
os.path.join(rtl_dir, "common", "stats_counter.v"),
os.path.join(rtl_dir, "common", "stats_collect.v"),
os.path.join(rtl_dir, "common", "stats_pcie_if.v"),
os.path.join(rtl_dir, "common", "stats_pcie_tlp.v"),
os.path.join(rtl_dir, "common", "stats_dma_if_pcie.v"),
os.path.join(rtl_dir, "common", "stats_dma_latency.v"),
os.path.join(rtl_dir, "common", "mqnic_tx_scheduler_block_rr.v"),
os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"),
os.path.join(rtl_dir, "common", "tdma_scheduler.v"),
os.path.join(rtl_dir, "common", "tdma_ber.v"),
os.path.join(rtl_dir, "common", "tdma_ber_ch.v"),
os.path.join(eth_rtl_dir, "eth_mac_10g.v"),
os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"),
os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"),
os.path.join(eth_rtl_dir, "lfsr.v"),
os.path.join(eth_rtl_dir, "ptp_clock.v"),
os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"),
os.path.join(eth_rtl_dir, "ptp_perout.v"),
os.path.join(axi_rtl_dir, "axil_interconnect.v"),
os.path.join(axi_rtl_dir, "axil_crossbar.v"),
os.path.join(axi_rtl_dir, "axil_crossbar_addr.v"),
os.path.join(axi_rtl_dir, "axil_crossbar_rd.v"),
os.path.join(axi_rtl_dir, "axil_crossbar_wr.v"),
os.path.join(axi_rtl_dir, "axil_reg_if.v"),
os.path.join(axi_rtl_dir, "axil_reg_if_rd.v"),
os.path.join(axi_rtl_dir, "axil_reg_if_wr.v"),
os.path.join(axi_rtl_dir, "axil_register_rd.v"),
os.path.join(axi_rtl_dir, "axil_register_wr.v"),
os.path.join(axi_rtl_dir, "arbiter.v"),
os.path.join(axi_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_adapter.v"),
os.path.join(axis_rtl_dir, "axis_arb_mux.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
os.path.join(axis_rtl_dir, "axis_demux.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_fifo_adapter.v"),
os.path.join(axis_rtl_dir, "axis_pipeline_fifo.v"),
os.path.join(axis_rtl_dir, "axis_register.v"),
os.path.join(pcie_rtl_dir, "pcie_axil_master.v"),
os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"),
os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"),
os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"),
os.path.join(pcie_rtl_dir, "dma_if_pcie.v"),
os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"),
os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"),
os.path.join(pcie_rtl_dir, "dma_if_mux.v"),
os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"),
os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"),
os.path.join(pcie_rtl_dir, "dma_if_desc_mux.v"),
os.path.join(pcie_rtl_dir, "dma_ram_demux_rd.v"),
os.path.join(pcie_rtl_dir, "dma_ram_demux_wr.v"),
os.path.join(pcie_rtl_dir, "dma_psdpram.v"),
os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"),
os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"),
os.path.join(pcie_rtl_dir, "pcie_us_if.v"),
os.path.join(pcie_rtl_dir, "pcie_us_if_rc.v"),
os.path.join(pcie_rtl_dir, "pcie_us_if_rq.v"),
os.path.join(pcie_rtl_dir, "pcie_us_if_cc.v"),
os.path.join(pcie_rtl_dir, "pcie_us_if_cq.v"),
os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"),
os.path.join(pcie_rtl_dir, "pcie_us_msi.v"),
os.path.join(pcie_rtl_dir, "pulse_merge.v"),
]
parameters = {}
# Structural configuration
parameters['IF_COUNT'] = 2
parameters['PORTS_PER_IF'] = 1
parameters['SCHED_PER_IF'] = parameters['PORTS_PER_IF']
parameters['PORT_MASK'] = 0
# PTP configuration
parameters['PTP_CLK_PERIOD_NS_NUM'] = 1024
parameters['PTP_CLK_PERIOD_NS_DENOM'] = 165
parameters['PTP_CLOCK_PIPELINE'] = 0
parameters['PTP_CLOCK_CDC_PIPELINE'] = 0
parameters['PTP_USE_SAMPLE_CLOCK'] = 1
parameters['PTP_PORT_CDC_PIPELINE'] = 0
parameters['PTP_PEROUT_ENABLE'] = 1
parameters['PTP_PEROUT_COUNT'] = 1
# Queue manager configuration
parameters['EVENT_QUEUE_OP_TABLE_SIZE'] = 32
parameters['TX_QUEUE_OP_TABLE_SIZE'] = 32
parameters['RX_QUEUE_OP_TABLE_SIZE'] = 32
parameters['TX_CPL_QUEUE_OP_TABLE_SIZE'] = parameters['TX_QUEUE_OP_TABLE_SIZE']
parameters['RX_CPL_QUEUE_OP_TABLE_SIZE'] = parameters['RX_QUEUE_OP_TABLE_SIZE']
parameters['EVENT_QUEUE_INDEX_WIDTH'] = 5
parameters['TX_QUEUE_INDEX_WIDTH'] = 13
parameters['RX_QUEUE_INDEX_WIDTH'] = 8
parameters['TX_CPL_QUEUE_INDEX_WIDTH'] = parameters['TX_QUEUE_INDEX_WIDTH']
parameters['RX_CPL_QUEUE_INDEX_WIDTH'] = parameters['RX_QUEUE_INDEX_WIDTH']
parameters['EVENT_QUEUE_PIPELINE'] = 3
parameters['TX_QUEUE_PIPELINE'] = 3 + max(parameters['TX_QUEUE_INDEX_WIDTH']-12, 0)
parameters['RX_QUEUE_PIPELINE'] = 3 + max(parameters['RX_QUEUE_INDEX_WIDTH']-12, 0)
parameters['TX_CPL_QUEUE_PIPELINE'] = parameters['TX_QUEUE_PIPELINE']
parameters['RX_CPL_QUEUE_PIPELINE'] = parameters['RX_QUEUE_PIPELINE']
# TX and RX engine configuration
parameters['TX_DESC_TABLE_SIZE'] = 32
parameters['RX_DESC_TABLE_SIZE'] = 32
# Scheduler configuration
parameters['TX_SCHEDULER_OP_TABLE_SIZE'] = parameters['TX_DESC_TABLE_SIZE']
parameters['TX_SCHEDULER_PIPELINE'] = parameters['TX_QUEUE_PIPELINE']
parameters['TDMA_INDEX_WIDTH'] = 6
# Interface configuration
parameters['PTP_TS_ENABLE'] = 1
parameters['TX_CPL_FIFO_DEPTH'] = 32
parameters['TX_CHECKSUM_ENABLE'] = 1
parameters['RX_RSS_ENABLE'] = 1
parameters['RX_HASH_ENABLE'] = 1
parameters['RX_CHECKSUM_ENABLE'] = 1
parameters['TX_FIFO_DEPTH'] = 32768
parameters['RX_FIFO_DEPTH'] = 32768
parameters['MAX_TX_SIZE'] = 9214
parameters['MAX_RX_SIZE'] = 9214
parameters['TX_RAM_SIZE'] = 32768
parameters['RX_RAM_SIZE'] = 32768
# Application block configuration
parameters['APP_ID'] = 0x00000000
parameters['APP_ENABLE'] = 0
parameters['APP_CTRL_ENABLE'] = 1
parameters['APP_DMA_ENABLE'] = 1
parameters['APP_AXIS_DIRECT_ENABLE'] = 1
parameters['APP_AXIS_SYNC_ENABLE'] = 1
parameters['APP_AXIS_IF_ENABLE'] = 1
parameters['APP_STAT_ENABLE'] = 1
# DMA interface configuration
parameters['DMA_IMM_ENABLE'] = 0
parameters['DMA_IMM_WIDTH'] = 32
parameters['DMA_LEN_WIDTH'] = 16
parameters['DMA_TAG_WIDTH'] = 16
parameters['RAM_ADDR_WIDTH'] = (max(parameters['TX_RAM_SIZE'], parameters['RX_RAM_SIZE'])-1).bit_length()
parameters['RAM_PIPELINE'] = 2
# PCIe interface configuration
parameters['AXIS_PCIE_DATA_WIDTH'] = 256
parameters['PF_COUNT'] = 1
parameters['VF_COUNT'] = 0
parameters['PCIE_TAG_COUNT'] = 64
parameters['PCIE_DMA_READ_OP_TABLE_SIZE'] = parameters['PCIE_TAG_COUNT']
parameters['PCIE_DMA_READ_TX_LIMIT'] = 16
parameters['PCIE_DMA_READ_TX_FC_ENABLE'] = 1
parameters['PCIE_DMA_WRITE_OP_TABLE_SIZE'] = 16
parameters['PCIE_DMA_WRITE_TX_LIMIT'] = 3
parameters['PCIE_DMA_WRITE_TX_FC_ENABLE'] = 1
# AXI lite interface configuration (control)
parameters['AXIL_CTRL_DATA_WIDTH'] = 32
parameters['AXIL_CTRL_ADDR_WIDTH'] = 24
# AXI lite interface configuration (application control)
parameters['AXIL_APP_CTRL_DATA_WIDTH'] = parameters['AXIL_CTRL_DATA_WIDTH']
parameters['AXIL_APP_CTRL_ADDR_WIDTH'] = 24
# Ethernet interface configuration
parameters['AXIS_ETH_TX_PIPELINE'] = 0
parameters['AXIS_ETH_TX_FIFO_PIPELINE'] = 2
parameters['AXIS_ETH_TX_TS_PIPELINE'] = 0
parameters['AXIS_ETH_RX_PIPELINE'] = 0
parameters['AXIS_ETH_RX_FIFO_PIPELINE'] = 2
# Statistics counter subsystem
parameters['STAT_ENABLE'] = 1
parameters['STAT_DMA_ENABLE'] = 1
parameters['STAT_PCIE_ENABLE'] = 1
parameters['STAT_INC_WIDTH'] = 24
parameters['STAT_ID_WIDTH'] = 12
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
)

View File

@ -486,6 +486,34 @@ static int mqnic_generic_board_init(struct mqnic_dev *mqnic)
// read MACs from EEPROM
init_mac_list_from_eeprom_base(mqnic, mqnic->eeprom_i2c_client, 0, MQNIC_MAX_IF);
break;
case MQNIC_BOARD_ID_NEXUS_K3P_Q:
request_module("at24");
// I2C adapter
adapter = mqnic_i2c_adapter_create(mqnic, 0);
// QSFP0
mqnic->mod_i2c_client[0] = create_i2c_client(adapter, "24c02", 0x50, NULL);
// I2C adapter
adapter = mqnic_i2c_adapter_create(mqnic, 1);
// QSFP1
mqnic->mod_i2c_client[1] = create_i2c_client(adapter, "24c02", 0x50, NULL);
mqnic->mod_i2c_client_count = 2;
// I2C adapter
adapter = mqnic_i2c_adapter_create(mqnic, 2);
// I2C EEPROM
mqnic->eeprom_i2c_client = create_i2c_client(adapter, "24c02", 0x50, NULL);
// read MACs from EEPROM
init_mac_list_from_eeprom_base(mqnic, mqnic->eeprom_i2c_client, 0, MQNIC_MAX_IF);
break;
case MQNIC_BOARD_ID_DNPCIE_40G_KU:

View File

@ -67,6 +67,7 @@
#define MQNIC_BOARD_ID_FB2CG_KU15P 0x1c2ca00e
#define MQNIC_BOARD_ID_NEXUS_K35_S 0x1ce40003
#define MQNIC_BOARD_ID_NEXUS_K3P_S 0x1ce40009
#define MQNIC_BOARD_ID_NEXUS_K3P_Q 0x1ce4000a
#define MQNIC_BOARD_ID_DNPCIE_40G_KU 0x17df1a00
#define MQNIC_BOARD_ID_ADM_PCIE_9V3 0x41449003