From 1ffbd2d8d35bea01e5ff490574a3b6583f6f4e51 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sat, 16 Apr 2022 12:33:50 -0700 Subject: [PATCH] mqnic/fpga/XUPP3R: Add 10G, 25G, and 100G mqnic designs for BittWare XUP-P3R board Signed-off-by: Alex Forencich --- fpga/mqnic/XUPP3R/fpga_100g/README.md | 23 + fpga/mqnic/XUPP3R/fpga_100g/app | 1 + fpga/mqnic/XUPP3R/fpga_100g/boot.xdc | 4 + fpga/mqnic/XUPP3R/fpga_100g/common/vivado.mk | 126 + fpga/mqnic/XUPP3R/fpga_100g/fpga.xdc | 381 +++ fpga/mqnic/XUPP3R/fpga_100g/fpga/Makefile | 233 ++ fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl | 246 ++ .../XUPP3R/fpga_100g/ip/cmac_usplus_0.tcl | 21 + .../XUPP3R/fpga_100g/ip/cmac_usplus_1.tcl | 21 + .../XUPP3R/fpga_100g/ip/cmac_usplus_2.tcl | 21 + .../XUPP3R/fpga_100g/ip/cmac_usplus_3.tcl | 21 + .../fpga_100g/ip/pcie4_uscale_plus_0.tcl | 22 + fpga/mqnic/XUPP3R/fpga_100g/lib | 1 + fpga/mqnic/XUPP3R/fpga_100g/placement.xdc | 34 + fpga/mqnic/XUPP3R/fpga_100g/rtl/common | 1 + fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v | 2912 +++++++++++++++++ fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v | 1346 ++++++++ fpga/mqnic/XUPP3R/fpga_100g/rtl/sync_signal.v | 62 + .../XUPP3R/fpga_100g/tb/fpga_core/Makefile | 421 +++ .../XUPP3R/fpga_100g/tb/fpga_core/mqnic.py | 1 + .../fpga_100g/tb/fpga_core/test_fpga_core.py | 796 +++++ fpga/mqnic/XUPP3R/fpga_25g/README.md | 22 + fpga/mqnic/XUPP3R/fpga_25g/app | 1 + fpga/mqnic/XUPP3R/fpga_25g/boot.xdc | 4 + fpga/mqnic/XUPP3R/fpga_25g/common/vivado.mk | 126 + fpga/mqnic/XUPP3R/fpga_25g/fpga.xdc | 381 +++ fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile | 252 ++ fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl | 279 ++ .../mqnic/XUPP3R/fpga_25g/ip/eth_xcvr_gty.tcl | 129 + .../fpga_25g/ip/pcie4_uscale_plus_0.tcl | 22 + fpga/mqnic/XUPP3R/fpga_25g/lib | 1 + fpga/mqnic/XUPP3R/fpga_25g/placement.xdc | 32 + fpga/mqnic/XUPP3R/fpga_25g/rtl/common | 1 + fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v | 2346 +++++++++++++ fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v | 1732 ++++++++++ fpga/mqnic/XUPP3R/fpga_25g/rtl/sync_signal.v | 62 + .../XUPP3R/fpga_25g/tb/fpga_core/Makefile | 426 +++ .../XUPP3R/fpga_25g/tb/fpga_core/mqnic.py | 1 + .../fpga_25g/tb/fpga_core/test_fpga_core.py | 927 ++++++ 39 files changed, 13438 insertions(+) create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/README.md create mode 120000 fpga/mqnic/XUPP3R/fpga_100g/app create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/boot.xdc create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/common/vivado.mk create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/fpga.xdc create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/fpga/Makefile create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_0.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_1.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_2.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_3.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/ip/pcie4_uscale_plus_0.tcl create mode 120000 fpga/mqnic/XUPP3R/fpga_100g/lib create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/placement.xdc create mode 120000 fpga/mqnic/XUPP3R/fpga_100g/rtl/common create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/rtl/sync_signal.v create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile create mode 120000 fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/mqnic.py create mode 100644 fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/README.md create mode 120000 fpga/mqnic/XUPP3R/fpga_25g/app create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/boot.xdc create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/common/vivado.mk create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/fpga.xdc create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/ip/eth_xcvr_gty.tcl create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/ip/pcie4_uscale_plus_0.tcl create mode 120000 fpga/mqnic/XUPP3R/fpga_25g/lib create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/placement.xdc create mode 120000 fpga/mqnic/XUPP3R/fpga_25g/rtl/common create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/rtl/sync_signal.v create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile create mode 120000 fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/mqnic.py create mode 100644 fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py diff --git a/fpga/mqnic/XUPP3R/fpga_100g/README.md b/fpga/mqnic/XUPP3R/fpga_100g/README.md new file mode 100644 index 000000000..c00ed56e2 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/README.md @@ -0,0 +1,23 @@ +# Corundum mqnic for XUP-P3R + +## Introduction + +This design targets the BittWare XUP-PR3 FPGA board. + +* FPGA: xcvu9p-flgb2104-2-e +* MAC: Xilinx 100G CMAC +* PHY: 100G CAUI-4 CMAC and internal GTY transceivers + +## 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 XUP-PR3 board with Vivado. Then load the +driver with insmod mqnic.ko. Check dmesg for output from driver +initialization. diff --git a/fpga/mqnic/XUPP3R/fpga_100g/app b/fpga/mqnic/XUPP3R/fpga_100g/app new file mode 120000 index 000000000..4d46690fb --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/app @@ -0,0 +1 @@ +../../../app/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_100g/boot.xdc b/fpga/mqnic/XUPP3R/fpga_100g/boot.xdc new file mode 100644 index 000000000..5fb323e94 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/boot.xdc @@ -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"] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/common/vivado.mk b/fpga/mqnic/XUPP3R/fpga_100g/common/vivado.mk new file mode 100644 index 000000000..df3528189 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/common/vivado.mk @@ -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"; diff --git a/fpga/mqnic/XUPP3R/fpga_100g/fpga.xdc b/fpga/mqnic/XUPP3R/fpga_100g/fpga.xdc new file mode 100644 index 000000000..658274940 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/fpga.xdc @@ -0,0 +1,381 @@ +# XDC constraints for the Xilinx VCU1525 board +# part: xcvu9p-flgb2104-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.CONFIGFALLBACK ENABLE [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [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.UNUSEDPIN PULLUP [current_design] + +# System clocks +# 48 MHz system clock +set_property -dict {LOC AV23 IOSTANDARD LVCMOS18} [get_ports clk_48mhz] +create_clock -period 20.833 -name clk_48mhz [get_ports clk_48mhz] + +# 322.265625 MHz clock from Si5338 B ch 1 +#set_property -dict {LOC AY23 IOSTANDARD DIFF_SSTL18_I} [get_ports clk_b1_p] +#set_property -dict {LOC BA23 IOSTANDARD DIFF_SSTL18_I} [get_ports clk_b1_n] +#create_clock -period 3.103 -name clk_b1 [get_ports clk_b1_p] + +# 322.265625 MHz clock from Si5338 B ch 2 +#set_property -dict {LOC BB9 IOSTANDARD DIFF_SSTL15_DCI ODT RTT_48} [get_ports clk_b2_p] +#set_property -dict {LOC BC9 IOSTANDARD DIFF_SSTL15_DCI ODT RTT_48} [get_ports clk_b2_n] +#create_clock -period 3.103 -name clk_b2 [get_ports clk_b2_p] + +# 100 MHz DDR4 module 1 clock from Si5338 A ch 0 +#set_property -dict {LOC AV18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_1_p] +#set_property -dict {LOC AW18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_1_n] +#create_clock -period 10.000 -name clk_ddr_1 [get_ports clk_ddr_1_p] + +# 100 MHz DDR4 module 2 clock from Si5338 A ch 1 +#set_property -dict {LOC BB36 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_2_p] +#set_property -dict {LOC BC36 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_2_n] +#create_clock -period 10.000 -name clk_ddr_2 [get_ports clk_ddr_2_p] + +# 100 MHz DDR4 module 3 clock from Si5338 A ch 2 +#set_property -dict {LOC E38 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_3_p] +#set_property -dict {LOC D38 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_3_n] +#create_clock -period 10.000 -name clk_ddr_3 [get_ports clk_ddr_3_p] + +# 100 MHz DDR4 module 4 clock from Si5338 A ch 3 +#set_property -dict {LOC K18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_4_p] +#set_property -dict {LOC J18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_4_n] +#create_clock -period 10.000 -name clk_ddr_4 [get_ports clk_ddr_4_p] + +# LEDs +set_property -dict {LOC AR22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AT22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC AV22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[3]}] + +set_false_path -to [get_ports {led[*]}] +set_output_delay 0 [get_ports {led[*]}] + +# Reset +#set_property -dict {LOC IOSTANDARD LVCMOS12} [get_ports reset] + +#set_false_path -from [get_ports {reset}] +#set_input_delay 0 [get_ports {reset}] + +# UART +#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] + +#set_false_path -to [get_ports {uart_txd}] +#set_output_delay 0 [get_ports {uart_txd}] +#set_false_path -from [get_ports {uart_rxd}] +#set_input_delay 0 [get_ports {uart_rxd}] + +# EEPROM I2C interface +set_property -dict {LOC AN24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports eeprom_i2c_scl] +set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [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}] + +# I2C-related signals +set_property -dict {LOC AT24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports fpga_i2c_master_l] +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_ctl_en] + +set_false_path -to [get_ports {fpga_i2c_master_l qsfp_ctl_en}] +set_output_delay 0 [get_ports {fpga_i2c_master_l qsfp_ctl_en}] + +# QSFP28 Interfaces +set_property -dict {LOC BC45} [get_ports qsfp0_rx1_p] ;# MGTYRXP0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BC46} [get_ports qsfp0_rx1_n] ;# MGTYRXN0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BF42} [get_ports qsfp0_tx1_p] ;# MGTYTXP0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BF43} [get_ports qsfp0_tx1_n] ;# MGTYTXN0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA45} [get_ports qsfp0_rx2_p] ;# MGTYRXP1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA46} [get_ports qsfp0_rx2_n] ;# MGTYRXN1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BD42} [get_ports qsfp0_tx2_p] ;# MGTYTXP1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BD43} [get_ports qsfp0_tx2_n] ;# MGTYTXN1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW45} [get_ports qsfp0_rx3_p] ;# MGTYRXP2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW46} [get_ports qsfp0_rx3_n] ;# MGTYRXN2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BB42} [get_ports qsfp0_tx3_p] ;# MGTYTXP2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BB43} [get_ports qsfp0_tx3_n] ;# MGTYTXN2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AV43} [get_ports qsfp0_rx4_p] ;# MGTYRXP3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AV44} [get_ports qsfp0_rx4_n] ;# MGTYRXN3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW40} [get_ports qsfp0_tx4_p] ;# MGTYTXP3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW41} [get_ports qsfp0_tx4_n] ;# MGTYTXN3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA40} [get_ports qsfp0_mgt_refclk_b0_p] ;# MGTREFCLK0P_120 from Si5338 B ch 0 +set_property -dict {LOC BA41} [get_ports qsfp0_mgt_refclk_b0_n] ;# MGTREFCLK0N_120 from Si5338 B ch 0 +#set_property -dict {LOC AY38} [get_ports qsfp0_mgt_refclk_b1_p] ;# MGTREFCLK1P_120 from Si5338 B ch 1 +#set_property -dict {LOC AY39} [get_ports qsfp0_mgt_refclk_b1_n] ;# MGTREFCLK1N_120 from Si5338 B ch 1 +#set_property -dict {LOC AU36} [get_ports qsfp0_mgt_refclk_c0_p] ;# MGTREFCLK0P_121 from Si5338 C ch 0 +#set_property -dict {LOC AU37} [get_ports qsfp0_mgt_refclk_c0_n] ;# MGTREFCLK0N_121 from Si5338 C ch 0 +#set_property -dict {LOC AV38} [get_ports qsfp0_mgt_refclk_c1_p] ;# MGTREFCLK1P_121 from Si5338 C ch 1 +#set_property -dict {LOC AV39} [get_ports qsfp0_mgt_refclk_c1_n] ;# MGTREFCLK1N_121 from Si5338 C ch 1 +set_property -dict {LOC BD24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl] +set_property -dict {LOC BD23 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp0_modprsl] +set_property -dict {LOC BE23 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp0_intl] +set_property -dict {LOC BC24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode] +set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp0_i2c_scl] +set_property -dict {LOC BF23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp0_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_b0 [get_ports qsfp0_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 1) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_b1 [get_ports qsfp0_mgt_refclk_b1_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 0) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_c0 [get_ports qsfp0_mgt_refclk_c0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 1) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_c1 [get_ports qsfp0_mgt_refclk_c1_p] + +set_false_path -to [get_ports {qsfp0_resetl qsfp0_lpmode}] +set_output_delay 0 [get_ports {qsfp0_resetl qsfp0_lpmode}] +set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}] +set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}] + +set_false_path -to [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_output_delay 0 [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_false_path -from [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_input_delay 0 [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] + +set_property -dict {LOC AN45} [get_ports qsfp1_rx1_p] ;# MGTYRXP0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN46} [get_ports qsfp1_rx1_n] ;# MGTYRXN0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN40} [get_ports qsfp1_tx1_p] ;# MGTYTXP0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN41} [get_ports qsfp1_tx1_n] ;# MGTYTXN0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM43} [get_ports qsfp1_rx2_p] ;# MGTYRXP1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM44} [get_ports qsfp1_rx2_n] ;# MGTYRXN1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM38} [get_ports qsfp1_tx2_p] ;# MGTYTXP1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM39} [get_ports qsfp1_tx2_n] ;# MGTYTXN1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL45} [get_ports qsfp1_rx3_p] ;# MGTYRXP2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL46} [get_ports qsfp1_rx3_n] ;# MGTYRXN2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL40} [get_ports qsfp1_tx3_p] ;# MGTYTXP2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL41} [get_ports qsfp1_tx3_n] ;# MGTYTXN2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK43} [get_ports qsfp1_rx4_p] ;# MGTYRXP3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK44} [get_ports qsfp1_rx4_n] ;# MGTYRXN3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK38} [get_ports qsfp1_tx4_p] ;# MGTYTXP3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK39} [get_ports qsfp1_tx4_n] ;# MGTYTXN3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AR36} [get_ports qsfp1_mgt_refclk_b0_p] ;# MGTREFCLK0P_122 from Si5338 B ch 0 +set_property -dict {LOC AR37} [get_ports qsfp1_mgt_refclk_b0_n] ;# MGTREFCLK0N_122 from Si5338 B ch 0 +#set_property -dict {LOC AN36} [get_ports qsfp1_mgt_refclk_b1_p] ;# MGTREFCLK1P_122 from Si5338 B ch 1 +#set_property -dict {LOC AN37} [get_ports qsfp1_mgt_refclk_b1_n] ;# MGTREFCLK1N_122 from Si5338 B ch 1 +#set_property -dict {LOC AL36} [get_ports qsfp1_mgt_refclk_c2_p] ;# MGTREFCLK0P_123 from Si5338 C ch 2 +#set_property -dict {LOC AL37} [get_ports qsfp1_mgt_refclk_c2_n] ;# MGTREFCLK0N_123 from Si5338 C ch 2 +#set_property -dict {LOC AJ36} [get_ports qsfp1_mgt_refclk_c3_p] ;# MGTREFCLK1P_123 from Si5338 C ch 3 +#set_property -dict {LOC AJ37} [get_ports qsfp1_mgt_refclk_c3_n] ;# MGTREFCLK1N_123 from Si5338 C ch 3 +set_property -dict {LOC BE20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl] +set_property -dict {LOC BD21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp1_modprsl] +set_property -dict {LOC BE21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp1_intl] +set_property -dict {LOC BD20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode] +set_property -dict {LOC BE22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp1_i2c_scl] +set_property -dict {LOC BF22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp1_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_b0 [get_ports qsfp1_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 1) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_b1 [get_ports qsfp1_mgt_refclk_b1_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 2) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_c2 [get_ports qsfp1_mgt_refclk_c2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 3) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_c3 [get_ports qsfp1_mgt_refclk_c3_p] + +set_false_path -to [get_ports {qsfp1_resetl qsfp1_lpmode}] +set_output_delay 0 [get_ports {qsfp1_resetl qsfp1_lpmode}] +set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}] +set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}] + +set_false_path -to [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_output_delay 0 [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_false_path -from [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_input_delay 0 [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] + +set_property -dict {LOC AA45} [get_ports qsfp2_rx1_p] ;# MGTYRXP0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA46} [get_ports qsfp2_rx1_n] ;# MGTYRXN0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA40} [get_ports qsfp2_tx1_p] ;# MGTYTXP0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA41} [get_ports qsfp2_tx1_n] ;# MGTYTXN0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y43 } [get_ports qsfp2_rx2_p] ;# MGTYRXP1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y44 } [get_ports qsfp2_rx2_n] ;# MGTYRXN1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y38 } [get_ports qsfp2_tx2_p] ;# MGTYTXP1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y39 } [get_ports qsfp2_tx2_n] ;# MGTYTXN1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W45 } [get_ports qsfp2_rx3_p] ;# MGTYRXP2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W46 } [get_ports qsfp2_rx3_n] ;# MGTYRXN2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W40 } [get_ports qsfp2_tx3_p] ;# MGTYTXP2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W41 } [get_ports qsfp2_tx3_n] ;# MGTYTXN2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V43 } [get_ports qsfp2_rx4_p] ;# MGTYRXP3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V44 } [get_ports qsfp2_rx4_n] ;# MGTYRXN3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V38 } [get_ports qsfp2_tx4_p] ;# MGTYTXP3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V39 } [get_ports qsfp2_tx4_n] ;# MGTYTXN3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AC36} [get_ports qsfp2_mgt_refclk_b0_p] ;# MGTREFCLK0P_125 from Si5338 B ch 0 +set_property -dict {LOC AC37} [get_ports qsfp2_mgt_refclk_b0_n] ;# MGTREFCLK0N_125 from Si5338 B ch 0 +#set_property -dict {LOC AA36} [get_ports qsfp2_mgt_refclk_b2_p] ;# MGTREFCLK1P_125 from Si5338 B ch 2 +#set_property -dict {LOC AA37} [get_ports qsfp2_mgt_refclk_b2_n] ;# MGTREFCLK1N_125 from Si5338 B ch 2 +#set_property -dict {LOC W36 } [get_ports qsfp2_mgt_refclk_d0_p] ;# MGTREFCLK0P_126 from Si5338 D ch 0 +#set_property -dict {LOC W37 } [get_ports qsfp2_mgt_refclk_d0_n] ;# MGTREFCLK0N_126 from Si5338 D ch 0 +#set_property -dict {LOC U36 } [get_ports qsfp2_mgt_refclk_d1_p] ;# MGTREFCLK1P_126 from Si5338 D ch 1 +#set_property -dict {LOC U37 } [get_ports qsfp2_mgt_refclk_d1_n] ;# MGTREFCLK1N_126 from Si5338 D ch 1 +set_property -dict {LOC BB22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp2_resetl] +set_property -dict {LOC BB20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp2_modprsl] +set_property -dict {LOC BB21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp2_intl] +set_property -dict {LOC BC21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp2_lpmode] +set_property -dict {LOC BF20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp2_i2c_scl] +set_property -dict {LOC BA20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp2_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_b0 [get_ports qsfp2_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 2) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_b2 [get_ports qsfp2_mgt_refclk_b2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 0) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_d0 [get_ports qsfp2_mgt_refclk_d0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 1) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_d1 [get_ports qsfp2_mgt_refclk_d1_p] + +set_false_path -to [get_ports {qsfp2_resetl qsfp2_lpmode}] +set_output_delay 0 [get_ports {qsfp2_resetl qsfp2_lpmode}] +set_false_path -from [get_ports {qsfp2_modprsl qsfp2_intl}] +set_input_delay 0 [get_ports {qsfp2_modprsl qsfp2_intl}] + +set_false_path -to [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_output_delay 0 [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_false_path -from [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_input_delay 0 [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] + +set_property -dict {LOC N45 } [get_ports qsfp3_rx1_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N46 } [get_ports qsfp3_rx1_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N40 } [get_ports qsfp3_tx1_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N41 } [get_ports qsfp3_tx1_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M43 } [get_ports qsfp3_rx2_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M44 } [get_ports qsfp3_rx2_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M38 } [get_ports qsfp3_tx2_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M39 } [get_ports qsfp3_tx2_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L45 } [get_ports qsfp3_rx3_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L46 } [get_ports qsfp3_rx3_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L40 } [get_ports qsfp3_tx3_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L41 } [get_ports qsfp3_tx3_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC K43 } [get_ports qsfp3_rx4_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC K44 } [get_ports qsfp3_rx4_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC J40 } [get_ports qsfp3_tx4_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC J41 } [get_ports qsfp3_tx4_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC R36 } [get_ports qsfp3_mgt_refclk_b0_p] ;# MGTREFCLK0P_127 from Si5338 B ch 0 +set_property -dict {LOC R37 } [get_ports qsfp3_mgt_refclk_b0_n] ;# MGTREFCLK0N_127 from Si5338 B ch 0 +#set_property -dict {LOC N36 } [get_ports qsfp3_mgt_refclk_b3_p] ;# MGTREFCLK1P_127 from Si5338 B ch 3 +#set_property -dict {LOC N37 } [get_ports qsfp3_mgt_refclk_b3_n] ;# MGTREFCLK1N_127 from Si5338 B ch 3 +#set_property -dict {LOC L36 } [get_ports qsfp3_mgt_refclk_d2_p] ;# MGTREFCLK0P_128 from Si5338 D ch 2 +#set_property -dict {LOC L37 } [get_ports qsfp3_mgt_refclk_d2_n] ;# MGTREFCLK0N_128 from Si5338 D ch 2 +#set_property -dict {LOC K38 } [get_ports qsfp3_mgt_refclk_d3_p] ;# MGTREFCLK1P_128 from Si5338 D ch 3 +#set_property -dict {LOC K39 } [get_ports qsfp3_mgt_refclk_d3_n] ;# MGTREFCLK1N_128 from Si5338 D ch 3 +set_property -dict {LOC BC23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp3_resetl] +set_property -dict {LOC BB24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp3_modprsl] +set_property -dict {LOC AY22 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp3_intl] +set_property -dict {LOC BA22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp3_lpmode] +set_property -dict {LOC BC22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp3_i2c_scl] +set_property -dict {LOC BA24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp3_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_b0 [get_ports qsfp3_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 2) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_b3 [get_ports qsfp3_mgt_refclk_b3_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 2) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_d2 [get_ports qsfp3_mgt_refclk_d2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 3) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_d3 [get_ports qsfp3_mgt_refclk_d3_p] + +set_false_path -to [get_ports {qsfp3_resetl qsfp3_lpmode}] +set_output_delay 0 [get_ports {qsfp3_resetl qsfp3_lpmode}] +set_false_path -from [get_ports {qsfp3_modprsl qsfp3_intl}] +set_input_delay 0 [get_ports {qsfp3_modprsl qsfp3_intl}] + +set_false_path -to [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_output_delay 0 [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_false_path -from [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_input_delay 0 [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] + +# PCIe Interface +set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AT11 } [get_ports pcie_refclk_0_p] ;# MGTREFCLK0P_225 +set_property -dict {LOC AT10 } [get_ports pcie_refclk_0_n] ;# MGTREFCLK0N_225 +# set_property -dict {LOC AM11 } [get_ports pcie_refclk_b1_p] ;# MGTREFCLK0P_226 from Si5338 B ch 1 +# set_property -dict {LOC AM10 } [get_ports pcie_refclk_b1_n] ;# MGTREFCLK0N_226 from Si5338 B ch 1 +# set_property -dict {LOC AH11 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_227 +# set_property -dict {LOC AH10 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_227 +set_property -dict {LOC AR26 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports pcie_refclk_0_p] + +set_false_path -from [get_ports {pcie_reset_n}] +set_input_delay 0 [get_ports {pcie_reset_n}] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/fpga/Makefile b/fpga/mqnic/XUPP3R/fpga_100g/fpga/Makefile new file mode 100644 index 000000000..4c63545ec --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/fpga/Makefile @@ -0,0 +1,233 @@ + +# FPGA settings +FPGA_PART = xcvu9p-flgb2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# 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_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_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_mac_axis.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/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/cmac_pad.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 += placement.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 + +# IP +IP_TCL_FILES = ip/pcie4_uscale_plus_0.tcl +IP_TCL_FILES += ip/cmac_usplus_0.tcl +IP_TCL_FILES += ip/cmac_usplus_1.tcl +IP_TCL_FILES += ip/cmac_usplus_2.tcl +IP_TCL_FILES += ip/cmac_usplus_3.tcl + +# Configuration +CONFIG_TCL_FILES = ./config.tcl + +include ../common/vivado.mk + +%_fallback.bit: %.bit + echo "open_project $*.xpr" > generate_fallback_bit.tcl + echo "open_run impl_1" >> generate_fallback_bit.tcl + echo "startgroup" >> generate_fallback_bit.tcl + echo "set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]" >> generate_fallback_bit.tcl + echo "endgroup" >> generate_fallback_bit.tcl + echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl + echo "undo" >> generate_fallback_bit.tcl + echo "exit" >> generate_fallback_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT"; + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +%.mcs %.prm: %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +%_fallback.mcs %_fallback.prm: %_fallback.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x0C000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl + echo "exit" >> generate_fallback_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_fallback_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \ + echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done; + +%_full.mcs %_full.prm: %_fallback.bit %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit up 0x0C000000 $*_fallback.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl + echo "exit" >> generate_full_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_full_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*_full$$x rev/$*_full_rev$$COUNT$$x; \ + echo "Output: rev/$*_full_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl + +flash%: $(FPGA_TOP)%.mcs $(FPGA_TOP)%.prm + echo "open_hw" > flash$*.tcl + echo "connect_hw_server" >> flash$*.tcl + echo "open_hw_target" >> flash$*.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash$*.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash$*.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash$*.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash$*.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)$*.prm\"] [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash$*.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash$*.tcl + echo "program_hw_devices [current_hw_device]" >> flash$*.tcl + echo "refresh_hw_device [current_hw_device]" >> flash$*.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash$*.tcl + echo "boot_hw_device [current_hw_device]" >> flash$*.tcl + echo "exit" >> flash$*.tcl + vivado -nojournal -nolog -mode batch -source flash$*.tcl diff --git a/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl b/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl new file mode 100644 index 000000000..0d2f31e80 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl @@ -0,0 +1,246 @@ +# 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 0x4B31093] +set fw_id [expr 0x00000000] +set fw_ver $tag_ver +set board_vendor_id [expr 0x12ba] +set board_device_id [expr 0x9823] +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] + +# Structural configuration +dict set params IF_COUNT "4" +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_PORT_CDC_PIPELINE "0" +dict set params PTP_PEROUT_ENABLE "0" +dict set params PTP_PEROUT_COUNT "1" + +# Queue manager configuration (interface) +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 (port) +dict set params TX_DESC_TABLE_SIZE "32" +dict set params RX_DESC_TABLE_SIZE "32" + +# Scheduler configuration (port) +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" + +# Timestamping configuration (port) +dict set params PTP_TS_ENABLE "1" +dict set params TX_PTP_TS_FIFO_DEPTH "32" +dict set params RX_PTP_TS_FIFO_DEPTH "32" + +# Interface configuration (port) +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 "131072" +dict set params MAX_TX_SIZE "9214" +dict set params MAX_RX_SIZE "9214" +dict set params TX_RAM_SIZE "131072" +dict set params RX_RAM_SIZE "131072" + +# Application block configuration +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_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 "25" + +# 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 "25" + +# Ethernet interface configuration +dict set params AXIS_ETH_TX_PIPELINE "4" +dict set params AXIS_ETH_TX_FIFO_PIPELINE "4" +dict set params AXIS_ETH_TX_TS_PIPELINE "4" +dict set params AXIS_ETH_RX_PIPELINE "4" +dict set params AXIS_ETH_RX_FIFO_PIPELINE "4" + +# 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] + +# 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] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_0.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_0.tcl new file mode 100644 index 000000000..c6903d82b --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_0.tcl @@ -0,0 +1,21 @@ + +create_ip -name cmac_usplus -vendor xilinx.com -library ip -module_name cmac_usplus_0 + +set_property -dict [list \ + CONFIG.CMAC_CAUI4_MODE {1} \ + CONFIG.NUM_LANES {4x25} \ + CONFIG.GT_REF_CLK_FREQ {322.265625} \ + CONFIG.USER_INTERFACE {AXIS} \ + CONFIG.GT_DRP_CLK {125} \ + CONFIG.TX_FLOW_CONTROL {0} \ + CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.INCLUDE_RS_FEC {1} \ + CONFIG.CMAC_CORE_SELECT {CMACE4_X0Y1} \ + CONFIG.GT_GROUP_SELECT {X0Y4~X0Y7} \ + CONFIG.LANE1_GT_LOC {X0Y4} \ + CONFIG.LANE2_GT_LOC {X0Y5} \ + CONFIG.LANE3_GT_LOC {X0Y6} \ + CONFIG.LANE4_GT_LOC {X0Y7} \ + CONFIG.ENABLE_PIPELINE_REG {1} \ + CONFIG.ENABLE_TIME_STAMPING {1} +] [get_ips cmac_usplus_0] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_1.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_1.tcl new file mode 100644 index 000000000..e7610bbfa --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_1.tcl @@ -0,0 +1,21 @@ + +create_ip -name cmac_usplus -vendor xilinx.com -library ip -module_name cmac_usplus_1 + +set_property -dict [list \ + CONFIG.CMAC_CAUI4_MODE {1} \ + CONFIG.NUM_LANES {4x25} \ + CONFIG.GT_REF_CLK_FREQ {322.265625} \ + CONFIG.USER_INTERFACE {AXIS} \ + CONFIG.GT_DRP_CLK {125} \ + CONFIG.TX_FLOW_CONTROL {0} \ + CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.INCLUDE_RS_FEC {1} \ + CONFIG.CMAC_CORE_SELECT {CMACE4_X0Y2} \ + CONFIG.GT_GROUP_SELECT {X0Y12~X0Y15} \ + CONFIG.LANE1_GT_LOC {X0Y12} \ + CONFIG.LANE2_GT_LOC {X0Y13} \ + CONFIG.LANE3_GT_LOC {X0Y14} \ + CONFIG.LANE4_GT_LOC {X0Y15} \ + CONFIG.ENABLE_PIPELINE_REG {1} \ + CONFIG.ENABLE_TIME_STAMPING {1} +] [get_ips cmac_usplus_1] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_2.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_2.tcl new file mode 100644 index 000000000..261ce9d61 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_2.tcl @@ -0,0 +1,21 @@ + +create_ip -name cmac_usplus -vendor xilinx.com -library ip -module_name cmac_usplus_2 + +set_property -dict [list \ + CONFIG.CMAC_CAUI4_MODE {1} \ + CONFIG.NUM_LANES {4x25} \ + CONFIG.GT_REF_CLK_FREQ {322.265625} \ + CONFIG.USER_INTERFACE {AXIS} \ + CONFIG.GT_DRP_CLK {125} \ + CONFIG.TX_FLOW_CONTROL {0} \ + CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.INCLUDE_RS_FEC {1} \ + CONFIG.CMAC_CORE_SELECT {CMACE4_X0Y4} \ + CONFIG.GT_GROUP_SELECT {X0Y24~X0Y27} \ + CONFIG.LANE1_GT_LOC {X0Y24} \ + CONFIG.LANE2_GT_LOC {X0Y25} \ + CONFIG.LANE3_GT_LOC {X0Y26} \ + CONFIG.LANE4_GT_LOC {X0Y27} \ + CONFIG.ENABLE_PIPELINE_REG {1} \ + CONFIG.ENABLE_TIME_STAMPING {1} +] [get_ips cmac_usplus_2] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_3.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_3.tcl new file mode 100644 index 000000000..76463ce3e --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus_3.tcl @@ -0,0 +1,21 @@ + +create_ip -name cmac_usplus -vendor xilinx.com -library ip -module_name cmac_usplus_3 + +set_property -dict [list \ + CONFIG.CMAC_CAUI4_MODE {1} \ + CONFIG.NUM_LANES {4x25} \ + CONFIG.GT_REF_CLK_FREQ {322.265625} \ + CONFIG.USER_INTERFACE {AXIS} \ + CONFIG.GT_DRP_CLK {125} \ + CONFIG.TX_FLOW_CONTROL {0} \ + CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.INCLUDE_RS_FEC {1} \ + CONFIG.CMAC_CORE_SELECT {CMACE4_X0Y5} \ + CONFIG.GT_GROUP_SELECT {X0Y32~X0Y35} \ + CONFIG.LANE1_GT_LOC {X0Y32} \ + CONFIG.LANE2_GT_LOC {X0Y33} \ + CONFIG.LANE3_GT_LOC {X0Y34} \ + CONFIG.LANE4_GT_LOC {X0Y35} \ + CONFIG.ENABLE_PIPELINE_REG {1} \ + CONFIG.ENABLE_TIME_STAMPING {1} +] [get_ips cmac_usplus_3] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/pcie4_uscale_plus_0.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/pcie4_uscale_plus_0.tcl new file mode 100644 index 000000000..92d15de62 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/pcie4_uscale_plus_0.tcl @@ -0,0 +1,22 @@ + +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 {X16} \ + CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \ + CONFIG.axisten_if_enable_client_tag {true} \ + CONFIG.axisten_if_width {512_bit} \ + 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 {9823} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {12ba} \ + 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} \ +] [get_ips pcie4_uscale_plus_0] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/lib b/fpga/mqnic/XUPP3R/fpga_100g/lib new file mode 120000 index 000000000..9512b3d5e --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/lib @@ -0,0 +1 @@ +../../../lib/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_100g/placement.xdc b/fpga/mqnic/XUPP3R/fpga_100g/placement.xdc new file mode 100644 index 000000000..864ac1d26 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/placement.xdc @@ -0,0 +1,34 @@ +# Placement constraints +#create_pblock pblock_slr0 +#add_cells_to_pblock [get_pblocks pblock_slr0] [get_cells -quiet ""] +#resize_pblock [get_pblocks pblock_slr0] -add {SLR0} + +create_pblock pblock_slr1 +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux_inst"] +add_cells_to_pblock -quiet [get_pblocks pblock_slr0] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux.dma_if_mux_ctrl_inst"] +add_cells_to_pblock -quiet [get_pblocks pblock_slr0] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux.dma_if_mux_data_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].interface_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].tx_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].rx_fifo_inst"] +resize_pblock [get_pblocks pblock_slr1] -add {SLR1} + +#create_pblock pblock_slr2 +#add_cells_to_pblock [get_pblocks pblock_slr2] [get_cells -quiet ""] +#resize_pblock [get_pblocks pblock_slr2] -add {SLR2} + +create_pblock pblock_pcie +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "pcie4_uscale_plus_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/pcie_if_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/pcie_axil_master_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/dma_if_pcie_inst"] +resize_pblock [get_pblocks pblock_pcie] -add {CLOCKREGION_X4Y5:CLOCKREGION_X5Y8} + +create_pblock pblock_eth +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "cmac_usplus_0 qsfp0_cmac_pad_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "cmac_usplus_1 qsfp1_cmac_pad_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "cmac_usplus_2 qsfp2_cmac_pad_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "cmac_usplus_3 qsfp3_cmac_pad_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].tx_async_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].rx_async_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].ptp.tx_ptp_ts_fifo_inst"] +resize_pblock [get_pblocks pblock_eth] -add {CLOCKREGION_X0Y1:CLOCKREGION_X0Y9} diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/common b/fpga/mqnic/XUPP3R/fpga_100g/rtl/common new file mode 120000 index 000000000..449c9409c --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/common @@ -0,0 +1 @@ +../../../../common/rtl/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v new file mode 100644 index 000000000..cdd917ce8 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v @@ -0,0 +1,2912 @@ +/* + +Copyright 2019-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. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga # +( + // FW and board IDs + parameter FPGA_ID = 32'h4B31093, + parameter FW_ID = 32'h00000000, + parameter FW_VER = 32'h00_00_01_00, + parameter BOARD_ID = 32'h12ba_9823, + parameter BOARD_VER = 32'h01_00_00_00, + parameter BUILD_DATE = 32'd602976000, + parameter GIT_HASH = 32'hdce357bf, + parameter RELEASE_INFO = 32'h00000000, + + // Structural configuration + parameter IF_COUNT = 2, + parameter PORTS_PER_IF = 1, + parameter SCHED_PER_IF = PORTS_PER_IF, + parameter PORT_MASK = 0, + + // PTP configuration + parameter PTP_CLOCK_PIPELINE = 0, + parameter PTP_PORT_CDC_PIPELINE = 0, + parameter PTP_PEROUT_ENABLE = 0, + parameter PTP_PEROUT_COUNT = 1, + + // Queue manager configuration (interface) + parameter EVENT_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_QUEUE_OP_TABLE_SIZE = 32, + parameter RX_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_CPL_QUEUE_OP_TABLE_SIZE = TX_QUEUE_OP_TABLE_SIZE, + parameter RX_CPL_QUEUE_OP_TABLE_SIZE = RX_QUEUE_OP_TABLE_SIZE, + parameter EVENT_QUEUE_INDEX_WIDTH = 5, + parameter TX_QUEUE_INDEX_WIDTH = 13, + parameter RX_QUEUE_INDEX_WIDTH = 8, + parameter TX_CPL_QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH, + parameter RX_CPL_QUEUE_INDEX_WIDTH = RX_QUEUE_INDEX_WIDTH, + parameter EVENT_QUEUE_PIPELINE = 3, + parameter TX_QUEUE_PIPELINE = 3+(TX_QUEUE_INDEX_WIDTH > 12 ? TX_QUEUE_INDEX_WIDTH-12 : 0), + parameter RX_QUEUE_PIPELINE = 3+(RX_QUEUE_INDEX_WIDTH > 12 ? RX_QUEUE_INDEX_WIDTH-12 : 0), + parameter TX_CPL_QUEUE_PIPELINE = TX_QUEUE_PIPELINE, + parameter RX_CPL_QUEUE_PIPELINE = RX_QUEUE_PIPELINE, + + // TX and RX engine configuration (port) + parameter TX_DESC_TABLE_SIZE = 32, + parameter RX_DESC_TABLE_SIZE = 32, + + // Scheduler configuration (port) + parameter TX_SCHEDULER_OP_TABLE_SIZE = TX_DESC_TABLE_SIZE, + parameter TX_SCHEDULER_PIPELINE = TX_QUEUE_PIPELINE, + parameter TDMA_INDEX_WIDTH = 6, + + // Timestamping configuration (port) + parameter PTP_TS_ENABLE = 1, + parameter TX_PTP_TS_FIFO_DEPTH = 32, + parameter RX_PTP_TS_FIFO_DEPTH = 32, + + // Interface configuration (port) + parameter TX_CHECKSUM_ENABLE = 1, + parameter RX_RSS_ENABLE = 1, + parameter RX_HASH_ENABLE = 1, + parameter RX_CHECKSUM_ENABLE = 1, + parameter TX_FIFO_DEPTH = 32768, + parameter RX_FIFO_DEPTH = 131072, + parameter MAX_TX_SIZE = 9214, + parameter MAX_RX_SIZE = 9214, + parameter TX_RAM_SIZE = 131072, + parameter RX_RAM_SIZE = 131072, + + // Application block configuration + parameter APP_ENABLE = 0, + parameter APP_CTRL_ENABLE = 1, + parameter APP_DMA_ENABLE = 1, + parameter APP_AXIS_DIRECT_ENABLE = 1, + parameter APP_AXIS_SYNC_ENABLE = 1, + parameter APP_AXIS_IF_ENABLE = 1, + parameter APP_STAT_ENABLE = 1, + + // DMA interface configuration + parameter DMA_LEN_WIDTH = 16, + parameter DMA_TAG_WIDTH = 16, + parameter RAM_ADDR_WIDTH = $clog2(TX_RAM_SIZE > RX_RAM_SIZE ? TX_RAM_SIZE : RX_RAM_SIZE), + parameter RAM_PIPELINE = 2, + + // PCIe interface configuration + parameter AXIS_PCIE_DATA_WIDTH = 512, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161, + parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 62 : 137, + parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183, + parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter PF_COUNT = 1, + parameter VF_COUNT = 0, + parameter PCIE_TAG_COUNT = 64, + parameter PCIE_DMA_READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + parameter PCIE_DMA_READ_TX_LIMIT = 16, + parameter PCIE_DMA_READ_TX_FC_ENABLE = 1, + parameter PCIE_DMA_WRITE_OP_TABLE_SIZE = 16, + parameter PCIE_DMA_WRITE_TX_LIMIT = 3, + parameter PCIE_DMA_WRITE_TX_FC_ENABLE = 1, + + // AXI lite interface configuration (control) + parameter AXIL_CTRL_DATA_WIDTH = 32, + parameter AXIL_CTRL_ADDR_WIDTH = 24, + + // AXI lite interface configuration (application control) + parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, + parameter AXIL_APP_CTRL_ADDR_WIDTH = 24, + + // Ethernet interface configuration + parameter AXIS_ETH_TX_PIPELINE = 4, + parameter AXIS_ETH_TX_FIFO_PIPELINE = 4, + parameter AXIS_ETH_TX_TS_PIPELINE = 4, + parameter AXIS_ETH_RX_PIPELINE = 4, + parameter AXIS_ETH_RX_FIFO_PIPELINE = 4, + + // Statistics counter subsystem + parameter STAT_ENABLE = 1, + parameter STAT_DMA_ENABLE = 1, + parameter STAT_PCIE_ENABLE = 1, + parameter STAT_INC_WIDTH = 24, + parameter STAT_ID_WIDTH = 12 +) +( + /* + * Clock: 48MHz LVDS + */ + input wire clk_48mhz, + + /* + * GPIO + */ + output wire [3:0] led, + + /* + * I2C and related signals + */ + inout wire eeprom_i2c_scl, + inout wire eeprom_i2c_sda, + output wire fpga_i2c_master_l, + output wire qsfp_ctl_en, + + /* + * PCI express + */ + input wire [15:0] pcie_rx_p, + input wire [15:0] pcie_rx_n, + output wire [15:0] pcie_tx_p, + output wire [15:0] pcie_tx_n, + input wire pcie_refclk_0_p, + input wire pcie_refclk_0_n, + // input wire pcie_refclk_b1_p, + // input wire pcie_refclk_b1_n, + // input wire pcie_refclk_1_p, + // input wire pcie_refclk_1_n, + input wire pcie_reset_n, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp0_tx1_p, + output wire qsfp0_tx1_n, + input wire qsfp0_rx1_p, + input wire qsfp0_rx1_n, + output wire qsfp0_tx2_p, + output wire qsfp0_tx2_n, + input wire qsfp0_rx2_p, + input wire qsfp0_rx2_n, + output wire qsfp0_tx3_p, + output wire qsfp0_tx3_n, + input wire qsfp0_rx3_p, + input wire qsfp0_rx3_n, + output wire qsfp0_tx4_p, + output wire qsfp0_tx4_n, + input wire qsfp0_rx4_p, + input wire qsfp0_rx4_n, + input wire qsfp0_mgt_refclk_b0_p, + input wire qsfp0_mgt_refclk_b0_n, + // input wire qsfp0_mgt_refclk_b1_p, + // input wire qsfp0_mgt_refclk_b1_n, + // input wire qsfp0_mgt_refclk_c0_p, + // input wire qsfp0_mgt_refclk_c0_n, + // input wire qsfp0_mgt_refclk_c1_p, + // input wire qsfp0_mgt_refclk_c1_n, + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + inout wire qsfp0_i2c_scl, + inout wire qsfp0_i2c_sda, + + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + input wire qsfp1_mgt_refclk_b0_p, + input wire qsfp1_mgt_refclk_b0_n, + // input wire qsfp1_mgt_refclk_b1_p, + // input wire qsfp1_mgt_refclk_b1_n, + // input wire qsfp1_mgt_refclk_c2_p, + // input wire qsfp1_mgt_refclk_c2_n, + // input wire qsfp1_mgt_refclk_c3_p, + // input wire qsfp1_mgt_refclk_c3_n, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + inout wire qsfp1_i2c_scl, + inout wire qsfp1_i2c_sda, + + output wire qsfp2_tx1_p, + output wire qsfp2_tx1_n, + input wire qsfp2_rx1_p, + input wire qsfp2_rx1_n, + output wire qsfp2_tx2_p, + output wire qsfp2_tx2_n, + input wire qsfp2_rx2_p, + input wire qsfp2_rx2_n, + output wire qsfp2_tx3_p, + output wire qsfp2_tx3_n, + input wire qsfp2_rx3_p, + input wire qsfp2_rx3_n, + output wire qsfp2_tx4_p, + output wire qsfp2_tx4_n, + input wire qsfp2_rx4_p, + input wire qsfp2_rx4_n, + input wire qsfp2_mgt_refclk_b0_p, + input wire qsfp2_mgt_refclk_b0_n, + // input wire qsfp2_mgt_refclk_b2_p, + // input wire qsfp2_mgt_refclk_b2_n, + // input wire qsfp2_mgt_refclk_d0_p, + // input wire qsfp2_mgt_refclk_d0_n, + // input wire qsfp2_mgt_refclk_d1_p, + // input wire qsfp2_mgt_refclk_d1_n, + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + inout wire qsfp2_i2c_scl, + inout wire qsfp2_i2c_sda, + + output wire qsfp3_tx1_p, + output wire qsfp3_tx1_n, + input wire qsfp3_rx1_p, + input wire qsfp3_rx1_n, + output wire qsfp3_tx2_p, + output wire qsfp3_tx2_n, + input wire qsfp3_rx2_p, + input wire qsfp3_rx2_n, + output wire qsfp3_tx3_p, + output wire qsfp3_tx3_n, + input wire qsfp3_rx3_p, + input wire qsfp3_rx3_n, + output wire qsfp3_tx4_p, + output wire qsfp3_tx4_n, + input wire qsfp3_rx4_p, + input wire qsfp3_rx4_n, + input wire qsfp3_mgt_refclk_b0_p, + input wire qsfp3_mgt_refclk_b0_n, + // input wire qsfp3_mgt_refclk_b3_p, + // input wire qsfp3_mgt_refclk_b3_n, + // input wire qsfp3_mgt_refclk_d2_p, + // input wire qsfp3_mgt_refclk_d2_n, + // input wire qsfp3_mgt_refclk_d3_p, + // input wire qsfp3_mgt_refclk_d3_n, + output wire qsfp3_resetl, + input wire qsfp3_modprsl, + input wire qsfp3_intl, + output wire qsfp3_lpmode, + inout wire qsfp3_i2c_scl, + inout wire qsfp3_i2c_sda +); + +// PTP configuration +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_WIDTH = 16; +parameter PTP_PERIOD_NS_WIDTH = 4; +parameter PTP_OFFSET_NS_WIDTH = 32; +parameter PTP_FNS_WIDTH = 32; +parameter PTP_PERIOD_NS = 4'd4; +parameter PTP_PERIOD_FNS = 32'd0; +parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter PTP_SEPARATE_RX_CLOCK = 1; + +// PCIe interface configuration +parameter MSI_COUNT = 32; + +// Ethernet interface configuration +parameter AXIS_ETH_DATA_WIDTH = 512; +parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; +parameter AXIS_ETH_SYNC_DATA_WIDTH = AXIS_ETH_DATA_WIDTH; +parameter AXIS_ETH_TX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter AXIS_ETH_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; + +// Clock and reset +wire pcie_user_clk; +wire pcie_user_reset; + +wire cfgmclk_int; + +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst; +wire mmcm_locked; +wire mmcm_clkfb; + +// MMCM instance +// 48 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 125, D = 4 sets Fvco = 1500 MHz +// Divide by 12 to get output frequency of 125 MHz +MMCME4_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(12), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(125), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(4), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(20.833), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_48mhz), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .out(rst_125mhz_int) +); + +// GPIO +assign qsfp_ctl_en = 1'b1; +assign fpga_i2c_master_l = 1'b0; + +wire eeprom_i2c_scl_i; +wire eeprom_i2c_scl_o; +wire eeprom_i2c_scl_t; +wire eeprom_i2c_sda_i; +wire eeprom_i2c_sda_o; +wire eeprom_i2c_sda_t; + +wire qsfp0_modprsl_int; +wire qsfp0_intl_int; +wire qsfp0_i2c_scl_i; +wire qsfp0_i2c_scl_o; +wire qsfp0_i2c_scl_t; +wire qsfp0_i2c_sda_i; +wire qsfp0_i2c_sda_o; +wire qsfp0_i2c_sda_t; + +wire qsfp1_modprsl_int; +wire qsfp1_intl_int; +wire qsfp1_i2c_scl_i; +wire qsfp1_i2c_scl_o; +wire qsfp1_i2c_scl_t; +wire qsfp1_i2c_sda_i; +wire qsfp1_i2c_sda_o; +wire qsfp1_i2c_sda_t; + +wire qsfp2_modprsl_int; +wire qsfp2_intl_int; +wire qsfp2_i2c_scl_i; +wire qsfp2_i2c_scl_o; +wire qsfp2_i2c_scl_t; +wire qsfp2_i2c_sda_i; +wire qsfp2_i2c_sda_o; +wire qsfp2_i2c_sda_t; + +wire qsfp3_modprsl_int; +wire qsfp3_intl_int; +wire qsfp3_i2c_scl_i; +wire qsfp3_i2c_scl_o; +wire qsfp3_i2c_scl_t; +wire qsfp3_i2c_sda_i; +wire qsfp3_i2c_sda_o; +wire qsfp3_i2c_sda_t; + +reg eeprom_i2c_scl_o_reg; +reg eeprom_i2c_scl_t_reg; +reg eeprom_i2c_sda_o_reg; +reg eeprom_i2c_sda_t_reg; + +reg qsfp0_i2c_scl_o_reg; +reg qsfp0_i2c_scl_t_reg; +reg qsfp0_i2c_sda_o_reg; +reg qsfp0_i2c_sda_t_reg; + +reg qsfp1_i2c_scl_o_reg; +reg qsfp1_i2c_scl_t_reg; +reg qsfp1_i2c_sda_o_reg; +reg qsfp1_i2c_sda_t_reg; + +reg qsfp2_i2c_scl_o_reg; +reg qsfp2_i2c_scl_t_reg; +reg qsfp2_i2c_sda_o_reg; +reg qsfp2_i2c_sda_t_reg; + +reg qsfp3_i2c_scl_o_reg; +reg qsfp3_i2c_scl_t_reg; +reg qsfp3_i2c_sda_o_reg; +reg qsfp3_i2c_sda_t_reg; + +always @(posedge pcie_user_clk) begin + eeprom_i2c_scl_o_reg <= eeprom_i2c_scl_o; + eeprom_i2c_scl_t_reg <= eeprom_i2c_scl_t; + eeprom_i2c_sda_o_reg <= eeprom_i2c_sda_o; + eeprom_i2c_sda_t_reg <= eeprom_i2c_sda_t; + + qsfp0_i2c_scl_o_reg <= qsfp0_i2c_scl_o; + qsfp0_i2c_scl_t_reg <= qsfp0_i2c_scl_t; + qsfp0_i2c_sda_o_reg <= qsfp0_i2c_sda_o; + qsfp0_i2c_sda_t_reg <= qsfp0_i2c_sda_t; + + qsfp1_i2c_scl_o_reg <= qsfp1_i2c_scl_o; + qsfp1_i2c_scl_t_reg <= qsfp1_i2c_scl_t; + qsfp1_i2c_sda_o_reg <= qsfp1_i2c_sda_o; + qsfp1_i2c_sda_t_reg <= qsfp1_i2c_sda_t; + + qsfp2_i2c_scl_o_reg <= qsfp2_i2c_scl_o; + qsfp2_i2c_scl_t_reg <= qsfp2_i2c_scl_t; + qsfp2_i2c_sda_o_reg <= qsfp2_i2c_sda_o; + qsfp2_i2c_sda_t_reg <= qsfp2_i2c_sda_t; + + qsfp3_i2c_scl_o_reg <= qsfp3_i2c_scl_o; + qsfp3_i2c_scl_t_reg <= qsfp3_i2c_scl_t; + qsfp3_i2c_sda_o_reg <= qsfp3_i2c_sda_o; + qsfp3_i2c_sda_t_reg <= qsfp3_i2c_sda_t; +end + +sync_signal #( + .WIDTH(18), + .N(2) +) +sync_signal_inst ( + .clk(pcie_user_clk), + .in({eeprom_i2c_scl, eeprom_i2c_sda, + qsfp0_modprsl, qsfp0_intl, qsfp0_i2c_scl, qsfp0_i2c_sda, + qsfp1_modprsl, qsfp1_intl, qsfp1_i2c_scl, qsfp1_i2c_sda, + qsfp2_modprsl, qsfp2_intl, qsfp2_i2c_scl, qsfp2_i2c_sda, + qsfp3_modprsl, qsfp3_intl, qsfp3_i2c_scl, qsfp3_i2c_sda}), + .out({eeprom_i2c_scl_i, eeprom_i2c_sda_i, + qsfp0_modprsl_int, qsfp0_intl_int, qsfp0_i2c_scl_i, qsfp0_i2c_sda_i, + qsfp1_modprsl_int, qsfp1_intl_int, qsfp1_i2c_scl_i, qsfp1_i2c_sda_i, + qsfp2_modprsl_int, qsfp2_intl_int, qsfp2_i2c_scl_i, qsfp2_i2c_sda_i, + qsfp3_modprsl_int, qsfp3_intl_int, qsfp3_i2c_scl_i, qsfp3_i2c_sda_i}) +); + +assign eeprom_i2c_scl = eeprom_i2c_scl_t_reg ? 1'bz : eeprom_i2c_scl_o_reg; +assign eeprom_i2c_sda = eeprom_i2c_sda_t_reg ? 1'bz : eeprom_i2c_sda_o_reg; + +assign qsfp0_i2c_scl = qsfp0_i2c_scl_t_reg ? 1'bz : qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_sda = qsfp0_i2c_sda_t_reg ? 1'bz : qsfp0_i2c_sda_o_reg; + +assign qsfp1_i2c_scl = qsfp1_i2c_scl_t_reg ? 1'bz : qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_sda = qsfp1_i2c_sda_t_reg ? 1'bz : qsfp1_i2c_sda_o_reg; + +assign qsfp2_i2c_scl = qsfp2_i2c_scl_t_reg ? 1'bz : qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_sda = qsfp2_i2c_sda_t_reg ? 1'bz : qsfp2_i2c_sda_o_reg; + +assign qsfp3_i2c_scl = qsfp3_i2c_scl_t_reg ? 1'bz : qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_sda = qsfp3_i2c_sda_t_reg ? 1'bz : qsfp3_i2c_sda_o_reg; + +// Flash +wire qspi_clk_int; +wire [3:0] qspi_dq_int; +wire [3:0] qspi_dq_i_int; +wire [3:0] qspi_dq_o_int; +wire [3:0] qspi_dq_oe_int; +wire qspi_cs_int; + +reg qspi_clk_reg; +reg [3:0] qspi_dq_o_reg; +reg [3:0] qspi_dq_oe_reg; +reg qspi_cs_reg; + +always @(posedge pcie_user_clk) begin + qspi_clk_reg <= qspi_clk_int; + qspi_dq_o_reg <= qspi_dq_o_int; + qspi_dq_oe_reg <= qspi_dq_oe_int; + qspi_cs_reg <= qspi_cs_int; +end + +sync_signal #( + .WIDTH(4), + .N(2) +) +flash_sync_signal_inst ( + .clk(pcie_user_clk), + .in({qspi_dq_int}), + .out({qspi_dq_i_int}) +); + +// startupe3 instance +STARTUPE3 +startupe3_inst ( + .CFGCLK(), + .CFGMCLK(), + .DI(qspi_dq_int), + .DO(qspi_dq_o_reg), + .DTS(~qspi_dq_oe_reg), + .EOS(), + .FCSBO(qspi_cs_reg), + .FCSBTS(1'b0), + .GSR(1'b0), + .GTS(1'b0), + .KEYCLEARB(1'b1), + .PACK(1'b0), + .PREQ(), + .USRCCLKO(qspi_clk_reg), + .USRCCLKTS(1'b0), + .USRDONEO(1'b0), + .USRDONETS(1'b1) +); + +// FPGA boot +wire fpga_boot; + +reg fpga_boot_sync_reg_0 = 1'b0; +reg fpga_boot_sync_reg_1 = 1'b0; +reg fpga_boot_sync_reg_2 = 1'b0; + +wire icap_avail; +reg [2:0] icap_state = 0; +reg icap_csib_reg = 1'b1; +reg icap_rdwrb_reg = 1'b0; +reg [31:0] icap_di_reg = 32'hffffffff; + +wire [31:0] icap_di_rev; + +assign icap_di_rev[ 7] = icap_di_reg[ 0]; +assign icap_di_rev[ 6] = icap_di_reg[ 1]; +assign icap_di_rev[ 5] = icap_di_reg[ 2]; +assign icap_di_rev[ 4] = icap_di_reg[ 3]; +assign icap_di_rev[ 3] = icap_di_reg[ 4]; +assign icap_di_rev[ 2] = icap_di_reg[ 5]; +assign icap_di_rev[ 1] = icap_di_reg[ 6]; +assign icap_di_rev[ 0] = icap_di_reg[ 7]; + +assign icap_di_rev[15] = icap_di_reg[ 8]; +assign icap_di_rev[14] = icap_di_reg[ 9]; +assign icap_di_rev[13] = icap_di_reg[10]; +assign icap_di_rev[12] = icap_di_reg[11]; +assign icap_di_rev[11] = icap_di_reg[12]; +assign icap_di_rev[10] = icap_di_reg[13]; +assign icap_di_rev[ 9] = icap_di_reg[14]; +assign icap_di_rev[ 8] = icap_di_reg[15]; + +assign icap_di_rev[23] = icap_di_reg[16]; +assign icap_di_rev[22] = icap_di_reg[17]; +assign icap_di_rev[21] = icap_di_reg[18]; +assign icap_di_rev[20] = icap_di_reg[19]; +assign icap_di_rev[19] = icap_di_reg[20]; +assign icap_di_rev[18] = icap_di_reg[21]; +assign icap_di_rev[17] = icap_di_reg[22]; +assign icap_di_rev[16] = icap_di_reg[23]; + +assign icap_di_rev[31] = icap_di_reg[24]; +assign icap_di_rev[30] = icap_di_reg[25]; +assign icap_di_rev[29] = icap_di_reg[26]; +assign icap_di_rev[28] = icap_di_reg[27]; +assign icap_di_rev[27] = icap_di_reg[28]; +assign icap_di_rev[26] = icap_di_reg[29]; +assign icap_di_rev[25] = icap_di_reg[30]; +assign icap_di_rev[24] = icap_di_reg[31]; + +always @(posedge clk_125mhz_int) begin + case (icap_state) + 0: begin + icap_state <= 0; + icap_csib_reg <= 1'b1; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + + if (fpga_boot_sync_reg_2 && icap_avail) begin + icap_state <= 1; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + end + end + 1: begin + icap_state <= 2; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hAA995566; // sync word + end + 2: begin + icap_state <= 3; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + 3: begin + icap_state <= 4; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h30008001; // write 1 word to CMD + end + 4: begin + icap_state <= 5; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h0000000F; // IPROG + end + 5: begin + icap_state <= 0; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + endcase + + fpga_boot_sync_reg_0 <= fpga_boot; + fpga_boot_sync_reg_1 <= fpga_boot_sync_reg_0; + fpga_boot_sync_reg_2 <= fpga_boot_sync_reg_1; +end + +ICAPE3 +icape3_inst ( + .AVAIL(icap_avail), + .CLK(clk_125mhz_int), + .CSIB(icap_csib_reg), + .I(icap_di_rev), + .O(), + .PRDONE(), + .PRERROR(), + .RDWRB(icap_rdwrb_reg) +); + +// PCIe +wire pcie_sys_clk; +wire pcie_sys_clk_gt; + +IBUFDS_GTE4 #( + .REFCLK_HROW_CK_SEL(2'b00) +) +ibufds_gte4_pcie_mgt_refclk_inst ( + .I (pcie_refclk_0_p), + .IB (pcie_refclk_0_n), + .CEB (1'b0), + .O (pcie_sys_clk_gt), + .ODIV2 (pcie_sys_clk) +); + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rq_tkeep; +wire axis_rq_tlast; +wire axis_rq_tready; +wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] axis_rq_tuser; +wire axis_rq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rc_tkeep; +wire axis_rc_tlast; +wire axis_rc_tready; +wire [AXIS_PCIE_RC_USER_WIDTH-1:0] axis_rc_tuser; +wire axis_rc_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cq_tkeep; +wire axis_cq_tlast; +wire axis_cq_tready; +wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] axis_cq_tuser; +wire axis_cq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cc_tkeep; +wire axis_cc_tlast; +wire axis_cc_tready; +wire [AXIS_PCIE_CC_USER_WIDTH-1:0] axis_cc_tuser; +wire axis_cc_tvalid; + +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num0; +wire pcie_rq_seq_num_vld0; +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num1; +wire pcie_rq_seq_num_vld1; + +wire [3:0] pcie_tfc_nph_av; +wire [3:0] pcie_tfc_npd_av; + +wire [2:0] cfg_max_payload; +wire [2:0] cfg_max_read_req; + +wire [9:0] cfg_mgmt_addr; +wire [7:0] cfg_mgmt_function_number; +wire cfg_mgmt_write; +wire [31:0] cfg_mgmt_write_data; +wire [3:0] cfg_mgmt_byte_enable; +wire cfg_mgmt_read; +wire [31:0] cfg_mgmt_read_data; +wire cfg_mgmt_read_write_done; + +wire [7:0] cfg_fc_ph; +wire [11:0] cfg_fc_pd; +wire [7:0] cfg_fc_nph; +wire [11:0] cfg_fc_npd; +wire [7:0] cfg_fc_cplh; +wire [11:0] cfg_fc_cpld; +wire [2:0] cfg_fc_sel; + +wire [3:0] cfg_interrupt_msi_enable; +wire [11:0] cfg_interrupt_msi_mmenable; +wire cfg_interrupt_msi_mask_update; +wire [31:0] cfg_interrupt_msi_data; +wire [3:0] cfg_interrupt_msi_select; +wire [31:0] cfg_interrupt_msi_int; +wire [31:0] cfg_interrupt_msi_pending_status; +wire cfg_interrupt_msi_pending_status_data_enable; +wire [3:0] cfg_interrupt_msi_pending_status_function_num; +wire cfg_interrupt_msi_sent; +wire cfg_interrupt_msi_fail; +wire [2:0] cfg_interrupt_msi_attr; +wire cfg_interrupt_msi_tph_present; +wire [1:0] cfg_interrupt_msi_tph_type; +wire [8:0] cfg_interrupt_msi_tph_st_tag; +wire [3:0] cfg_interrupt_msi_function_number; + +wire status_error_cor; +wire status_error_uncor; + +// extra register for pcie_user_reset signal +wire pcie_user_reset_int; +(* shreg_extract = "no" *) +reg pcie_user_reset_reg_1 = 1'b1; +(* shreg_extract = "no" *) +reg pcie_user_reset_reg_2 = 1'b1; + +always @(posedge pcie_user_clk) begin + pcie_user_reset_reg_1 <= pcie_user_reset_int; + pcie_user_reset_reg_2 <= pcie_user_reset_reg_1; +end + +BUFG +pcie_user_reset_bufg_inst ( + .I(pcie_user_reset_reg_2), + .O(pcie_user_reset) +); + +pcie4_uscale_plus_0 +pcie4_uscale_plus_inst ( + .pci_exp_txn(pcie_tx_n), + .pci_exp_txp(pcie_tx_p), + .pci_exp_rxn(pcie_rx_n), + .pci_exp_rxp(pcie_rx_p), + .user_clk(pcie_user_clk), + .user_reset(pcie_user_reset_int), + .user_lnk_up(), + + .s_axis_rq_tdata(axis_rq_tdata), + .s_axis_rq_tkeep(axis_rq_tkeep), + .s_axis_rq_tlast(axis_rq_tlast), + .s_axis_rq_tready(axis_rq_tready), + .s_axis_rq_tuser(axis_rq_tuser), + .s_axis_rq_tvalid(axis_rq_tvalid), + + .m_axis_rc_tdata(axis_rc_tdata), + .m_axis_rc_tkeep(axis_rc_tkeep), + .m_axis_rc_tlast(axis_rc_tlast), + .m_axis_rc_tready(axis_rc_tready), + .m_axis_rc_tuser(axis_rc_tuser), + .m_axis_rc_tvalid(axis_rc_tvalid), + + .m_axis_cq_tdata(axis_cq_tdata), + .m_axis_cq_tkeep(axis_cq_tkeep), + .m_axis_cq_tlast(axis_cq_tlast), + .m_axis_cq_tready(axis_cq_tready), + .m_axis_cq_tuser(axis_cq_tuser), + .m_axis_cq_tvalid(axis_cq_tvalid), + + .s_axis_cc_tdata(axis_cc_tdata), + .s_axis_cc_tkeep(axis_cc_tkeep), + .s_axis_cc_tlast(axis_cc_tlast), + .s_axis_cc_tready(axis_cc_tready), + .s_axis_cc_tuser(axis_cc_tuser), + .s_axis_cc_tvalid(axis_cc_tvalid), + + .pcie_rq_seq_num0(pcie_rq_seq_num0), + .pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0), + .pcie_rq_seq_num1(pcie_rq_seq_num1), + .pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1), + .pcie_rq_tag0(), + .pcie_rq_tag1(), + .pcie_rq_tag_av(), + .pcie_rq_tag_vld0(), + .pcie_rq_tag_vld1(), + + .pcie_tfc_nph_av(pcie_tfc_nph_av), + .pcie_tfc_npd_av(pcie_tfc_npd_av), + + .pcie_cq_np_req(1'b1), + .pcie_cq_np_req_count(), + + .cfg_phy_link_down(), + .cfg_phy_link_status(), + .cfg_negotiated_width(), + .cfg_current_speed(), + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_function_status(), + .cfg_function_power_state(), + .cfg_vf_status(), + .cfg_vf_power_state(), + .cfg_link_power_state(), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + .cfg_mgmt_debug_access(1'b0), + + .cfg_err_cor_out(), + .cfg_err_nonfatal_out(), + .cfg_err_fatal_out(), + .cfg_local_error_valid(), + .cfg_local_error_out(), + .cfg_ltssm_state(), + .cfg_rx_pm_state(), + .cfg_tx_pm_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(), + + .cfg_msg_received(), + .cfg_msg_received_data(), + .cfg_msg_received_type(), + .cfg_msg_transmit(1'b0), + .cfg_msg_transmit_type(3'd0), + .cfg_msg_transmit_data(32'd0), + .cfg_msg_transmit_done(), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_dsn(64'd0), + + .cfg_power_state_change_ack(1'b1), + .cfg_power_state_change_interrupt(), + + .cfg_err_cor_in(status_error_cor), + .cfg_err_uncor_in(status_error_uncor), + .cfg_flr_in_process(), + .cfg_flr_done(4'd0), + .cfg_vf_flr_in_process(), + .cfg_vf_flr_func_num(8'd0), + .cfg_vf_flr_done(8'd0), + + .cfg_link_training_enable(1'b1), + + .cfg_interrupt_int(4'd0), + .cfg_interrupt_pending(4'd0), + .cfg_interrupt_sent(), + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_pm_aspm_l1_entry_reject(1'b0), + .cfg_pm_aspm_tx_l0s_entry_disable(1'b0), + + .cfg_hot_reset_out(), + + .cfg_config_space_enable(1'b1), + .cfg_req_pm_transition_l23_ready(1'b0), + .cfg_hot_reset_in(1'b0), + + .cfg_ds_port_number(8'd0), + .cfg_ds_bus_number(8'd0), + .cfg_ds_device_number(5'd0), + //.cfg_ds_function_number(3'd0), + + //.cfg_subsys_vend_id(16'h1234), + + .sys_clk(pcie_sys_clk), + .sys_clk_gt(pcie_sys_clk_gt), + .sys_reset(pcie_reset_n), + + .phy_rdy_out() +); + +// QSFP0 CMAC +wire qsfp0_tx_clk_int; +wire qsfp0_tx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep_int; +wire qsfp0_tx_axis_tvalid_int; +wire qsfp0_tx_axis_tready_int; +wire qsfp0_tx_axis_tlast_int; +wire [16+1-1:0] qsfp0_tx_axis_tuser_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_mac_tx_axis_tdata; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_mac_tx_axis_tkeep; +wire qsfp0_mac_tx_axis_tvalid; +wire qsfp0_mac_tx_axis_tready; +wire qsfp0_mac_tx_axis_tlast; +wire [16+1-1:0] qsfp0_mac_tx_axis_tuser; + +wire [79:0] qsfp0_tx_ptp_time_int; +wire [79:0] qsfp0_tx_ptp_ts_int; +wire [15:0] qsfp0_tx_ptp_ts_tag_int; +wire qsfp0_tx_ptp_ts_valid_int; + +wire qsfp0_rx_clk_int; +wire qsfp0_rx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep_int; +wire qsfp0_rx_axis_tvalid_int; +wire qsfp0_rx_axis_tlast_int; +wire [80+1-1:0] qsfp0_rx_axis_tuser_int; + +wire qsfp0_rx_ptp_clk_int; +wire qsfp0_rx_ptp_rst_int; +wire [79:0] qsfp0_rx_ptp_time_int; + +wire qsfp0_rx_status; + +wire qsfp0_txuserclk2; +wire qsfp0_rxuserclk2; + +assign qsfp0_tx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_clk_int = qsfp0_txuserclk2; +assign qsfp0_rx_ptp_clk_int = qsfp0_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp0_rx_ptp_rst_inst ( + .clk(qsfp0_rx_ptp_clk_int), + .rst(qsfp0_tx_rst_int), + .out(qsfp0_rx_ptp_rst_int) +); + +cmac_pad #( + .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .USER_WIDTH(16+1) +) +qsfp0_cmac_pad_inst ( + .clk(qsfp0_tx_clk_int), + .rst(qsfp0_tx_rst_int), + + .s_axis_tdata(qsfp0_tx_axis_tdata_int), + .s_axis_tkeep(qsfp0_tx_axis_tkeep_int), + .s_axis_tvalid(qsfp0_tx_axis_tvalid_int), + .s_axis_tready(qsfp0_tx_axis_tready_int), + .s_axis_tlast(qsfp0_tx_axis_tlast_int), + .s_axis_tuser(qsfp0_tx_axis_tuser_int), + + .m_axis_tdata(qsfp0_mac_tx_axis_tdata), + .m_axis_tkeep(qsfp0_mac_tx_axis_tkeep), + .m_axis_tvalid(qsfp0_mac_tx_axis_tvalid), + .m_axis_tready(qsfp0_mac_tx_axis_tready), + .m_axis_tlast(qsfp0_mac_tx_axis_tlast), + .m_axis_tuser(qsfp0_mac_tx_axis_tuser) +); + +cmac_usplus_0 +qsfp0_cmac_inst ( + .gt_rxp_in({qsfp0_rx4_p, qsfp0_rx3_p, qsfp0_rx2_p, qsfp0_rx1_p}), // input + .gt_rxn_in({qsfp0_rx4_n, qsfp0_rx3_n, qsfp0_rx2_n, qsfp0_rx1_n}), // input + .gt_txp_out({qsfp0_tx4_p, qsfp0_tx3_p, qsfp0_tx2_p, qsfp0_tx1_p}), // output + .gt_txn_out({qsfp0_tx4_n, qsfp0_tx3_n, qsfp0_tx2_n, qsfp0_tx1_n}), // output + .gt_txusrclk2(qsfp0_txuserclk2), // output + .gt_loopback_in(12'd0), // input [11:0] + .gt_rxrecclkout(), // output [3:0] + .gt_powergoodout(), // output [3:0] + .gt_ref_clk_out(), // output + .gtwiz_reset_tx_datapath(1'b0), // input + .gtwiz_reset_rx_datapath(1'b0), // input + .sys_reset(rst_125mhz_int), // input + .gt_ref_clk_p(qsfp0_mgt_refclk_b0_p), // input + .gt_ref_clk_n(qsfp0_mgt_refclk_b0_n), // input + .init_clk(clk_125mhz_int), // input + + .rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), // output + .rx_axis_tdata(qsfp0_rx_axis_tdata_int), // output [511:0] + .rx_axis_tlast(qsfp0_rx_axis_tlast_int), // output + .rx_axis_tkeep(qsfp0_rx_axis_tkeep_int), // output [63:0] + .rx_axis_tuser(qsfp0_rx_axis_tuser_int[0]), // output + + .rx_otn_bip8_0(), // output [7:0] + .rx_otn_bip8_1(), // output [7:0] + .rx_otn_bip8_2(), // output [7:0] + .rx_otn_bip8_3(), // output [7:0] + .rx_otn_bip8_4(), // output [7:0] + .rx_otn_data_0(), // output [65:0] + .rx_otn_data_1(), // output [65:0] + .rx_otn_data_2(), // output [65:0] + .rx_otn_data_3(), // output [65:0] + .rx_otn_data_4(), // output [65:0] + .rx_otn_ena(), // output + .rx_otn_lane0(), // output + .rx_otn_vlmarker(), // output + .rx_preambleout(), // output [55:0] + .usr_rx_reset(qsfp0_rx_rst_int), // output + .gt_rxusrclk2(qsfp0_rxuserclk2), // output + + .rx_lane_aligner_fill_0(), // output [6:0] + .rx_lane_aligner_fill_1(), // output [6:0] + .rx_lane_aligner_fill_10(), // output [6:0] + .rx_lane_aligner_fill_11(), // output [6:0] + .rx_lane_aligner_fill_12(), // output [6:0] + .rx_lane_aligner_fill_13(), // output [6:0] + .rx_lane_aligner_fill_14(), // output [6:0] + .rx_lane_aligner_fill_15(), // output [6:0] + .rx_lane_aligner_fill_16(), // output [6:0] + .rx_lane_aligner_fill_17(), // output [6:0] + .rx_lane_aligner_fill_18(), // output [6:0] + .rx_lane_aligner_fill_19(), // output [6:0] + .rx_lane_aligner_fill_2(), // output [6:0] + .rx_lane_aligner_fill_3(), // output [6:0] + .rx_lane_aligner_fill_4(), // output [6:0] + .rx_lane_aligner_fill_5(), // output [6:0] + .rx_lane_aligner_fill_6(), // output [6:0] + .rx_lane_aligner_fill_7(), // output [6:0] + .rx_lane_aligner_fill_8(), // output [6:0] + .rx_lane_aligner_fill_9(), // output [6:0] + .rx_ptp_tstamp_out(qsfp0_rx_axis_tuser_int[80:1]), // output [79:0] + .rx_ptp_pcslane_out(), // output [4:0] + .ctl_rx_systemtimerin(qsfp0_rx_ptp_time_int), // input [79:0] + + .stat_rx_aligned(), // output + .stat_rx_aligned_err(), // output + .stat_rx_bad_code(), // output [2:0] + .stat_rx_bad_fcs(), // output [2:0] + .stat_rx_bad_preamble(), // output + .stat_rx_bad_sfd(), // output + .stat_rx_bip_err_0(), // output + .stat_rx_bip_err_1(), // output + .stat_rx_bip_err_10(), // output + .stat_rx_bip_err_11(), // output + .stat_rx_bip_err_12(), // output + .stat_rx_bip_err_13(), // output + .stat_rx_bip_err_14(), // output + .stat_rx_bip_err_15(), // output + .stat_rx_bip_err_16(), // output + .stat_rx_bip_err_17(), // output + .stat_rx_bip_err_18(), // output + .stat_rx_bip_err_19(), // output + .stat_rx_bip_err_2(), // output + .stat_rx_bip_err_3(), // output + .stat_rx_bip_err_4(), // output + .stat_rx_bip_err_5(), // output + .stat_rx_bip_err_6(), // output + .stat_rx_bip_err_7(), // output + .stat_rx_bip_err_8(), // output + .stat_rx_bip_err_9(), // output + .stat_rx_block_lock(), // output [19:0] + .stat_rx_broadcast(), // output + .stat_rx_fragment(), // output [2:0] + .stat_rx_framing_err_0(), // output [1:0] + .stat_rx_framing_err_1(), // output [1:0] + .stat_rx_framing_err_10(), // output [1:0] + .stat_rx_framing_err_11(), // output [1:0] + .stat_rx_framing_err_12(), // output [1:0] + .stat_rx_framing_err_13(), // output [1:0] + .stat_rx_framing_err_14(), // output [1:0] + .stat_rx_framing_err_15(), // output [1:0] + .stat_rx_framing_err_16(), // output [1:0] + .stat_rx_framing_err_17(), // output [1:0] + .stat_rx_framing_err_18(), // output [1:0] + .stat_rx_framing_err_19(), // output [1:0] + .stat_rx_framing_err_2(), // output [1:0] + .stat_rx_framing_err_3(), // output [1:0] + .stat_rx_framing_err_4(), // output [1:0] + .stat_rx_framing_err_5(), // output [1:0] + .stat_rx_framing_err_6(), // output [1:0] + .stat_rx_framing_err_7(), // output [1:0] + .stat_rx_framing_err_8(), // output [1:0] + .stat_rx_framing_err_9(), // output [1:0] + .stat_rx_framing_err_valid_0(), // output + .stat_rx_framing_err_valid_1(), // output + .stat_rx_framing_err_valid_10(), // output + .stat_rx_framing_err_valid_11(), // output + .stat_rx_framing_err_valid_12(), // output + .stat_rx_framing_err_valid_13(), // output + .stat_rx_framing_err_valid_14(), // output + .stat_rx_framing_err_valid_15(), // output + .stat_rx_framing_err_valid_16(), // output + .stat_rx_framing_err_valid_17(), // output + .stat_rx_framing_err_valid_18(), // output + .stat_rx_framing_err_valid_19(), // output + .stat_rx_framing_err_valid_2(), // output + .stat_rx_framing_err_valid_3(), // output + .stat_rx_framing_err_valid_4(), // output + .stat_rx_framing_err_valid_5(), // output + .stat_rx_framing_err_valid_6(), // output + .stat_rx_framing_err_valid_7(), // output + .stat_rx_framing_err_valid_8(), // output + .stat_rx_framing_err_valid_9(), // output + .stat_rx_got_signal_os(), // output + .stat_rx_hi_ber(), // output + .stat_rx_inrangeerr(), // output + .stat_rx_internal_local_fault(), // output + .stat_rx_jabber(), // output + .stat_rx_local_fault(), // output + .stat_rx_mf_err(), // output [19:0] + .stat_rx_mf_len_err(), // output [19:0] + .stat_rx_mf_repeat_err(), // output [19:0] + .stat_rx_misaligned(), // output + .stat_rx_multicast(), // output + .stat_rx_oversize(), // output + .stat_rx_packet_1024_1518_bytes(), // output + .stat_rx_packet_128_255_bytes(), // output + .stat_rx_packet_1519_1522_bytes(), // output + .stat_rx_packet_1523_1548_bytes(), // output + .stat_rx_packet_1549_2047_bytes(), // output + .stat_rx_packet_2048_4095_bytes(), // output + .stat_rx_packet_256_511_bytes(), // output + .stat_rx_packet_4096_8191_bytes(), // output + .stat_rx_packet_512_1023_bytes(), // output + .stat_rx_packet_64_bytes(), // output + .stat_rx_packet_65_127_bytes(), // output + .stat_rx_packet_8192_9215_bytes(), // output + .stat_rx_packet_bad_fcs(), // output + .stat_rx_packet_large(), // output + .stat_rx_packet_small(), // output [2:0] + + .ctl_rx_enable(1'b1), // input + .ctl_rx_force_resync(1'b0), // input + .ctl_rx_test_pattern(1'b0), // input + .ctl_rsfec_ieee_error_indication_mode(1'b0), // input + .ctl_rx_rsfec_enable(1'b1), // input + .ctl_rx_rsfec_enable_correction(1'b1), // input + .ctl_rx_rsfec_enable_indication(1'b1), // input + .core_rx_reset(1'b0), // input + .rx_clk(qsfp0_rx_clk_int), // input + + .stat_rx_received_local_fault(), // output + .stat_rx_remote_fault(), // output + .stat_rx_status(qsfp0_rx_status), // output + .stat_rx_stomped_fcs(), // output [2:0] + .stat_rx_synced(), // output [19:0] + .stat_rx_synced_err(), // output [19:0] + .stat_rx_test_pattern_mismatch(), // output [2:0] + .stat_rx_toolong(), // output + .stat_rx_total_bytes(), // output [6:0] + .stat_rx_total_good_bytes(), // output [13:0] + .stat_rx_total_good_packets(), // output + .stat_rx_total_packets(), // output [2:0] + .stat_rx_truncated(), // output + .stat_rx_undersize(), // output [2:0] + .stat_rx_unicast(), // output + .stat_rx_vlan(), // output + .stat_rx_pcsl_demuxed(), // output [19:0] + .stat_rx_pcsl_number_0(), // output [4:0] + .stat_rx_pcsl_number_1(), // output [4:0] + .stat_rx_pcsl_number_10(), // output [4:0] + .stat_rx_pcsl_number_11(), // output [4:0] + .stat_rx_pcsl_number_12(), // output [4:0] + .stat_rx_pcsl_number_13(), // output [4:0] + .stat_rx_pcsl_number_14(), // output [4:0] + .stat_rx_pcsl_number_15(), // output [4:0] + .stat_rx_pcsl_number_16(), // output [4:0] + .stat_rx_pcsl_number_17(), // output [4:0] + .stat_rx_pcsl_number_18(), // output [4:0] + .stat_rx_pcsl_number_19(), // output [4:0] + .stat_rx_pcsl_number_2(), // output [4:0] + .stat_rx_pcsl_number_3(), // output [4:0] + .stat_rx_pcsl_number_4(), // output [4:0] + .stat_rx_pcsl_number_5(), // output [4:0] + .stat_rx_pcsl_number_6(), // output [4:0] + .stat_rx_pcsl_number_7(), // output [4:0] + .stat_rx_pcsl_number_8(), // output [4:0] + .stat_rx_pcsl_number_9(), // output [4:0] + .stat_rx_rsfec_am_lock0(), // output + .stat_rx_rsfec_am_lock1(), // output + .stat_rx_rsfec_am_lock2(), // output + .stat_rx_rsfec_am_lock3(), // output + .stat_rx_rsfec_corrected_cw_inc(), // output + .stat_rx_rsfec_cw_inc(), // output + .stat_rx_rsfec_err_count0_inc(), // output [2:0] + .stat_rx_rsfec_err_count1_inc(), // output [2:0] + .stat_rx_rsfec_err_count2_inc(), // output [2:0] + .stat_rx_rsfec_err_count3_inc(), // output [2:0] + .stat_rx_rsfec_hi_ser(), // output + .stat_rx_rsfec_lane_alignment_status(), // output + .stat_rx_rsfec_lane_fill_0(), // output [13:0] + .stat_rx_rsfec_lane_fill_1(), // output [13:0] + .stat_rx_rsfec_lane_fill_2(), // output [13:0] + .stat_rx_rsfec_lane_fill_3(), // output [13:0] + .stat_rx_rsfec_lane_mapping(), // output [7:0] + .stat_rx_rsfec_uncorrected_cw_inc(), // output + + .ctl_tx_systemtimerin(qsfp0_tx_ptp_time_int), // input [79:0] + + .stat_tx_ptp_fifo_read_error(), // output + .stat_tx_ptp_fifo_write_error(), // output + + .tx_ptp_tstamp_valid_out(qsfp0_tx_ptp_ts_valid_int), // output + .tx_ptp_pcslane_out(), // output [4:0] + .tx_ptp_tstamp_tag_out(qsfp0_tx_ptp_ts_tag_int), // output [15:0] + .tx_ptp_tstamp_out(qsfp0_tx_ptp_ts_int), // output [79:0] + .tx_ptp_1588op_in(2'b10), // input [1:0] + .tx_ptp_tag_field_in(qsfp0_mac_tx_axis_tuser[16:1]), // input [15:0] + + .stat_tx_bad_fcs(), // output + .stat_tx_broadcast(), // output + .stat_tx_frame_error(), // output + .stat_tx_local_fault(), // output + .stat_tx_multicast(), // output + .stat_tx_packet_1024_1518_bytes(), // output + .stat_tx_packet_128_255_bytes(), // output + .stat_tx_packet_1519_1522_bytes(), // output + .stat_tx_packet_1523_1548_bytes(), // output + .stat_tx_packet_1549_2047_bytes(), // output + .stat_tx_packet_2048_4095_bytes(), // output + .stat_tx_packet_256_511_bytes(), // output + .stat_tx_packet_4096_8191_bytes(), // output + .stat_tx_packet_512_1023_bytes(), // output + .stat_tx_packet_64_bytes(), // output + .stat_tx_packet_65_127_bytes(), // output + .stat_tx_packet_8192_9215_bytes(), // output + .stat_tx_packet_large(), // output + .stat_tx_packet_small(), // output + .stat_tx_total_bytes(), // output [5:0] + .stat_tx_total_good_bytes(), // output [13:0] + .stat_tx_total_good_packets(), // output + .stat_tx_total_packets(), // output + .stat_tx_unicast(), // output + .stat_tx_vlan(), // output + + .ctl_tx_enable(1'b1), // input + .ctl_tx_test_pattern(1'b0), // input + .ctl_tx_rsfec_enable(1'b1), // input + .ctl_tx_send_idle(1'b0), // input + .ctl_tx_send_rfi(1'b0), // input + .ctl_tx_send_lfi(1'b0), // input + .core_tx_reset(1'b0), // input + + .tx_axis_tready(qsfp0_mac_tx_axis_tready), // output + .tx_axis_tvalid(qsfp0_mac_tx_axis_tvalid), // input + .tx_axis_tdata(qsfp0_mac_tx_axis_tdata), // input [511:0] + .tx_axis_tlast(qsfp0_mac_tx_axis_tlast), // input + .tx_axis_tkeep(qsfp0_mac_tx_axis_tkeep), // input [63:0] + .tx_axis_tuser(qsfp0_mac_tx_axis_tuser[0]), // input + + .tx_ovfout(), // output + .tx_unfout(), // output + .tx_preamblein(56'd0), // input [55:0] + .usr_tx_reset(qsfp0_tx_rst_int), // output + + .core_drp_reset(1'b0), // input + .drp_clk(1'b0), // input + .drp_addr(10'd0), // input [9:0] + .drp_di(16'd0), // input [15:0] + .drp_en(1'b0), // input + .drp_do(), // output [15:0] + .drp_rdy(), // output + .drp_we(1'b0) // input +); + +// QSFP1 CMAC +wire qsfp1_tx_clk_int; +wire qsfp1_tx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep_int; +wire qsfp1_tx_axis_tvalid_int; +wire qsfp1_tx_axis_tready_int; +wire qsfp1_tx_axis_tlast_int; +wire [16+1-1:0] qsfp1_tx_axis_tuser_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_mac_tx_axis_tdata; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_mac_tx_axis_tkeep; +wire qsfp1_mac_tx_axis_tvalid; +wire qsfp1_mac_tx_axis_tready; +wire qsfp1_mac_tx_axis_tlast; +wire [16+1-1:0] qsfp1_mac_tx_axis_tuser; + +wire [79:0] qsfp1_tx_ptp_time_int; +wire [79:0] qsfp1_tx_ptp_ts_int; +wire [15:0] qsfp1_tx_ptp_ts_tag_int; +wire qsfp1_tx_ptp_ts_valid_int; + +wire qsfp1_rx_clk_int; +wire qsfp1_rx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep_int; +wire qsfp1_rx_axis_tvalid_int; +wire qsfp1_rx_axis_tlast_int; +wire [80+1-1:0] qsfp1_rx_axis_tuser_int; + +wire qsfp1_rx_ptp_clk_int; +wire qsfp1_rx_ptp_rst_int; +wire [79:0] qsfp1_rx_ptp_time_int; + +wire qsfp1_rx_status; + +wire qsfp1_txuserclk2; +wire qsfp1_rxuserclk2; + +assign qsfp1_tx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_clk_int = qsfp1_txuserclk2; +assign qsfp1_rx_ptp_clk_int = qsfp1_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp1_rx_ptp_rst_inst ( + .clk(qsfp1_rx_ptp_clk_int), + .rst(qsfp1_tx_rst_int), + .out(qsfp1_rx_ptp_rst_int) +); + +cmac_pad #( + .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .USER_WIDTH(16+1) +) +qsfp1_cmac_pad_inst ( + .clk(qsfp1_tx_clk_int), + .rst(qsfp1_tx_rst_int), + + .s_axis_tdata(qsfp1_tx_axis_tdata_int), + .s_axis_tkeep(qsfp1_tx_axis_tkeep_int), + .s_axis_tvalid(qsfp1_tx_axis_tvalid_int), + .s_axis_tready(qsfp1_tx_axis_tready_int), + .s_axis_tlast(qsfp1_tx_axis_tlast_int), + .s_axis_tuser(qsfp1_tx_axis_tuser_int), + + .m_axis_tdata(qsfp1_mac_tx_axis_tdata), + .m_axis_tkeep(qsfp1_mac_tx_axis_tkeep), + .m_axis_tvalid(qsfp1_mac_tx_axis_tvalid), + .m_axis_tready(qsfp1_mac_tx_axis_tready), + .m_axis_tlast(qsfp1_mac_tx_axis_tlast), + .m_axis_tuser(qsfp1_mac_tx_axis_tuser) +); + +cmac_usplus_1 +qsfp1_cmac_inst ( + .gt_rxp_in({qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), // input + .gt_rxn_in({qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), // input + .gt_txp_out({qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), // output + .gt_txn_out({qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), // output + .gt_txusrclk2(qsfp1_txuserclk2), // output + .gt_loopback_in(12'd0), // input [11:0] + .gt_rxrecclkout(), // output [3:0] + .gt_powergoodout(), // output [3:0] + .gt_ref_clk_out(), // output + .gtwiz_reset_tx_datapath(1'b0), // input + .gtwiz_reset_rx_datapath(1'b0), // input + .sys_reset(rst_125mhz_int), // input + .gt_ref_clk_p(qsfp1_mgt_refclk_b0_p), // input + .gt_ref_clk_n(qsfp1_mgt_refclk_b0_n), // input + .init_clk(clk_125mhz_int), // input + + .rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), // output + .rx_axis_tdata(qsfp1_rx_axis_tdata_int), // output [511:0] + .rx_axis_tlast(qsfp1_rx_axis_tlast_int), // output + .rx_axis_tkeep(qsfp1_rx_axis_tkeep_int), // output [63:0] + .rx_axis_tuser(qsfp1_rx_axis_tuser_int[0]), // output + + .rx_otn_bip8_0(), // output [7:0] + .rx_otn_bip8_1(), // output [7:0] + .rx_otn_bip8_2(), // output [7:0] + .rx_otn_bip8_3(), // output [7:0] + .rx_otn_bip8_4(), // output [7:0] + .rx_otn_data_0(), // output [65:0] + .rx_otn_data_1(), // output [65:0] + .rx_otn_data_2(), // output [65:0] + .rx_otn_data_3(), // output [65:0] + .rx_otn_data_4(), // output [65:0] + .rx_otn_ena(), // output + .rx_otn_lane0(), // output + .rx_otn_vlmarker(), // output + .rx_preambleout(), // output [55:0] + .usr_rx_reset(qsfp1_rx_rst_int), // output + .gt_rxusrclk2(qsfp1_rxuserclk2), // output + + .rx_lane_aligner_fill_0(), // output [6:0] + .rx_lane_aligner_fill_1(), // output [6:0] + .rx_lane_aligner_fill_10(), // output [6:0] + .rx_lane_aligner_fill_11(), // output [6:0] + .rx_lane_aligner_fill_12(), // output [6:0] + .rx_lane_aligner_fill_13(), // output [6:0] + .rx_lane_aligner_fill_14(), // output [6:0] + .rx_lane_aligner_fill_15(), // output [6:0] + .rx_lane_aligner_fill_16(), // output [6:0] + .rx_lane_aligner_fill_17(), // output [6:0] + .rx_lane_aligner_fill_18(), // output [6:0] + .rx_lane_aligner_fill_19(), // output [6:0] + .rx_lane_aligner_fill_2(), // output [6:0] + .rx_lane_aligner_fill_3(), // output [6:0] + .rx_lane_aligner_fill_4(), // output [6:0] + .rx_lane_aligner_fill_5(), // output [6:0] + .rx_lane_aligner_fill_6(), // output [6:0] + .rx_lane_aligner_fill_7(), // output [6:0] + .rx_lane_aligner_fill_8(), // output [6:0] + .rx_lane_aligner_fill_9(), // output [6:0] + .rx_ptp_tstamp_out(qsfp1_rx_axis_tuser_int[80:1]), // output [79:0] + .rx_ptp_pcslane_out(), // output [4:0] + .ctl_rx_systemtimerin(qsfp1_rx_ptp_time_int), // input [79:0] + + .stat_rx_aligned(), // output + .stat_rx_aligned_err(), // output + .stat_rx_bad_code(), // output [2:0] + .stat_rx_bad_fcs(), // output [2:0] + .stat_rx_bad_preamble(), // output + .stat_rx_bad_sfd(), // output + .stat_rx_bip_err_0(), // output + .stat_rx_bip_err_1(), // output + .stat_rx_bip_err_10(), // output + .stat_rx_bip_err_11(), // output + .stat_rx_bip_err_12(), // output + .stat_rx_bip_err_13(), // output + .stat_rx_bip_err_14(), // output + .stat_rx_bip_err_15(), // output + .stat_rx_bip_err_16(), // output + .stat_rx_bip_err_17(), // output + .stat_rx_bip_err_18(), // output + .stat_rx_bip_err_19(), // output + .stat_rx_bip_err_2(), // output + .stat_rx_bip_err_3(), // output + .stat_rx_bip_err_4(), // output + .stat_rx_bip_err_5(), // output + .stat_rx_bip_err_6(), // output + .stat_rx_bip_err_7(), // output + .stat_rx_bip_err_8(), // output + .stat_rx_bip_err_9(), // output + .stat_rx_block_lock(), // output [19:0] + .stat_rx_broadcast(), // output + .stat_rx_fragment(), // output [2:0] + .stat_rx_framing_err_0(), // output [1:0] + .stat_rx_framing_err_1(), // output [1:0] + .stat_rx_framing_err_10(), // output [1:0] + .stat_rx_framing_err_11(), // output [1:0] + .stat_rx_framing_err_12(), // output [1:0] + .stat_rx_framing_err_13(), // output [1:0] + .stat_rx_framing_err_14(), // output [1:0] + .stat_rx_framing_err_15(), // output [1:0] + .stat_rx_framing_err_16(), // output [1:0] + .stat_rx_framing_err_17(), // output [1:0] + .stat_rx_framing_err_18(), // output [1:0] + .stat_rx_framing_err_19(), // output [1:0] + .stat_rx_framing_err_2(), // output [1:0] + .stat_rx_framing_err_3(), // output [1:0] + .stat_rx_framing_err_4(), // output [1:0] + .stat_rx_framing_err_5(), // output [1:0] + .stat_rx_framing_err_6(), // output [1:0] + .stat_rx_framing_err_7(), // output [1:0] + .stat_rx_framing_err_8(), // output [1:0] + .stat_rx_framing_err_9(), // output [1:0] + .stat_rx_framing_err_valid_0(), // output + .stat_rx_framing_err_valid_1(), // output + .stat_rx_framing_err_valid_10(), // output + .stat_rx_framing_err_valid_11(), // output + .stat_rx_framing_err_valid_12(), // output + .stat_rx_framing_err_valid_13(), // output + .stat_rx_framing_err_valid_14(), // output + .stat_rx_framing_err_valid_15(), // output + .stat_rx_framing_err_valid_16(), // output + .stat_rx_framing_err_valid_17(), // output + .stat_rx_framing_err_valid_18(), // output + .stat_rx_framing_err_valid_19(), // output + .stat_rx_framing_err_valid_2(), // output + .stat_rx_framing_err_valid_3(), // output + .stat_rx_framing_err_valid_4(), // output + .stat_rx_framing_err_valid_5(), // output + .stat_rx_framing_err_valid_6(), // output + .stat_rx_framing_err_valid_7(), // output + .stat_rx_framing_err_valid_8(), // output + .stat_rx_framing_err_valid_9(), // output + .stat_rx_got_signal_os(), // output + .stat_rx_hi_ber(), // output + .stat_rx_inrangeerr(), // output + .stat_rx_internal_local_fault(), // output + .stat_rx_jabber(), // output + .stat_rx_local_fault(), // output + .stat_rx_mf_err(), // output [19:0] + .stat_rx_mf_len_err(), // output [19:0] + .stat_rx_mf_repeat_err(), // output [19:0] + .stat_rx_misaligned(), // output + .stat_rx_multicast(), // output + .stat_rx_oversize(), // output + .stat_rx_packet_1024_1518_bytes(), // output + .stat_rx_packet_128_255_bytes(), // output + .stat_rx_packet_1519_1522_bytes(), // output + .stat_rx_packet_1523_1548_bytes(), // output + .stat_rx_packet_1549_2047_bytes(), // output + .stat_rx_packet_2048_4095_bytes(), // output + .stat_rx_packet_256_511_bytes(), // output + .stat_rx_packet_4096_8191_bytes(), // output + .stat_rx_packet_512_1023_bytes(), // output + .stat_rx_packet_64_bytes(), // output + .stat_rx_packet_65_127_bytes(), // output + .stat_rx_packet_8192_9215_bytes(), // output + .stat_rx_packet_bad_fcs(), // output + .stat_rx_packet_large(), // output + .stat_rx_packet_small(), // output [2:0] + + .ctl_rx_enable(1'b1), // input + .ctl_rx_force_resync(1'b0), // input + .ctl_rx_test_pattern(1'b0), // input + .ctl_rsfec_ieee_error_indication_mode(1'b0), // input + .ctl_rx_rsfec_enable(1'b1), // input + .ctl_rx_rsfec_enable_correction(1'b1), // input + .ctl_rx_rsfec_enable_indication(1'b1), // input + .core_rx_reset(1'b0), // input + .rx_clk(qsfp1_rx_clk_int), // input + + .stat_rx_received_local_fault(), // output + .stat_rx_remote_fault(), // output + .stat_rx_status(qsfp1_rx_status), // output + .stat_rx_stomped_fcs(), // output [2:0] + .stat_rx_synced(), // output [19:0] + .stat_rx_synced_err(), // output [19:0] + .stat_rx_test_pattern_mismatch(), // output [2:0] + .stat_rx_toolong(), // output + .stat_rx_total_bytes(), // output [6:0] + .stat_rx_total_good_bytes(), // output [13:0] + .stat_rx_total_good_packets(), // output + .stat_rx_total_packets(), // output [2:0] + .stat_rx_truncated(), // output + .stat_rx_undersize(), // output [2:0] + .stat_rx_unicast(), // output + .stat_rx_vlan(), // output + .stat_rx_pcsl_demuxed(), // output [19:0] + .stat_rx_pcsl_number_0(), // output [4:0] + .stat_rx_pcsl_number_1(), // output [4:0] + .stat_rx_pcsl_number_10(), // output [4:0] + .stat_rx_pcsl_number_11(), // output [4:0] + .stat_rx_pcsl_number_12(), // output [4:0] + .stat_rx_pcsl_number_13(), // output [4:0] + .stat_rx_pcsl_number_14(), // output [4:0] + .stat_rx_pcsl_number_15(), // output [4:0] + .stat_rx_pcsl_number_16(), // output [4:0] + .stat_rx_pcsl_number_17(), // output [4:0] + .stat_rx_pcsl_number_18(), // output [4:0] + .stat_rx_pcsl_number_19(), // output [4:0] + .stat_rx_pcsl_number_2(), // output [4:0] + .stat_rx_pcsl_number_3(), // output [4:0] + .stat_rx_pcsl_number_4(), // output [4:0] + .stat_rx_pcsl_number_5(), // output [4:0] + .stat_rx_pcsl_number_6(), // output [4:0] + .stat_rx_pcsl_number_7(), // output [4:0] + .stat_rx_pcsl_number_8(), // output [4:0] + .stat_rx_pcsl_number_9(), // output [4:0] + .stat_rx_rsfec_am_lock0(), // output + .stat_rx_rsfec_am_lock1(), // output + .stat_rx_rsfec_am_lock2(), // output + .stat_rx_rsfec_am_lock3(), // output + .stat_rx_rsfec_corrected_cw_inc(), // output + .stat_rx_rsfec_cw_inc(), // output + .stat_rx_rsfec_err_count0_inc(), // output [2:0] + .stat_rx_rsfec_err_count1_inc(), // output [2:0] + .stat_rx_rsfec_err_count2_inc(), // output [2:0] + .stat_rx_rsfec_err_count3_inc(), // output [2:0] + .stat_rx_rsfec_hi_ser(), // output + .stat_rx_rsfec_lane_alignment_status(), // output + .stat_rx_rsfec_lane_fill_0(), // output [13:0] + .stat_rx_rsfec_lane_fill_1(), // output [13:0] + .stat_rx_rsfec_lane_fill_2(), // output [13:0] + .stat_rx_rsfec_lane_fill_3(), // output [13:0] + .stat_rx_rsfec_lane_mapping(), // output [7:0] + .stat_rx_rsfec_uncorrected_cw_inc(), // output + + .ctl_tx_systemtimerin(qsfp1_tx_ptp_time_int), // input [79:0] + + .stat_tx_ptp_fifo_read_error(), // output + .stat_tx_ptp_fifo_write_error(), // output + + .tx_ptp_tstamp_valid_out(qsfp1_tx_ptp_ts_valid_int), // output + .tx_ptp_pcslane_out(), // output [4:0] + .tx_ptp_tstamp_tag_out(qsfp1_tx_ptp_ts_tag_int), // output [15:0] + .tx_ptp_tstamp_out(qsfp1_tx_ptp_ts_int), // output [79:0] + .tx_ptp_1588op_in(2'b10), // input [1:0] + .tx_ptp_tag_field_in(qsfp1_mac_tx_axis_tuser[16:1]), // input [15:0] + + .stat_tx_bad_fcs(), // output + .stat_tx_broadcast(), // output + .stat_tx_frame_error(), // output + .stat_tx_local_fault(), // output + .stat_tx_multicast(), // output + .stat_tx_packet_1024_1518_bytes(), // output + .stat_tx_packet_128_255_bytes(), // output + .stat_tx_packet_1519_1522_bytes(), // output + .stat_tx_packet_1523_1548_bytes(), // output + .stat_tx_packet_1549_2047_bytes(), // output + .stat_tx_packet_2048_4095_bytes(), // output + .stat_tx_packet_256_511_bytes(), // output + .stat_tx_packet_4096_8191_bytes(), // output + .stat_tx_packet_512_1023_bytes(), // output + .stat_tx_packet_64_bytes(), // output + .stat_tx_packet_65_127_bytes(), // output + .stat_tx_packet_8192_9215_bytes(), // output + .stat_tx_packet_large(), // output + .stat_tx_packet_small(), // output + .stat_tx_total_bytes(), // output [5:0] + .stat_tx_total_good_bytes(), // output [13:0] + .stat_tx_total_good_packets(), // output + .stat_tx_total_packets(), // output + .stat_tx_unicast(), // output + .stat_tx_vlan(), // output + + .ctl_tx_enable(1'b1), // input + .ctl_tx_test_pattern(1'b0), // input + .ctl_tx_rsfec_enable(1'b1), // input + .ctl_tx_send_idle(1'b0), // input + .ctl_tx_send_rfi(1'b0), // input + .ctl_tx_send_lfi(1'b0), // input + .core_tx_reset(1'b0), // input + + .tx_axis_tready(qsfp1_mac_tx_axis_tready), // output + .tx_axis_tvalid(qsfp1_mac_tx_axis_tvalid), // input + .tx_axis_tdata(qsfp1_mac_tx_axis_tdata), // input [511:0] + .tx_axis_tlast(qsfp1_mac_tx_axis_tlast), // input + .tx_axis_tkeep(qsfp1_mac_tx_axis_tkeep), // input [63:0] + .tx_axis_tuser(qsfp1_mac_tx_axis_tuser[0]), // input + + .tx_ovfout(), // output + .tx_unfout(), // output + .tx_preamblein(56'd0), // input [55:0] + .usr_tx_reset(qsfp1_tx_rst_int), // output + + .core_drp_reset(1'b0), // input + .drp_clk(1'b0), // input + .drp_addr(10'd0), // input [9:0] + .drp_di(16'd0), // input [15:0] + .drp_en(1'b0), // input + .drp_do(), // output [15:0] + .drp_rdy(), // output + .drp_we(1'b0) // input +); + +// QSFP2 CMAC +wire qsfp2_tx_clk_int; +wire qsfp2_tx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_tx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_tx_axis_tkeep_int; +wire qsfp2_tx_axis_tvalid_int; +wire qsfp2_tx_axis_tready_int; +wire qsfp2_tx_axis_tlast_int; +wire [16+1-1:0] qsfp2_tx_axis_tuser_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_mac_tx_axis_tdata; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_mac_tx_axis_tkeep; +wire qsfp2_mac_tx_axis_tvalid; +wire qsfp2_mac_tx_axis_tready; +wire qsfp2_mac_tx_axis_tlast; +wire [16+1-1:0] qsfp2_mac_tx_axis_tuser; + +wire [79:0] qsfp2_tx_ptp_time_int; +wire [79:0] qsfp2_tx_ptp_ts_int; +wire [15:0] qsfp2_tx_ptp_ts_tag_int; +wire qsfp2_tx_ptp_ts_valid_int; + +wire qsfp2_rx_clk_int; +wire qsfp2_rx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_rx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_rx_axis_tkeep_int; +wire qsfp2_rx_axis_tvalid_int; +wire qsfp2_rx_axis_tlast_int; +wire [80+1-1:0] qsfp2_rx_axis_tuser_int; + +wire qsfp2_rx_ptp_clk_int; +wire qsfp2_rx_ptp_rst_int; +wire [79:0] qsfp2_rx_ptp_time_int; + +wire qsfp2_rx_status; + +wire qsfp2_txuserclk2; +wire qsfp2_rxuserclk2; + +assign qsfp2_tx_clk_int = qsfp2_txuserclk2; +assign qsfp2_rx_clk_int = qsfp2_txuserclk2; +assign qsfp2_rx_ptp_clk_int = qsfp2_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp2_rx_ptp_rst_inst ( + .clk(qsfp2_rx_ptp_clk_int), + .rst(qsfp2_tx_rst_int), + .out(qsfp2_rx_ptp_rst_int) +); + +cmac_pad #( + .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .USER_WIDTH(16+1) +) +qsfp2_cmac_pad_inst ( + .clk(qsfp2_tx_clk_int), + .rst(qsfp2_tx_rst_int), + + .s_axis_tdata(qsfp2_tx_axis_tdata_int), + .s_axis_tkeep(qsfp2_tx_axis_tkeep_int), + .s_axis_tvalid(qsfp2_tx_axis_tvalid_int), + .s_axis_tready(qsfp2_tx_axis_tready_int), + .s_axis_tlast(qsfp2_tx_axis_tlast_int), + .s_axis_tuser(qsfp2_tx_axis_tuser_int), + + .m_axis_tdata(qsfp2_mac_tx_axis_tdata), + .m_axis_tkeep(qsfp2_mac_tx_axis_tkeep), + .m_axis_tvalid(qsfp2_mac_tx_axis_tvalid), + .m_axis_tready(qsfp2_mac_tx_axis_tready), + .m_axis_tlast(qsfp2_mac_tx_axis_tlast), + .m_axis_tuser(qsfp2_mac_tx_axis_tuser) +); + +cmac_usplus_2 +qsfp2_cmac_inst ( + .gt_rxp_in({qsfp2_rx4_p, qsfp2_rx3_p, qsfp2_rx2_p, qsfp2_rx1_p}), // input + .gt_rxn_in({qsfp2_rx4_n, qsfp2_rx3_n, qsfp2_rx2_n, qsfp2_rx1_n}), // input + .gt_txp_out({qsfp2_tx4_p, qsfp2_tx3_p, qsfp2_tx2_p, qsfp2_tx1_p}), // output + .gt_txn_out({qsfp2_tx4_n, qsfp2_tx3_n, qsfp2_tx2_n, qsfp2_tx1_n}), // output + .gt_txusrclk2(qsfp2_txuserclk2), // output + .gt_loopback_in(12'd0), // input [11:0] + .gt_rxrecclkout(), // output [3:0] + .gt_powergoodout(), // output [3:0] + .gt_ref_clk_out(), // output + .gtwiz_reset_tx_datapath(1'b0), // input + .gtwiz_reset_rx_datapath(1'b0), // input + .sys_reset(rst_125mhz_int), // input + .gt_ref_clk_p(qsfp2_mgt_refclk_b0_p), // input + .gt_ref_clk_n(qsfp2_mgt_refclk_b0_n), // input + .init_clk(clk_125mhz_int), // input + + .rx_axis_tvalid(qsfp2_rx_axis_tvalid_int), // output + .rx_axis_tdata(qsfp2_rx_axis_tdata_int), // output [511:0] + .rx_axis_tlast(qsfp2_rx_axis_tlast_int), // output + .rx_axis_tkeep(qsfp2_rx_axis_tkeep_int), // output [63:0] + .rx_axis_tuser(qsfp2_rx_axis_tuser_int[0]), // output + + .rx_otn_bip8_0(), // output [7:0] + .rx_otn_bip8_1(), // output [7:0] + .rx_otn_bip8_2(), // output [7:0] + .rx_otn_bip8_3(), // output [7:0] + .rx_otn_bip8_4(), // output [7:0] + .rx_otn_data_0(), // output [65:0] + .rx_otn_data_1(), // output [65:0] + .rx_otn_data_2(), // output [65:0] + .rx_otn_data_3(), // output [65:0] + .rx_otn_data_4(), // output [65:0] + .rx_otn_ena(), // output + .rx_otn_lane0(), // output + .rx_otn_vlmarker(), // output + .rx_preambleout(), // output [55:0] + .usr_rx_reset(qsfp2_rx_rst_int), // output + .gt_rxusrclk2(qsfp2_rxuserclk2), // output + + .rx_lane_aligner_fill_0(), // output [6:0] + .rx_lane_aligner_fill_1(), // output [6:0] + .rx_lane_aligner_fill_10(), // output [6:0] + .rx_lane_aligner_fill_11(), // output [6:0] + .rx_lane_aligner_fill_12(), // output [6:0] + .rx_lane_aligner_fill_13(), // output [6:0] + .rx_lane_aligner_fill_14(), // output [6:0] + .rx_lane_aligner_fill_15(), // output [6:0] + .rx_lane_aligner_fill_16(), // output [6:0] + .rx_lane_aligner_fill_17(), // output [6:0] + .rx_lane_aligner_fill_18(), // output [6:0] + .rx_lane_aligner_fill_19(), // output [6:0] + .rx_lane_aligner_fill_2(), // output [6:0] + .rx_lane_aligner_fill_3(), // output [6:0] + .rx_lane_aligner_fill_4(), // output [6:0] + .rx_lane_aligner_fill_5(), // output [6:0] + .rx_lane_aligner_fill_6(), // output [6:0] + .rx_lane_aligner_fill_7(), // output [6:0] + .rx_lane_aligner_fill_8(), // output [6:0] + .rx_lane_aligner_fill_9(), // output [6:0] + .rx_ptp_tstamp_out(qsfp2_rx_axis_tuser_int[80:1]), // output [79:0] + .rx_ptp_pcslane_out(), // output [4:0] + .ctl_rx_systemtimerin(qsfp2_rx_ptp_time_int), // input [79:0] + + .stat_rx_aligned(), // output + .stat_rx_aligned_err(), // output + .stat_rx_bad_code(), // output [2:0] + .stat_rx_bad_fcs(), // output [2:0] + .stat_rx_bad_preamble(), // output + .stat_rx_bad_sfd(), // output + .stat_rx_bip_err_0(), // output + .stat_rx_bip_err_1(), // output + .stat_rx_bip_err_10(), // output + .stat_rx_bip_err_11(), // output + .stat_rx_bip_err_12(), // output + .stat_rx_bip_err_13(), // output + .stat_rx_bip_err_14(), // output + .stat_rx_bip_err_15(), // output + .stat_rx_bip_err_16(), // output + .stat_rx_bip_err_17(), // output + .stat_rx_bip_err_18(), // output + .stat_rx_bip_err_19(), // output + .stat_rx_bip_err_2(), // output + .stat_rx_bip_err_3(), // output + .stat_rx_bip_err_4(), // output + .stat_rx_bip_err_5(), // output + .stat_rx_bip_err_6(), // output + .stat_rx_bip_err_7(), // output + .stat_rx_bip_err_8(), // output + .stat_rx_bip_err_9(), // output + .stat_rx_block_lock(), // output [19:0] + .stat_rx_broadcast(), // output + .stat_rx_fragment(), // output [2:0] + .stat_rx_framing_err_0(), // output [1:0] + .stat_rx_framing_err_1(), // output [1:0] + .stat_rx_framing_err_10(), // output [1:0] + .stat_rx_framing_err_11(), // output [1:0] + .stat_rx_framing_err_12(), // output [1:0] + .stat_rx_framing_err_13(), // output [1:0] + .stat_rx_framing_err_14(), // output [1:0] + .stat_rx_framing_err_15(), // output [1:0] + .stat_rx_framing_err_16(), // output [1:0] + .stat_rx_framing_err_17(), // output [1:0] + .stat_rx_framing_err_18(), // output [1:0] + .stat_rx_framing_err_19(), // output [1:0] + .stat_rx_framing_err_2(), // output [1:0] + .stat_rx_framing_err_3(), // output [1:0] + .stat_rx_framing_err_4(), // output [1:0] + .stat_rx_framing_err_5(), // output [1:0] + .stat_rx_framing_err_6(), // output [1:0] + .stat_rx_framing_err_7(), // output [1:0] + .stat_rx_framing_err_8(), // output [1:0] + .stat_rx_framing_err_9(), // output [1:0] + .stat_rx_framing_err_valid_0(), // output + .stat_rx_framing_err_valid_1(), // output + .stat_rx_framing_err_valid_10(), // output + .stat_rx_framing_err_valid_11(), // output + .stat_rx_framing_err_valid_12(), // output + .stat_rx_framing_err_valid_13(), // output + .stat_rx_framing_err_valid_14(), // output + .stat_rx_framing_err_valid_15(), // output + .stat_rx_framing_err_valid_16(), // output + .stat_rx_framing_err_valid_17(), // output + .stat_rx_framing_err_valid_18(), // output + .stat_rx_framing_err_valid_19(), // output + .stat_rx_framing_err_valid_2(), // output + .stat_rx_framing_err_valid_3(), // output + .stat_rx_framing_err_valid_4(), // output + .stat_rx_framing_err_valid_5(), // output + .stat_rx_framing_err_valid_6(), // output + .stat_rx_framing_err_valid_7(), // output + .stat_rx_framing_err_valid_8(), // output + .stat_rx_framing_err_valid_9(), // output + .stat_rx_got_signal_os(), // output + .stat_rx_hi_ber(), // output + .stat_rx_inrangeerr(), // output + .stat_rx_internal_local_fault(), // output + .stat_rx_jabber(), // output + .stat_rx_local_fault(), // output + .stat_rx_mf_err(), // output [19:0] + .stat_rx_mf_len_err(), // output [19:0] + .stat_rx_mf_repeat_err(), // output [19:0] + .stat_rx_misaligned(), // output + .stat_rx_multicast(), // output + .stat_rx_oversize(), // output + .stat_rx_packet_1024_1518_bytes(), // output + .stat_rx_packet_128_255_bytes(), // output + .stat_rx_packet_1519_1522_bytes(), // output + .stat_rx_packet_1523_1548_bytes(), // output + .stat_rx_packet_1549_2047_bytes(), // output + .stat_rx_packet_2048_4095_bytes(), // output + .stat_rx_packet_256_511_bytes(), // output + .stat_rx_packet_4096_8191_bytes(), // output + .stat_rx_packet_512_1023_bytes(), // output + .stat_rx_packet_64_bytes(), // output + .stat_rx_packet_65_127_bytes(), // output + .stat_rx_packet_8192_9215_bytes(), // output + .stat_rx_packet_bad_fcs(), // output + .stat_rx_packet_large(), // output + .stat_rx_packet_small(), // output [2:0] + + .ctl_rx_enable(1'b1), // input + .ctl_rx_force_resync(1'b0), // input + .ctl_rx_test_pattern(1'b0), // input + .ctl_rsfec_ieee_error_indication_mode(1'b0), // input + .ctl_rx_rsfec_enable(1'b1), // input + .ctl_rx_rsfec_enable_correction(1'b1), // input + .ctl_rx_rsfec_enable_indication(1'b1), // input + .core_rx_reset(1'b0), // input + .rx_clk(qsfp2_rx_clk_int), // input + + .stat_rx_received_local_fault(), // output + .stat_rx_remote_fault(), // output + .stat_rx_status(qsfp2_rx_status), // output + .stat_rx_stomped_fcs(), // output [2:0] + .stat_rx_synced(), // output [19:0] + .stat_rx_synced_err(), // output [19:0] + .stat_rx_test_pattern_mismatch(), // output [2:0] + .stat_rx_toolong(), // output + .stat_rx_total_bytes(), // output [6:0] + .stat_rx_total_good_bytes(), // output [13:0] + .stat_rx_total_good_packets(), // output + .stat_rx_total_packets(), // output [2:0] + .stat_rx_truncated(), // output + .stat_rx_undersize(), // output [2:0] + .stat_rx_unicast(), // output + .stat_rx_vlan(), // output + .stat_rx_pcsl_demuxed(), // output [19:0] + .stat_rx_pcsl_number_0(), // output [4:0] + .stat_rx_pcsl_number_1(), // output [4:0] + .stat_rx_pcsl_number_10(), // output [4:0] + .stat_rx_pcsl_number_11(), // output [4:0] + .stat_rx_pcsl_number_12(), // output [4:0] + .stat_rx_pcsl_number_13(), // output [4:0] + .stat_rx_pcsl_number_14(), // output [4:0] + .stat_rx_pcsl_number_15(), // output [4:0] + .stat_rx_pcsl_number_16(), // output [4:0] + .stat_rx_pcsl_number_17(), // output [4:0] + .stat_rx_pcsl_number_18(), // output [4:0] + .stat_rx_pcsl_number_19(), // output [4:0] + .stat_rx_pcsl_number_2(), // output [4:0] + .stat_rx_pcsl_number_3(), // output [4:0] + .stat_rx_pcsl_number_4(), // output [4:0] + .stat_rx_pcsl_number_5(), // output [4:0] + .stat_rx_pcsl_number_6(), // output [4:0] + .stat_rx_pcsl_number_7(), // output [4:0] + .stat_rx_pcsl_number_8(), // output [4:0] + .stat_rx_pcsl_number_9(), // output [4:0] + .stat_rx_rsfec_am_lock0(), // output + .stat_rx_rsfec_am_lock1(), // output + .stat_rx_rsfec_am_lock2(), // output + .stat_rx_rsfec_am_lock3(), // output + .stat_rx_rsfec_corrected_cw_inc(), // output + .stat_rx_rsfec_cw_inc(), // output + .stat_rx_rsfec_err_count0_inc(), // output [2:0] + .stat_rx_rsfec_err_count1_inc(), // output [2:0] + .stat_rx_rsfec_err_count2_inc(), // output [2:0] + .stat_rx_rsfec_err_count3_inc(), // output [2:0] + .stat_rx_rsfec_hi_ser(), // output + .stat_rx_rsfec_lane_alignment_status(), // output + .stat_rx_rsfec_lane_fill_0(), // output [13:0] + .stat_rx_rsfec_lane_fill_1(), // output [13:0] + .stat_rx_rsfec_lane_fill_2(), // output [13:0] + .stat_rx_rsfec_lane_fill_3(), // output [13:0] + .stat_rx_rsfec_lane_mapping(), // output [7:0] + .stat_rx_rsfec_uncorrected_cw_inc(), // output + + .ctl_tx_systemtimerin(qsfp2_tx_ptp_time_int), // input [79:0] + + .stat_tx_ptp_fifo_read_error(), // output + .stat_tx_ptp_fifo_write_error(), // output + + .tx_ptp_tstamp_valid_out(qsfp2_tx_ptp_ts_valid_int), // output + .tx_ptp_pcslane_out(), // output [4:0] + .tx_ptp_tstamp_tag_out(qsfp2_tx_ptp_ts_tag_int), // output [15:0] + .tx_ptp_tstamp_out(qsfp2_tx_ptp_ts_int), // output [79:0] + .tx_ptp_1588op_in(2'b10), // input [1:0] + .tx_ptp_tag_field_in(qsfp2_mac_tx_axis_tuser[16:1]), // input [15:0] + + .stat_tx_bad_fcs(), // output + .stat_tx_broadcast(), // output + .stat_tx_frame_error(), // output + .stat_tx_local_fault(), // output + .stat_tx_multicast(), // output + .stat_tx_packet_1024_1518_bytes(), // output + .stat_tx_packet_128_255_bytes(), // output + .stat_tx_packet_1519_1522_bytes(), // output + .stat_tx_packet_1523_1548_bytes(), // output + .stat_tx_packet_1549_2047_bytes(), // output + .stat_tx_packet_2048_4095_bytes(), // output + .stat_tx_packet_256_511_bytes(), // output + .stat_tx_packet_4096_8191_bytes(), // output + .stat_tx_packet_512_1023_bytes(), // output + .stat_tx_packet_64_bytes(), // output + .stat_tx_packet_65_127_bytes(), // output + .stat_tx_packet_8192_9215_bytes(), // output + .stat_tx_packet_large(), // output + .stat_tx_packet_small(), // output + .stat_tx_total_bytes(), // output [5:0] + .stat_tx_total_good_bytes(), // output [13:0] + .stat_tx_total_good_packets(), // output + .stat_tx_total_packets(), // output + .stat_tx_unicast(), // output + .stat_tx_vlan(), // output + + .ctl_tx_enable(1'b1), // input + .ctl_tx_test_pattern(1'b0), // input + .ctl_tx_rsfec_enable(1'b1), // input + .ctl_tx_send_idle(1'b0), // input + .ctl_tx_send_rfi(1'b0), // input + .ctl_tx_send_lfi(1'b0), // input + .core_tx_reset(1'b0), // input + + .tx_axis_tready(qsfp2_mac_tx_axis_tready), // output + .tx_axis_tvalid(qsfp2_mac_tx_axis_tvalid), // input + .tx_axis_tdata(qsfp2_mac_tx_axis_tdata), // input [511:0] + .tx_axis_tlast(qsfp2_mac_tx_axis_tlast), // input + .tx_axis_tkeep(qsfp2_mac_tx_axis_tkeep), // input [63:0] + .tx_axis_tuser(qsfp2_mac_tx_axis_tuser[0]), // input + + .tx_ovfout(), // output + .tx_unfout(), // output + .tx_preamblein(56'd0), // input [55:0] + .usr_tx_reset(qsfp2_tx_rst_int), // output + + .core_drp_reset(1'b0), // input + .drp_clk(1'b0), // input + .drp_addr(10'd0), // input [9:0] + .drp_di(16'd0), // input [15:0] + .drp_en(1'b0), // input + .drp_do(), // output [15:0] + .drp_rdy(), // output + .drp_we(1'b0) // input +); + +// QSFP3 CMAC +wire qsfp3_tx_clk_int; +wire qsfp3_tx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp3_tx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp3_tx_axis_tkeep_int; +wire qsfp3_tx_axis_tvalid_int; +wire qsfp3_tx_axis_tready_int; +wire qsfp3_tx_axis_tlast_int; +wire [16+1-1:0] qsfp3_tx_axis_tuser_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp3_mac_tx_axis_tdata; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp3_mac_tx_axis_tkeep; +wire qsfp3_mac_tx_axis_tvalid; +wire qsfp3_mac_tx_axis_tready; +wire qsfp3_mac_tx_axis_tlast; +wire [16+1-1:0] qsfp3_mac_tx_axis_tuser; + +wire [79:0] qsfp3_tx_ptp_time_int; +wire [79:0] qsfp3_tx_ptp_ts_int; +wire [15:0] qsfp3_tx_ptp_ts_tag_int; +wire qsfp3_tx_ptp_ts_valid_int; + +wire qsfp3_rx_clk_int; +wire qsfp3_rx_rst_int; + +wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp3_rx_axis_tdata_int; +wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp3_rx_axis_tkeep_int; +wire qsfp3_rx_axis_tvalid_int; +wire qsfp3_rx_axis_tlast_int; +wire [80+1-1:0] qsfp3_rx_axis_tuser_int; + +wire qsfp3_rx_ptp_clk_int; +wire qsfp3_rx_ptp_rst_int; +wire [79:0] qsfp3_rx_ptp_time_int; + +wire qsfp3_rx_status; + +wire qsfp3_txuserclk2; +wire qsfp3_rxuserclk2; + +assign qsfp3_tx_clk_int = qsfp3_txuserclk2; +assign qsfp3_rx_clk_int = qsfp3_txuserclk2; +assign qsfp3_rx_ptp_clk_int = qsfp3_rxuserclk2; + +sync_reset #( + .N(4) +) +sync_reset_qsfp3_rx_ptp_rst_inst ( + .clk(qsfp3_rx_ptp_clk_int), + .rst(qsfp3_tx_rst_int), + .out(qsfp3_rx_ptp_rst_int) +); + +cmac_pad #( + .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .USER_WIDTH(16+1) +) +qsfp3_cmac_pad_inst ( + .clk(qsfp3_tx_clk_int), + .rst(qsfp3_tx_rst_int), + + .s_axis_tdata(qsfp3_tx_axis_tdata_int), + .s_axis_tkeep(qsfp3_tx_axis_tkeep_int), + .s_axis_tvalid(qsfp3_tx_axis_tvalid_int), + .s_axis_tready(qsfp3_tx_axis_tready_int), + .s_axis_tlast(qsfp3_tx_axis_tlast_int), + .s_axis_tuser(qsfp3_tx_axis_tuser_int), + + .m_axis_tdata(qsfp3_mac_tx_axis_tdata), + .m_axis_tkeep(qsfp3_mac_tx_axis_tkeep), + .m_axis_tvalid(qsfp3_mac_tx_axis_tvalid), + .m_axis_tready(qsfp3_mac_tx_axis_tready), + .m_axis_tlast(qsfp3_mac_tx_axis_tlast), + .m_axis_tuser(qsfp3_mac_tx_axis_tuser) +); + +cmac_usplus_3 +qsfp3_cmac_inst ( + .gt_rxp_in({qsfp3_rx4_p, qsfp3_rx3_p, qsfp3_rx2_p, qsfp3_rx1_p}), // input + .gt_rxn_in({qsfp3_rx4_n, qsfp3_rx3_n, qsfp3_rx2_n, qsfp3_rx1_n}), // input + .gt_txp_out({qsfp3_tx4_p, qsfp3_tx3_p, qsfp3_tx2_p, qsfp3_tx1_p}), // output + .gt_txn_out({qsfp3_tx4_n, qsfp3_tx3_n, qsfp3_tx2_n, qsfp3_tx1_n}), // output + .gt_txusrclk2(qsfp3_txuserclk2), // output + .gt_loopback_in(12'd0), // input [11:0] + .gt_rxrecclkout(), // output [3:0] + .gt_powergoodout(), // output [3:0] + .gt_ref_clk_out(), // output + .gtwiz_reset_tx_datapath(1'b0), // input + .gtwiz_reset_rx_datapath(1'b0), // input + .sys_reset(rst_125mhz_int), // input + .gt_ref_clk_p(qsfp3_mgt_refclk_b0_p), // input + .gt_ref_clk_n(qsfp3_mgt_refclk_b0_n), // input + .init_clk(clk_125mhz_int), // input + + .rx_axis_tvalid(qsfp3_rx_axis_tvalid_int), // output + .rx_axis_tdata(qsfp3_rx_axis_tdata_int), // output [511:0] + .rx_axis_tlast(qsfp3_rx_axis_tlast_int), // output + .rx_axis_tkeep(qsfp3_rx_axis_tkeep_int), // output [63:0] + .rx_axis_tuser(qsfp3_rx_axis_tuser_int[0]), // output + + .rx_otn_bip8_0(), // output [7:0] + .rx_otn_bip8_1(), // output [7:0] + .rx_otn_bip8_2(), // output [7:0] + .rx_otn_bip8_3(), // output [7:0] + .rx_otn_bip8_4(), // output [7:0] + .rx_otn_data_0(), // output [65:0] + .rx_otn_data_1(), // output [65:0] + .rx_otn_data_2(), // output [65:0] + .rx_otn_data_3(), // output [65:0] + .rx_otn_data_4(), // output [65:0] + .rx_otn_ena(), // output + .rx_otn_lane0(), // output + .rx_otn_vlmarker(), // output + .rx_preambleout(), // output [55:0] + .usr_rx_reset(qsfp3_rx_rst_int), // output + .gt_rxusrclk2(qsfp3_rxuserclk2), // output + + .rx_lane_aligner_fill_0(), // output [6:0] + .rx_lane_aligner_fill_1(), // output [6:0] + .rx_lane_aligner_fill_10(), // output [6:0] + .rx_lane_aligner_fill_11(), // output [6:0] + .rx_lane_aligner_fill_12(), // output [6:0] + .rx_lane_aligner_fill_13(), // output [6:0] + .rx_lane_aligner_fill_14(), // output [6:0] + .rx_lane_aligner_fill_15(), // output [6:0] + .rx_lane_aligner_fill_16(), // output [6:0] + .rx_lane_aligner_fill_17(), // output [6:0] + .rx_lane_aligner_fill_18(), // output [6:0] + .rx_lane_aligner_fill_19(), // output [6:0] + .rx_lane_aligner_fill_2(), // output [6:0] + .rx_lane_aligner_fill_3(), // output [6:0] + .rx_lane_aligner_fill_4(), // output [6:0] + .rx_lane_aligner_fill_5(), // output [6:0] + .rx_lane_aligner_fill_6(), // output [6:0] + .rx_lane_aligner_fill_7(), // output [6:0] + .rx_lane_aligner_fill_8(), // output [6:0] + .rx_lane_aligner_fill_9(), // output [6:0] + .rx_ptp_tstamp_out(qsfp3_rx_axis_tuser_int[80:1]), // output [79:0] + .rx_ptp_pcslane_out(), // output [4:0] + .ctl_rx_systemtimerin(qsfp3_rx_ptp_time_int), // input [79:0] + + .stat_rx_aligned(), // output + .stat_rx_aligned_err(), // output + .stat_rx_bad_code(), // output [2:0] + .stat_rx_bad_fcs(), // output [2:0] + .stat_rx_bad_preamble(), // output + .stat_rx_bad_sfd(), // output + .stat_rx_bip_err_0(), // output + .stat_rx_bip_err_1(), // output + .stat_rx_bip_err_10(), // output + .stat_rx_bip_err_11(), // output + .stat_rx_bip_err_12(), // output + .stat_rx_bip_err_13(), // output + .stat_rx_bip_err_14(), // output + .stat_rx_bip_err_15(), // output + .stat_rx_bip_err_16(), // output + .stat_rx_bip_err_17(), // output + .stat_rx_bip_err_18(), // output + .stat_rx_bip_err_19(), // output + .stat_rx_bip_err_2(), // output + .stat_rx_bip_err_3(), // output + .stat_rx_bip_err_4(), // output + .stat_rx_bip_err_5(), // output + .stat_rx_bip_err_6(), // output + .stat_rx_bip_err_7(), // output + .stat_rx_bip_err_8(), // output + .stat_rx_bip_err_9(), // output + .stat_rx_block_lock(), // output [19:0] + .stat_rx_broadcast(), // output + .stat_rx_fragment(), // output [2:0] + .stat_rx_framing_err_0(), // output [1:0] + .stat_rx_framing_err_1(), // output [1:0] + .stat_rx_framing_err_10(), // output [1:0] + .stat_rx_framing_err_11(), // output [1:0] + .stat_rx_framing_err_12(), // output [1:0] + .stat_rx_framing_err_13(), // output [1:0] + .stat_rx_framing_err_14(), // output [1:0] + .stat_rx_framing_err_15(), // output [1:0] + .stat_rx_framing_err_16(), // output [1:0] + .stat_rx_framing_err_17(), // output [1:0] + .stat_rx_framing_err_18(), // output [1:0] + .stat_rx_framing_err_19(), // output [1:0] + .stat_rx_framing_err_2(), // output [1:0] + .stat_rx_framing_err_3(), // output [1:0] + .stat_rx_framing_err_4(), // output [1:0] + .stat_rx_framing_err_5(), // output [1:0] + .stat_rx_framing_err_6(), // output [1:0] + .stat_rx_framing_err_7(), // output [1:0] + .stat_rx_framing_err_8(), // output [1:0] + .stat_rx_framing_err_9(), // output [1:0] + .stat_rx_framing_err_valid_0(), // output + .stat_rx_framing_err_valid_1(), // output + .stat_rx_framing_err_valid_10(), // output + .stat_rx_framing_err_valid_11(), // output + .stat_rx_framing_err_valid_12(), // output + .stat_rx_framing_err_valid_13(), // output + .stat_rx_framing_err_valid_14(), // output + .stat_rx_framing_err_valid_15(), // output + .stat_rx_framing_err_valid_16(), // output + .stat_rx_framing_err_valid_17(), // output + .stat_rx_framing_err_valid_18(), // output + .stat_rx_framing_err_valid_19(), // output + .stat_rx_framing_err_valid_2(), // output + .stat_rx_framing_err_valid_3(), // output + .stat_rx_framing_err_valid_4(), // output + .stat_rx_framing_err_valid_5(), // output + .stat_rx_framing_err_valid_6(), // output + .stat_rx_framing_err_valid_7(), // output + .stat_rx_framing_err_valid_8(), // output + .stat_rx_framing_err_valid_9(), // output + .stat_rx_got_signal_os(), // output + .stat_rx_hi_ber(), // output + .stat_rx_inrangeerr(), // output + .stat_rx_internal_local_fault(), // output + .stat_rx_jabber(), // output + .stat_rx_local_fault(), // output + .stat_rx_mf_err(), // output [19:0] + .stat_rx_mf_len_err(), // output [19:0] + .stat_rx_mf_repeat_err(), // output [19:0] + .stat_rx_misaligned(), // output + .stat_rx_multicast(), // output + .stat_rx_oversize(), // output + .stat_rx_packet_1024_1518_bytes(), // output + .stat_rx_packet_128_255_bytes(), // output + .stat_rx_packet_1519_1522_bytes(), // output + .stat_rx_packet_1523_1548_bytes(), // output + .stat_rx_packet_1549_2047_bytes(), // output + .stat_rx_packet_2048_4095_bytes(), // output + .stat_rx_packet_256_511_bytes(), // output + .stat_rx_packet_4096_8191_bytes(), // output + .stat_rx_packet_512_1023_bytes(), // output + .stat_rx_packet_64_bytes(), // output + .stat_rx_packet_65_127_bytes(), // output + .stat_rx_packet_8192_9215_bytes(), // output + .stat_rx_packet_bad_fcs(), // output + .stat_rx_packet_large(), // output + .stat_rx_packet_small(), // output [2:0] + + .ctl_rx_enable(1'b1), // input + .ctl_rx_force_resync(1'b0), // input + .ctl_rx_test_pattern(1'b0), // input + .ctl_rsfec_ieee_error_indication_mode(1'b0), // input + .ctl_rx_rsfec_enable(1'b1), // input + .ctl_rx_rsfec_enable_correction(1'b1), // input + .ctl_rx_rsfec_enable_indication(1'b1), // input + .core_rx_reset(1'b0), // input + .rx_clk(qsfp3_rx_clk_int), // input + + .stat_rx_received_local_fault(), // output + .stat_rx_remote_fault(), // output + .stat_rx_status(qsfp3_rx_status), // output + .stat_rx_stomped_fcs(), // output [2:0] + .stat_rx_synced(), // output [19:0] + .stat_rx_synced_err(), // output [19:0] + .stat_rx_test_pattern_mismatch(), // output [2:0] + .stat_rx_toolong(), // output + .stat_rx_total_bytes(), // output [6:0] + .stat_rx_total_good_bytes(), // output [13:0] + .stat_rx_total_good_packets(), // output + .stat_rx_total_packets(), // output [2:0] + .stat_rx_truncated(), // output + .stat_rx_undersize(), // output [2:0] + .stat_rx_unicast(), // output + .stat_rx_vlan(), // output + .stat_rx_pcsl_demuxed(), // output [19:0] + .stat_rx_pcsl_number_0(), // output [4:0] + .stat_rx_pcsl_number_1(), // output [4:0] + .stat_rx_pcsl_number_10(), // output [4:0] + .stat_rx_pcsl_number_11(), // output [4:0] + .stat_rx_pcsl_number_12(), // output [4:0] + .stat_rx_pcsl_number_13(), // output [4:0] + .stat_rx_pcsl_number_14(), // output [4:0] + .stat_rx_pcsl_number_15(), // output [4:0] + .stat_rx_pcsl_number_16(), // output [4:0] + .stat_rx_pcsl_number_17(), // output [4:0] + .stat_rx_pcsl_number_18(), // output [4:0] + .stat_rx_pcsl_number_19(), // output [4:0] + .stat_rx_pcsl_number_2(), // output [4:0] + .stat_rx_pcsl_number_3(), // output [4:0] + .stat_rx_pcsl_number_4(), // output [4:0] + .stat_rx_pcsl_number_5(), // output [4:0] + .stat_rx_pcsl_number_6(), // output [4:0] + .stat_rx_pcsl_number_7(), // output [4:0] + .stat_rx_pcsl_number_8(), // output [4:0] + .stat_rx_pcsl_number_9(), // output [4:0] + .stat_rx_rsfec_am_lock0(), // output + .stat_rx_rsfec_am_lock1(), // output + .stat_rx_rsfec_am_lock2(), // output + .stat_rx_rsfec_am_lock3(), // output + .stat_rx_rsfec_corrected_cw_inc(), // output + .stat_rx_rsfec_cw_inc(), // output + .stat_rx_rsfec_err_count0_inc(), // output [2:0] + .stat_rx_rsfec_err_count1_inc(), // output [2:0] + .stat_rx_rsfec_err_count2_inc(), // output [2:0] + .stat_rx_rsfec_err_count3_inc(), // output [2:0] + .stat_rx_rsfec_hi_ser(), // output + .stat_rx_rsfec_lane_alignment_status(), // output + .stat_rx_rsfec_lane_fill_0(), // output [13:0] + .stat_rx_rsfec_lane_fill_1(), // output [13:0] + .stat_rx_rsfec_lane_fill_2(), // output [13:0] + .stat_rx_rsfec_lane_fill_3(), // output [13:0] + .stat_rx_rsfec_lane_mapping(), // output [7:0] + .stat_rx_rsfec_uncorrected_cw_inc(), // output + + .ctl_tx_systemtimerin(qsfp3_tx_ptp_time_int), // input [79:0] + + .stat_tx_ptp_fifo_read_error(), // output + .stat_tx_ptp_fifo_write_error(), // output + + .tx_ptp_tstamp_valid_out(qsfp3_tx_ptp_ts_valid_int), // output + .tx_ptp_pcslane_out(), // output [4:0] + .tx_ptp_tstamp_tag_out(qsfp3_tx_ptp_ts_tag_int), // output [15:0] + .tx_ptp_tstamp_out(qsfp3_tx_ptp_ts_int), // output [79:0] + .tx_ptp_1588op_in(2'b10), // input [1:0] + .tx_ptp_tag_field_in(qsfp3_mac_tx_axis_tuser[16:1]), // input [15:0] + + .stat_tx_bad_fcs(), // output + .stat_tx_broadcast(), // output + .stat_tx_frame_error(), // output + .stat_tx_local_fault(), // output + .stat_tx_multicast(), // output + .stat_tx_packet_1024_1518_bytes(), // output + .stat_tx_packet_128_255_bytes(), // output + .stat_tx_packet_1519_1522_bytes(), // output + .stat_tx_packet_1523_1548_bytes(), // output + .stat_tx_packet_1549_2047_bytes(), // output + .stat_tx_packet_2048_4095_bytes(), // output + .stat_tx_packet_256_511_bytes(), // output + .stat_tx_packet_4096_8191_bytes(), // output + .stat_tx_packet_512_1023_bytes(), // output + .stat_tx_packet_64_bytes(), // output + .stat_tx_packet_65_127_bytes(), // output + .stat_tx_packet_8192_9215_bytes(), // output + .stat_tx_packet_large(), // output + .stat_tx_packet_small(), // output + .stat_tx_total_bytes(), // output [5:0] + .stat_tx_total_good_bytes(), // output [13:0] + .stat_tx_total_good_packets(), // output + .stat_tx_total_packets(), // output + .stat_tx_unicast(), // output + .stat_tx_vlan(), // output + + .ctl_tx_enable(1'b1), // input + .ctl_tx_test_pattern(1'b0), // input + .ctl_tx_rsfec_enable(1'b1), // input + .ctl_tx_send_idle(1'b0), // input + .ctl_tx_send_rfi(1'b0), // input + .ctl_tx_send_lfi(1'b0), // input + .core_tx_reset(1'b0), // input + + .tx_axis_tready(qsfp3_mac_tx_axis_tready), // output + .tx_axis_tvalid(qsfp3_mac_tx_axis_tvalid), // input + .tx_axis_tdata(qsfp3_mac_tx_axis_tdata), // input [511:0] + .tx_axis_tlast(qsfp3_mac_tx_axis_tlast), // input + .tx_axis_tkeep(qsfp3_mac_tx_axis_tkeep), // input [63:0] + .tx_axis_tuser(qsfp3_mac_tx_axis_tuser[0]), // input + + .tx_ovfout(), // output + .tx_unfout(), // output + .tx_preamblein(56'd0), // input [55:0] + .usr_tx_reset(qsfp3_tx_rst_int), // output + + .core_drp_reset(1'b0), // input + .drp_clk(1'b0), // input + .drp_addr(10'd0), // input [9:0] + .drp_di(16'd0), // input [15:0] + .drp_en(1'b0), // input + .drp_do(), // output [15:0] + .drp_rdy(), // output + .drp_we(1'b0) // input +); + +wire [3:0] led_int; + +assign led[0] = !qsfp0_rx_status; +assign led[1] = !qsfp1_rx_status; +assign led[2] = !qsfp2_rx_status; +assign led[3] = led_int[3]; + +fpga_core #( + // FW and board IDs + .FPGA_ID(FPGA_ID), + .FW_ID(FW_ID), + .FW_VER(FW_VER), + .BOARD_ID(BOARD_ID), + .BOARD_VER(BOARD_VER), + .BUILD_DATE(BUILD_DATE), + .GIT_HASH(GIT_HASH), + .RELEASE_INFO(RELEASE_INFO), + + // Structural configuration + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + .SCHED_PER_IF(SCHED_PER_IF), + .PORT_MASK(PORT_MASK), + + // PTP configuration + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .PTP_PERIOD_NS_WIDTH(PTP_PERIOD_NS_WIDTH), + .PTP_OFFSET_NS_WIDTH(PTP_OFFSET_NS_WIDTH), + .PTP_FNS_WIDTH(PTP_FNS_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_CLOCK_PIPELINE(PTP_CLOCK_PIPELINE), + .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), + .PTP_PORT_CDC_PIPELINE(PTP_PORT_CDC_PIPELINE), + .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), + .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), + + // Queue manager configuration (interface) + .EVENT_QUEUE_OP_TABLE_SIZE(EVENT_QUEUE_OP_TABLE_SIZE), + .TX_QUEUE_OP_TABLE_SIZE(TX_QUEUE_OP_TABLE_SIZE), + .RX_QUEUE_OP_TABLE_SIZE(RX_QUEUE_OP_TABLE_SIZE), + .TX_CPL_QUEUE_OP_TABLE_SIZE(TX_CPL_QUEUE_OP_TABLE_SIZE), + .RX_CPL_QUEUE_OP_TABLE_SIZE(RX_CPL_QUEUE_OP_TABLE_SIZE), + .EVENT_QUEUE_INDEX_WIDTH(EVENT_QUEUE_INDEX_WIDTH), + .TX_QUEUE_INDEX_WIDTH(TX_QUEUE_INDEX_WIDTH), + .RX_QUEUE_INDEX_WIDTH(RX_QUEUE_INDEX_WIDTH), + .TX_CPL_QUEUE_INDEX_WIDTH(TX_CPL_QUEUE_INDEX_WIDTH), + .RX_CPL_QUEUE_INDEX_WIDTH(RX_CPL_QUEUE_INDEX_WIDTH), + .EVENT_QUEUE_PIPELINE(EVENT_QUEUE_PIPELINE), + .TX_QUEUE_PIPELINE(TX_QUEUE_PIPELINE), + .RX_QUEUE_PIPELINE(RX_QUEUE_PIPELINE), + .TX_CPL_QUEUE_PIPELINE(TX_CPL_QUEUE_PIPELINE), + .RX_CPL_QUEUE_PIPELINE(RX_CPL_QUEUE_PIPELINE), + + // TX and RX engine configuration (port) + .TX_DESC_TABLE_SIZE(TX_DESC_TABLE_SIZE), + .RX_DESC_TABLE_SIZE(RX_DESC_TABLE_SIZE), + + // Scheduler configuration (port) + .TX_SCHEDULER_OP_TABLE_SIZE(TX_SCHEDULER_OP_TABLE_SIZE), + .TX_SCHEDULER_PIPELINE(TX_SCHEDULER_PIPELINE), + .TDMA_INDEX_WIDTH(TDMA_INDEX_WIDTH), + + // Timestamping configuration (port) + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TS_FIFO_DEPTH(TX_PTP_TS_FIFO_DEPTH), + .RX_PTP_TS_FIFO_DEPTH(RX_PTP_TS_FIFO_DEPTH), + + // Interface configuration (port) + .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), + .RX_RSS_ENABLE(RX_RSS_ENABLE), + .RX_HASH_ENABLE(RX_HASH_ENABLE), + .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .TX_FIFO_DEPTH(TX_FIFO_DEPTH), + .RX_FIFO_DEPTH(RX_FIFO_DEPTH), + .MAX_TX_SIZE(MAX_TX_SIZE), + .MAX_RX_SIZE(MAX_RX_SIZE), + .TX_RAM_SIZE(TX_RAM_SIZE), + .RX_RAM_SIZE(RX_RAM_SIZE), + + // Application block configuration + .APP_ENABLE(APP_ENABLE), + .APP_CTRL_ENABLE(APP_CTRL_ENABLE), + .APP_DMA_ENABLE(APP_DMA_ENABLE), + .APP_AXIS_DIRECT_ENABLE(APP_AXIS_DIRECT_ENABLE), + .APP_AXIS_SYNC_ENABLE(APP_AXIS_SYNC_ENABLE), + .APP_AXIS_IF_ENABLE(APP_AXIS_IF_ENABLE), + .APP_STAT_ENABLE(APP_STAT_ENABLE), + + // DMA interface configuration + .DMA_LEN_WIDTH(DMA_LEN_WIDTH), + .DMA_TAG_WIDTH(DMA_TAG_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), + .RAM_PIPELINE(RAM_PIPELINE), + + // PCIe interface configuration + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .PF_COUNT(PF_COUNT), + .VF_COUNT(VF_COUNT), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .PCIE_DMA_READ_OP_TABLE_SIZE(PCIE_DMA_READ_OP_TABLE_SIZE), + .PCIE_DMA_READ_TX_LIMIT(PCIE_DMA_READ_TX_LIMIT), + .PCIE_DMA_READ_TX_FC_ENABLE(PCIE_DMA_READ_TX_FC_ENABLE), + .PCIE_DMA_WRITE_OP_TABLE_SIZE(PCIE_DMA_WRITE_OP_TABLE_SIZE), + .PCIE_DMA_WRITE_TX_LIMIT(PCIE_DMA_WRITE_TX_LIMIT), + .PCIE_DMA_WRITE_TX_FC_ENABLE(PCIE_DMA_WRITE_TX_FC_ENABLE), + .MSI_COUNT(MSI_COUNT), + + // AXI lite interface configuration (control) + .AXIL_CTRL_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .AXIL_CTRL_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH), + + // AXI lite interface configuration (application control) + .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), + .AXIL_APP_CTRL_ADDR_WIDTH(AXIL_APP_CTRL_ADDR_WIDTH), + + // Ethernet interface configuration + .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .AXIS_ETH_SYNC_DATA_WIDTH(AXIS_ETH_SYNC_DATA_WIDTH), + .AXIS_ETH_TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .AXIS_ETH_RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .AXIS_ETH_TX_PIPELINE(AXIS_ETH_TX_PIPELINE), + .AXIS_ETH_TX_FIFO_PIPELINE(AXIS_ETH_TX_FIFO_PIPELINE), + .AXIS_ETH_TX_TS_PIPELINE(AXIS_ETH_TX_TS_PIPELINE), + .AXIS_ETH_RX_PIPELINE(AXIS_ETH_RX_PIPELINE), + .AXIS_ETH_RX_FIFO_PIPELINE(AXIS_ETH_RX_FIFO_PIPELINE), + + // Statistics counter subsystem + .STAT_ENABLE(STAT_ENABLE), + .STAT_DMA_ENABLE(STAT_DMA_ENABLE), + .STAT_PCIE_ENABLE(STAT_PCIE_ENABLE), + .STAT_INC_WIDTH(STAT_INC_WIDTH), + .STAT_ID_WIDTH(STAT_ID_WIDTH) +) +core_inst ( + /* + * Clock: 250 MHz + * Synchronous reset + */ + .clk_250mhz(pcie_user_clk), + .rst_250mhz(pcie_user_reset), + + /* + * GPIO + */ + .led(led_int), + + /* + * I2C + */ + .eeprom_i2c_scl_i(eeprom_i2c_scl_i), + .eeprom_i2c_scl_o(eeprom_i2c_scl_o), + .eeprom_i2c_scl_t(eeprom_i2c_scl_t), + .eeprom_i2c_sda_i(eeprom_i2c_sda_i), + .eeprom_i2c_sda_o(eeprom_i2c_sda_o), + .eeprom_i2c_sda_t(eeprom_i2c_sda_t), + + /* + * PCIe + */ + .m_axis_rq_tdata(axis_rq_tdata), + .m_axis_rq_tkeep(axis_rq_tkeep), + .m_axis_rq_tlast(axis_rq_tlast), + .m_axis_rq_tready(axis_rq_tready), + .m_axis_rq_tuser(axis_rq_tuser), + .m_axis_rq_tvalid(axis_rq_tvalid), + + .s_axis_rc_tdata(axis_rc_tdata), + .s_axis_rc_tkeep(axis_rc_tkeep), + .s_axis_rc_tlast(axis_rc_tlast), + .s_axis_rc_tready(axis_rc_tready), + .s_axis_rc_tuser(axis_rc_tuser), + .s_axis_rc_tvalid(axis_rc_tvalid), + + .s_axis_cq_tdata(axis_cq_tdata), + .s_axis_cq_tkeep(axis_cq_tkeep), + .s_axis_cq_tlast(axis_cq_tlast), + .s_axis_cq_tready(axis_cq_tready), + .s_axis_cq_tuser(axis_cq_tuser), + .s_axis_cq_tvalid(axis_cq_tvalid), + + .m_axis_cc_tdata(axis_cc_tdata), + .m_axis_cc_tkeep(axis_cc_tkeep), + .m_axis_cc_tlast(axis_cc_tlast), + .m_axis_cc_tready(axis_cc_tready), + .m_axis_cc_tuser(axis_cc_tuser), + .m_axis_cc_tvalid(axis_cc_tvalid), + + .s_axis_rq_seq_num_0(pcie_rq_seq_num0), + .s_axis_rq_seq_num_valid_0(pcie_rq_seq_num_vld0), + .s_axis_rq_seq_num_1(pcie_rq_seq_num1), + .s_axis_rq_seq_num_valid_1(pcie_rq_seq_num_vld1), + + .pcie_tfc_nph_av(pcie_tfc_nph_av), + .pcie_tfc_npd_av(pcie_tfc_npd_av), + + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor), + + /* + * Ethernet: QSFP28 + */ + .qsfp0_tx_clk(qsfp0_tx_clk_int), + .qsfp0_tx_rst(qsfp0_tx_rst_int), + .qsfp0_tx_axis_tdata(qsfp0_tx_axis_tdata_int), + .qsfp0_tx_axis_tkeep(qsfp0_tx_axis_tkeep_int), + .qsfp0_tx_axis_tvalid(qsfp0_tx_axis_tvalid_int), + .qsfp0_tx_axis_tready(qsfp0_tx_axis_tready_int), + .qsfp0_tx_axis_tlast(qsfp0_tx_axis_tlast_int), + .qsfp0_tx_axis_tuser(qsfp0_tx_axis_tuser_int), + .qsfp0_tx_ptp_time(qsfp0_tx_ptp_time_int), + .qsfp0_tx_ptp_ts(qsfp0_tx_ptp_ts_int), + .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), + .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + + .qsfp0_rx_clk(qsfp0_rx_clk_int), + .qsfp0_rx_rst(qsfp0_rx_rst_int), + .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), + .qsfp0_rx_axis_tkeep(qsfp0_rx_axis_tkeep_int), + .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid_int), + .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast_int), + .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser_int), + .qsfp0_rx_ptp_clk(qsfp0_rx_ptp_clk_int), + .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), + .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + + .qsfp0_modprsl(qsfp0_modprsl_int), + .qsfp0_resetl(qsfp0_resetl), + .qsfp0_intl(qsfp0_intl_int), + .qsfp0_lpmode(qsfp0_lpmode), + + .qsfp0_i2c_scl_i(qsfp0_i2c_scl_i), + .qsfp0_i2c_scl_o(qsfp0_i2c_scl_o), + .qsfp0_i2c_scl_t(qsfp0_i2c_scl_t), + .qsfp0_i2c_sda_i(qsfp0_i2c_sda_i), + .qsfp0_i2c_sda_o(qsfp0_i2c_sda_o), + .qsfp0_i2c_sda_t(qsfp0_i2c_sda_t), + + .qsfp1_tx_clk(qsfp1_tx_clk_int), + .qsfp1_tx_rst(qsfp1_tx_rst_int), + .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata_int), + .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep_int), + .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid_int), + .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready_int), + .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast_int), + .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser_int), + .qsfp1_tx_ptp_time(qsfp1_tx_ptp_time_int), + .qsfp1_tx_ptp_ts(qsfp1_tx_ptp_ts_int), + .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), + .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + + .qsfp1_rx_clk(qsfp1_rx_clk_int), + .qsfp1_rx_rst(qsfp1_rx_rst_int), + .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), + .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep_int), + .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid_int), + .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast_int), + .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser_int), + .qsfp1_rx_ptp_clk(qsfp1_rx_ptp_clk_int), + .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), + .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + + .qsfp1_modprsl(qsfp1_modprsl_int), + .qsfp1_resetl(qsfp1_resetl), + .qsfp1_intl(qsfp1_intl_int), + .qsfp1_lpmode(qsfp1_lpmode), + + .qsfp1_i2c_scl_i(qsfp1_i2c_scl_i), + .qsfp1_i2c_scl_o(qsfp1_i2c_scl_o), + .qsfp1_i2c_scl_t(qsfp1_i2c_scl_t), + .qsfp1_i2c_sda_i(qsfp1_i2c_sda_i), + .qsfp1_i2c_sda_o(qsfp1_i2c_sda_o), + .qsfp1_i2c_sda_t(qsfp1_i2c_sda_t), + + .qsfp2_tx_clk(qsfp2_tx_clk_int), + .qsfp2_tx_rst(qsfp2_tx_rst_int), + .qsfp2_tx_axis_tdata(qsfp2_tx_axis_tdata_int), + .qsfp2_tx_axis_tkeep(qsfp2_tx_axis_tkeep_int), + .qsfp2_tx_axis_tvalid(qsfp2_tx_axis_tvalid_int), + .qsfp2_tx_axis_tready(qsfp2_tx_axis_tready_int), + .qsfp2_tx_axis_tlast(qsfp2_tx_axis_tlast_int), + .qsfp2_tx_axis_tuser(qsfp2_tx_axis_tuser_int), + .qsfp2_tx_ptp_time(qsfp2_tx_ptp_time_int), + .qsfp2_tx_ptp_ts(qsfp2_tx_ptp_ts_int), + .qsfp2_tx_ptp_ts_tag(qsfp2_tx_ptp_ts_tag_int), + .qsfp2_tx_ptp_ts_valid(qsfp2_tx_ptp_ts_valid_int), + + .qsfp2_rx_clk(qsfp2_rx_clk_int), + .qsfp2_rx_rst(qsfp2_rx_rst_int), + .qsfp2_rx_axis_tdata(qsfp2_rx_axis_tdata_int), + .qsfp2_rx_axis_tkeep(qsfp2_rx_axis_tkeep_int), + .qsfp2_rx_axis_tvalid(qsfp2_rx_axis_tvalid_int), + .qsfp2_rx_axis_tlast(qsfp2_rx_axis_tlast_int), + .qsfp2_rx_axis_tuser(qsfp2_rx_axis_tuser_int), + .qsfp2_rx_ptp_clk(qsfp2_rx_ptp_clk_int), + .qsfp2_rx_ptp_rst(qsfp2_rx_ptp_rst_int), + .qsfp2_rx_ptp_time(qsfp2_rx_ptp_time_int), + + .qsfp2_modprsl(qsfp2_modprsl_int), + .qsfp2_resetl(qsfp2_resetl), + .qsfp2_intl(qsfp2_intl_int), + .qsfp2_lpmode(qsfp2_lpmode), + + .qsfp2_i2c_scl_i(qsfp2_i2c_scl_i), + .qsfp2_i2c_scl_o(qsfp2_i2c_scl_o), + .qsfp2_i2c_scl_t(qsfp2_i2c_scl_t), + .qsfp2_i2c_sda_i(qsfp2_i2c_sda_i), + .qsfp2_i2c_sda_o(qsfp2_i2c_sda_o), + .qsfp2_i2c_sda_t(qsfp2_i2c_sda_t), + + .qsfp3_tx_clk(qsfp3_tx_clk_int), + .qsfp3_tx_rst(qsfp3_tx_rst_int), + .qsfp3_tx_axis_tdata(qsfp3_tx_axis_tdata_int), + .qsfp3_tx_axis_tkeep(qsfp3_tx_axis_tkeep_int), + .qsfp3_tx_axis_tvalid(qsfp3_tx_axis_tvalid_int), + .qsfp3_tx_axis_tready(qsfp3_tx_axis_tready_int), + .qsfp3_tx_axis_tlast(qsfp3_tx_axis_tlast_int), + .qsfp3_tx_axis_tuser(qsfp3_tx_axis_tuser_int), + .qsfp3_tx_ptp_time(qsfp3_tx_ptp_time_int), + .qsfp3_tx_ptp_ts(qsfp3_tx_ptp_ts_int), + .qsfp3_tx_ptp_ts_tag(qsfp3_tx_ptp_ts_tag_int), + .qsfp3_tx_ptp_ts_valid(qsfp3_tx_ptp_ts_valid_int), + + .qsfp3_rx_clk(qsfp3_rx_clk_int), + .qsfp3_rx_rst(qsfp3_rx_rst_int), + .qsfp3_rx_axis_tdata(qsfp3_rx_axis_tdata_int), + .qsfp3_rx_axis_tkeep(qsfp3_rx_axis_tkeep_int), + .qsfp3_rx_axis_tvalid(qsfp3_rx_axis_tvalid_int), + .qsfp3_rx_axis_tlast(qsfp3_rx_axis_tlast_int), + .qsfp3_rx_axis_tuser(qsfp3_rx_axis_tuser_int), + .qsfp3_rx_ptp_clk(qsfp3_rx_ptp_clk_int), + .qsfp3_rx_ptp_rst(qsfp3_rx_ptp_rst_int), + .qsfp3_rx_ptp_time(qsfp3_rx_ptp_time_int), + + .qsfp3_modprsl(qsfp3_modprsl_int), + .qsfp3_resetl(qsfp3_resetl), + .qsfp3_intl(qsfp3_intl_int), + .qsfp3_lpmode(qsfp3_lpmode), + + .qsfp3_i2c_scl_i(qsfp3_i2c_scl_i), + .qsfp3_i2c_scl_o(qsfp3_i2c_scl_o), + .qsfp3_i2c_scl_t(qsfp3_i2c_scl_t), + .qsfp3_i2c_sda_i(qsfp3_i2c_sda_i), + .qsfp3_i2c_sda_o(qsfp3_i2c_sda_o), + .qsfp3_i2c_sda_t(qsfp3_i2c_sda_t), + + /* + * QSPI flash + */ + .fpga_boot(fpga_boot), + .qspi_clk(qspi_clk_int), + .qspi_dq_i(qspi_dq_i_int), + .qspi_dq_o(qspi_dq_o_int), + .qspi_dq_oe(qspi_dq_oe_int), + .qspi_cs(qspi_cs_int) +); + +endmodule + +`resetall diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v new file mode 100644 index 000000000..38eef2e3b --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v @@ -0,0 +1,1346 @@ +/* + +Copyright 2019-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. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + // FW and board IDs + parameter FPGA_ID = 32'h4B31093, + parameter FW_ID = 32'h00000000, + parameter FW_VER = 32'h00_00_01_00, + parameter BOARD_ID = 32'h12ba_9823, + parameter BOARD_VER = 32'h01_00_00_00, + parameter BUILD_DATE = 32'd602976000, + parameter GIT_HASH = 32'hdce357bf, + parameter RELEASE_INFO = 32'h00000000, + + // Structural configuration + parameter IF_COUNT = 2, + parameter PORTS_PER_IF = 1, + parameter SCHED_PER_IF = PORTS_PER_IF, + parameter PORT_MASK = 0, + + // PTP configuration + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_WIDTH = 16, + parameter PTP_PERIOD_NS_WIDTH = 4, + parameter PTP_OFFSET_NS_WIDTH = 32, + parameter PTP_FNS_WIDTH = 32, + parameter PTP_PERIOD_NS = 4'd4, + parameter PTP_PERIOD_FNS = 32'd0, + parameter PTP_CLOCK_PIPELINE = 0, + parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_SEPARATE_RX_CLOCK = 0, + parameter PTP_PORT_CDC_PIPELINE = 0, + parameter PTP_PEROUT_ENABLE = 0, + parameter PTP_PEROUT_COUNT = 1, + + // Queue manager configuration (interface) + parameter EVENT_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_QUEUE_OP_TABLE_SIZE = 32, + parameter RX_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_CPL_QUEUE_OP_TABLE_SIZE = TX_QUEUE_OP_TABLE_SIZE, + parameter RX_CPL_QUEUE_OP_TABLE_SIZE = RX_QUEUE_OP_TABLE_SIZE, + parameter EVENT_QUEUE_INDEX_WIDTH = 5, + parameter TX_QUEUE_INDEX_WIDTH = 13, + parameter RX_QUEUE_INDEX_WIDTH = 8, + parameter TX_CPL_QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH, + parameter RX_CPL_QUEUE_INDEX_WIDTH = RX_QUEUE_INDEX_WIDTH, + parameter EVENT_QUEUE_PIPELINE = 3, + parameter TX_QUEUE_PIPELINE = 3+(TX_QUEUE_INDEX_WIDTH > 12 ? TX_QUEUE_INDEX_WIDTH-12 : 0), + parameter RX_QUEUE_PIPELINE = 3+(RX_QUEUE_INDEX_WIDTH > 12 ? RX_QUEUE_INDEX_WIDTH-12 : 0), + parameter TX_CPL_QUEUE_PIPELINE = TX_QUEUE_PIPELINE, + parameter RX_CPL_QUEUE_PIPELINE = RX_QUEUE_PIPELINE, + + // TX and RX engine configuration (port) + parameter TX_DESC_TABLE_SIZE = 32, + parameter RX_DESC_TABLE_SIZE = 32, + + // Scheduler configuration (port) + parameter TX_SCHEDULER_OP_TABLE_SIZE = TX_DESC_TABLE_SIZE, + parameter TX_SCHEDULER_PIPELINE = TX_QUEUE_PIPELINE, + parameter TDMA_INDEX_WIDTH = 6, + + // Timestamping configuration (port) + parameter PTP_TS_ENABLE = 1, + parameter TX_PTP_TS_FIFO_DEPTH = 32, + parameter RX_PTP_TS_FIFO_DEPTH = 32, + + // Interface configuration (port) + parameter TX_CHECKSUM_ENABLE = 1, + parameter RX_RSS_ENABLE = 1, + parameter RX_HASH_ENABLE = 1, + parameter RX_CHECKSUM_ENABLE = 1, + parameter TX_FIFO_DEPTH = 32768, + parameter RX_FIFO_DEPTH = 131072, + parameter MAX_TX_SIZE = 9214, + parameter MAX_RX_SIZE = 9214, + parameter TX_RAM_SIZE = 131072, + parameter RX_RAM_SIZE = 131072, + + // Application block configuration + parameter APP_ENABLE = 0, + parameter APP_CTRL_ENABLE = 1, + parameter APP_DMA_ENABLE = 1, + parameter APP_AXIS_DIRECT_ENABLE = 1, + parameter APP_AXIS_SYNC_ENABLE = 1, + parameter APP_AXIS_IF_ENABLE = 1, + parameter APP_STAT_ENABLE = 1, + + // DMA interface configuration + parameter DMA_LEN_WIDTH = 16, + parameter DMA_TAG_WIDTH = 16, + parameter RAM_ADDR_WIDTH = $clog2(TX_RAM_SIZE > RX_RAM_SIZE ? TX_RAM_SIZE : RX_RAM_SIZE), + parameter RAM_PIPELINE = 2, + + // PCIe interface configuration + parameter AXIS_PCIE_DATA_WIDTH = 512, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161, + parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 62 : 137, + parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183, + parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter PF_COUNT = 1, + parameter VF_COUNT = 0, + parameter PCIE_TAG_COUNT = 64, + parameter PCIE_DMA_READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + parameter PCIE_DMA_READ_TX_LIMIT = 16, + parameter PCIE_DMA_READ_TX_FC_ENABLE = 1, + parameter PCIE_DMA_WRITE_OP_TABLE_SIZE = 16, + parameter PCIE_DMA_WRITE_TX_LIMIT = 3, + parameter PCIE_DMA_WRITE_TX_FC_ENABLE = 1, + parameter MSI_COUNT = 32, + + // AXI lite interface configuration (control) + parameter AXIL_CTRL_DATA_WIDTH = 32, + parameter AXIL_CTRL_ADDR_WIDTH = 24, + + // AXI lite interface configuration (application control) + parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, + parameter AXIL_APP_CTRL_ADDR_WIDTH = 24, + + // Ethernet interface configuration + parameter AXIS_ETH_DATA_WIDTH = 512, + parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8, + parameter AXIS_ETH_SYNC_DATA_WIDTH = AXIS_ETH_DATA_WIDTH, + parameter AXIS_ETH_TX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TAG_WIDTH : 0) + 1, + parameter AXIS_ETH_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, + parameter AXIS_ETH_TX_PIPELINE = 4, + parameter AXIS_ETH_TX_FIFO_PIPELINE = 4, + parameter AXIS_ETH_TX_TS_PIPELINE = 4, + parameter AXIS_ETH_RX_PIPELINE = 4, + parameter AXIS_ETH_RX_FIFO_PIPELINE = 4, + + // Statistics counter subsystem + parameter STAT_ENABLE = 1, + parameter STAT_DMA_ENABLE = 1, + parameter STAT_PCIE_ENABLE = 1, + parameter STAT_INC_WIDTH = 24, + parameter STAT_ID_WIDTH = 12 +) +( + /* + * Clock: 250 MHz + * Synchronous reset + */ + input wire clk_250mhz, + input wire rst_250mhz, + + /* + * GPIO + */ + output wire [3:0] led, + + /* + * I2C + */ + input wire eeprom_i2c_scl_i, + output wire eeprom_i2c_scl_o, + output wire eeprom_i2c_scl_t, + input wire eeprom_i2c_sda_i, + output wire eeprom_i2c_sda_o, + output wire eeprom_i2c_sda_t, + + /* + * PCIe + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep, + output wire m_axis_rq_tlast, + input wire m_axis_rq_tready, + output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser, + output wire m_axis_rq_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep, + input wire s_axis_rc_tlast, + output wire s_axis_rc_tready, + input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser, + input wire s_axis_rc_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep, + input wire s_axis_cq_tlast, + output wire s_axis_cq_tready, + input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser, + input wire s_axis_cq_tvalid, + + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep, + output wire m_axis_cc_tlast, + input wire m_axis_cc_tready, + output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser, + output wire m_axis_cc_tvalid, + + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0, + input wire s_axis_rq_seq_num_valid_0, + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1, + input wire s_axis_rq_seq_num_valid_1, + + input wire [1:0] pcie_tfc_nph_av, + input wire [1:0] pcie_tfc_npd_av, + + input wire [2:0] cfg_max_payload, + input wire [2:0] cfg_max_read_req, + + output wire [9:0] cfg_mgmt_addr, + output wire [7:0] cfg_mgmt_function_number, + output wire cfg_mgmt_write, + output wire [31:0] cfg_mgmt_write_data, + output wire [3:0] cfg_mgmt_byte_enable, + output wire cfg_mgmt_read, + input wire [31:0] cfg_mgmt_read_data, + input wire cfg_mgmt_read_write_done, + + input wire [7:0] cfg_fc_ph, + input wire [11:0] cfg_fc_pd, + input wire [7:0] cfg_fc_nph, + input wire [11:0] cfg_fc_npd, + input wire [7:0] cfg_fc_cplh, + input wire [11:0] cfg_fc_cpld, + output wire [2:0] cfg_fc_sel, + + input wire [3:0] cfg_interrupt_msi_enable, + input wire [11:0] cfg_interrupt_msi_mmenable, + input wire cfg_interrupt_msi_mask_update, + input wire [31:0] cfg_interrupt_msi_data, + output wire [3:0] cfg_interrupt_msi_select, + output wire [31:0] cfg_interrupt_msi_int, + output wire [31:0] cfg_interrupt_msi_pending_status, + output wire cfg_interrupt_msi_pending_status_data_enable, + output wire [3:0] cfg_interrupt_msi_pending_status_function_num, + input wire cfg_interrupt_msi_sent, + input wire cfg_interrupt_msi_fail, + output wire [2:0] cfg_interrupt_msi_attr, + output wire cfg_interrupt_msi_tph_present, + output wire [1:0] cfg_interrupt_msi_tph_type, + output wire [8:0] cfg_interrupt_msi_tph_st_tag, + output wire [3:0] cfg_interrupt_msi_function_number, + + output wire status_error_cor, + output wire status_error_uncor, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp0_tx_clk, + input wire qsfp0_tx_rst, + + output wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata, + output wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep, + output wire qsfp0_tx_axis_tvalid, + input wire qsfp0_tx_axis_tready, + output wire qsfp0_tx_axis_tlast, + output wire [16+1-1:0] qsfp0_tx_axis_tuser, + + output wire [79:0] qsfp0_tx_ptp_time, + input wire [79:0] qsfp0_tx_ptp_ts, + input wire [15:0] qsfp0_tx_ptp_ts_tag, + input wire qsfp0_tx_ptp_ts_valid, + + input wire qsfp0_rx_clk, + input wire qsfp0_rx_rst, + + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata, + input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep, + input wire qsfp0_rx_axis_tvalid, + input wire qsfp0_rx_axis_tlast, + input wire [80+1-1:0] qsfp0_rx_axis_tuser, + + input wire qsfp0_rx_ptp_clk, + input wire qsfp0_rx_ptp_rst, + output wire [79:0] qsfp0_rx_ptp_time, + + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + + input wire qsfp0_i2c_scl_i, + output wire qsfp0_i2c_scl_o, + output wire qsfp0_i2c_scl_t, + input wire qsfp0_i2c_sda_i, + output wire qsfp0_i2c_sda_o, + output wire qsfp0_i2c_sda_t, + + input wire qsfp1_tx_clk, + input wire qsfp1_tx_rst, + + output wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata, + output wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep, + output wire qsfp1_tx_axis_tvalid, + input wire qsfp1_tx_axis_tready, + output wire qsfp1_tx_axis_tlast, + output wire [16+1-1:0] qsfp1_tx_axis_tuser, + + output wire [79:0] qsfp1_tx_ptp_time, + input wire [79:0] qsfp1_tx_ptp_ts, + input wire [15:0] qsfp1_tx_ptp_ts_tag, + input wire qsfp1_tx_ptp_ts_valid, + + input wire qsfp1_rx_clk, + input wire qsfp1_rx_rst, + + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata, + input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep, + input wire qsfp1_rx_axis_tvalid, + input wire qsfp1_rx_axis_tlast, + input wire [80+1-1:0] qsfp1_rx_axis_tuser, + + input wire qsfp1_rx_ptp_clk, + input wire qsfp1_rx_ptp_rst, + output wire [79:0] qsfp1_rx_ptp_time, + + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + + input wire qsfp1_i2c_scl_i, + output wire qsfp1_i2c_scl_o, + output wire qsfp1_i2c_scl_t, + input wire qsfp1_i2c_sda_i, + output wire qsfp1_i2c_sda_o, + output wire qsfp1_i2c_sda_t, + + input wire qsfp2_tx_clk, + input wire qsfp2_tx_rst, + + output wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_tx_axis_tdata, + output wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_tx_axis_tkeep, + output wire qsfp2_tx_axis_tvalid, + input wire qsfp2_tx_axis_tready, + output wire qsfp2_tx_axis_tlast, + output wire [16+1-1:0] qsfp2_tx_axis_tuser, + + output wire [79:0] qsfp2_tx_ptp_time, + input wire [79:0] qsfp2_tx_ptp_ts, + input wire [15:0] qsfp2_tx_ptp_ts_tag, + input wire qsfp2_tx_ptp_ts_valid, + + input wire qsfp2_rx_clk, + input wire qsfp2_rx_rst, + + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_rx_axis_tdata, + input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_rx_axis_tkeep, + input wire qsfp2_rx_axis_tvalid, + input wire qsfp2_rx_axis_tlast, + input wire [80+1-1:0] qsfp2_rx_axis_tuser, + + input wire qsfp2_rx_ptp_clk, + input wire qsfp2_rx_ptp_rst, + output wire [79:0] qsfp2_rx_ptp_time, + + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + + input wire qsfp2_i2c_scl_i, + output wire qsfp2_i2c_scl_o, + output wire qsfp2_i2c_scl_t, + input wire qsfp2_i2c_sda_i, + output wire qsfp2_i2c_sda_o, + output wire qsfp2_i2c_sda_t, + + input wire qsfp3_tx_clk, + input wire qsfp3_tx_rst, + + output wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp3_tx_axis_tdata, + output wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp3_tx_axis_tkeep, + output wire qsfp3_tx_axis_tvalid, + input wire qsfp3_tx_axis_tready, + output wire qsfp3_tx_axis_tlast, + output wire [16+1-1:0] qsfp3_tx_axis_tuser, + + output wire [79:0] qsfp3_tx_ptp_time, + input wire [79:0] qsfp3_tx_ptp_ts, + input wire [15:0] qsfp3_tx_ptp_ts_tag, + input wire qsfp3_tx_ptp_ts_valid, + + input wire qsfp3_rx_clk, + input wire qsfp3_rx_rst, + + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp3_rx_axis_tdata, + input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp3_rx_axis_tkeep, + input wire qsfp3_rx_axis_tvalid, + input wire qsfp3_rx_axis_tlast, + input wire [80+1-1:0] qsfp3_rx_axis_tuser, + + input wire qsfp3_rx_ptp_clk, + input wire qsfp3_rx_ptp_rst, + output wire [79:0] qsfp3_rx_ptp_time, + + output wire qsfp3_resetl, + input wire qsfp3_modprsl, + input wire qsfp3_intl, + output wire qsfp3_lpmode, + + input wire qsfp3_i2c_scl_i, + output wire qsfp3_i2c_scl_o, + output wire qsfp3_i2c_scl_t, + input wire qsfp3_i2c_sda_i, + output wire qsfp3_i2c_sda_o, + output wire qsfp3_i2c_sda_t, + + /* + * QSPI flash + */ + output wire fpga_boot, + output wire qspi_clk, + input wire [3:0] qspi_dq_i, + output wire [3:0] qspi_dq_o, + output wire [3:0] qspi_dq_oe, + output wire qspi_cs +); + +parameter PORT_COUNT = IF_COUNT*PORTS_PER_IF; + +parameter F_COUNT = PF_COUNT+VF_COUNT; + +parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8); +parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); +parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); + +localparam RB_BASE_ADDR = 16'h1000; +localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}}; + +initial begin + if (PORT_COUNT > 4) begin + $error("Error: Max port count exceeded (instance %m)"); + $finish; + end +end + +// PTP +wire [PTP_TS_WIDTH-1:0] ptp_ts_96; +wire ptp_ts_step; +wire ptp_pps; + +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_locked; +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_error; +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_pulse; + +// control registers +wire [AXIL_CSR_ADDR_WIDTH-1:0] ctrl_reg_wr_addr; +wire [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_wr_data; +wire [AXIL_CTRL_STRB_WIDTH-1:0] ctrl_reg_wr_strb; +wire ctrl_reg_wr_en; +wire ctrl_reg_wr_wait; +wire ctrl_reg_wr_ack; +wire [AXIL_CSR_ADDR_WIDTH-1:0] ctrl_reg_rd_addr; +wire ctrl_reg_rd_en; +wire [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_rd_data; +wire ctrl_reg_rd_wait; +wire ctrl_reg_rd_ack; + +reg ctrl_reg_wr_ack_reg = 1'b0; +reg [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = {AXIL_CTRL_DATA_WIDTH{1'b0}}; +reg ctrl_reg_rd_ack_reg = 1'b0; + +reg qsfp0_reset_reg = 1'b0; +reg qsfp1_reset_reg = 1'b0; +reg qsfp2_reset_reg = 1'b0; +reg qsfp3_reset_reg = 1'b0; + +reg qsfp0_lpmode_reg = 1'b0; +reg qsfp1_lpmode_reg = 1'b0; +reg qsfp2_lpmode_reg = 1'b0; +reg qsfp3_lpmode_reg = 1'b0; + +reg eeprom_i2c_scl_o_reg = 1'b1; +reg eeprom_i2c_sda_o_reg = 1'b1; + +reg qsfp0_i2c_scl_o_reg = 1'b1; +reg qsfp0_i2c_sda_o_reg = 1'b1; + +reg qsfp1_i2c_scl_o_reg = 1'b1; +reg qsfp1_i2c_sda_o_reg = 1'b1; + +reg qsfp2_i2c_scl_o_reg = 1'b1; +reg qsfp2_i2c_sda_o_reg = 1'b1; + +reg qsfp3_i2c_scl_o_reg = 1'b1; +reg qsfp3_i2c_sda_o_reg = 1'b1; + +reg fpga_boot_reg = 1'b0; + +reg qspi_clk_reg = 1'b0; +reg qspi_cs_reg = 1'b1; +reg [3:0] qspi_dq_o_reg = 4'd0; +reg [3:0] qspi_dq_oe_reg = 4'd0; + +assign ctrl_reg_wr_wait = 1'b0; +assign ctrl_reg_wr_ack = ctrl_reg_wr_ack_reg; +assign ctrl_reg_rd_data = ctrl_reg_rd_data_reg; +assign ctrl_reg_rd_wait = 1'b0; +assign ctrl_reg_rd_ack = ctrl_reg_rd_ack_reg; + +assign qsfp0_resetl = !qsfp0_reset_reg; +assign qsfp1_resetl = !qsfp1_reset_reg; +assign qsfp2_resetl = !qsfp2_reset_reg; +assign qsfp3_resetl = !qsfp3_reset_reg; + +assign qsfp0_lpmode = qsfp0_lpmode_reg; +assign qsfp1_lpmode = qsfp1_lpmode_reg; +assign qsfp2_lpmode = qsfp2_lpmode_reg; +assign qsfp3_lpmode = qsfp3_lpmode_reg; + +assign eeprom_i2c_scl_o = eeprom_i2c_scl_o_reg; +assign eeprom_i2c_scl_t = eeprom_i2c_scl_o_reg; +assign eeprom_i2c_sda_o = eeprom_i2c_sda_o_reg; +assign eeprom_i2c_sda_t = eeprom_i2c_sda_o_reg; + +assign qsfp0_i2c_scl_o = qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_scl_t = qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_sda_o = qsfp0_i2c_sda_o_reg; +assign qsfp0_i2c_sda_t = qsfp0_i2c_sda_o_reg; + +assign qsfp1_i2c_scl_o = qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_scl_t = qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_sda_o = qsfp1_i2c_sda_o_reg; +assign qsfp1_i2c_sda_t = qsfp1_i2c_sda_o_reg; + +assign qsfp2_i2c_scl_o = qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_scl_t = qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_sda_o = qsfp2_i2c_sda_o_reg; +assign qsfp2_i2c_sda_t = qsfp2_i2c_sda_o_reg; + +assign qsfp3_i2c_scl_o = qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_scl_t = qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_sda_o = qsfp3_i2c_sda_o_reg; +assign qsfp3_i2c_sda_t = qsfp3_i2c_sda_o_reg; + +assign fpga_boot = fpga_boot_reg; + +assign qspi_clk = qspi_clk_reg; +assign qspi_cs = qspi_cs_reg; +assign qspi_dq_o = qspi_dq_o_reg; +assign qspi_dq_oe = qspi_dq_oe_reg; + +always @(posedge clk_250mhz) begin + ctrl_reg_wr_ack_reg <= 1'b0; + ctrl_reg_rd_data_reg <= {AXIL_CTRL_DATA_WIDTH{1'b0}}; + ctrl_reg_rd_ack_reg <= 1'b0; + + if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin + // write operation + ctrl_reg_wr_ack_reg <= 1'b0; + case ({ctrl_reg_wr_addr >> 2, 2'b00}) + // FW ID + 8'h0C: begin + // FW ID: FPGA JTAG ID + fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; + end + // I2C 0 + RBB+8'h0C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp0_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp0_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 1 + RBB+8'h1C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp1_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp1_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 2 + RBB+8'h2C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp2_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp2_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 3 + RBB+8'h3C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp3_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp3_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 4 + RBB+8'h4C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // XCVR GPIO + RBB+8'h5C: begin + // XCVR GPIO: control 0123 + if (ctrl_reg_wr_strb[0]) begin + qsfp0_reset_reg <= ctrl_reg_wr_data[4]; + qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp1_reset_reg <= ctrl_reg_wr_data[12]; + qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; + end + if (ctrl_reg_wr_strb[2]) begin + qsfp2_reset_reg <= ctrl_reg_wr_data[20]; + qsfp2_lpmode_reg <= ctrl_reg_wr_data[21]; + end + if (ctrl_reg_wr_strb[3]) begin + qsfp3_reset_reg <= ctrl_reg_wr_data[28]; + qsfp3_lpmode_reg <= ctrl_reg_wr_data[29]; + end + end + // QSPI flash + RBB+8'h6C: begin + // SPI flash ctrl: format + fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; + end + RBB+8'h70: begin + // SPI flash ctrl: control 0 + if (ctrl_reg_wr_strb[0]) begin + qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; + end + if (ctrl_reg_wr_strb[1]) begin + qspi_dq_oe_reg <= ctrl_reg_wr_data[11:8]; + end + if (ctrl_reg_wr_strb[2]) begin + qspi_clk_reg <= ctrl_reg_wr_data[16]; + qspi_cs_reg <= ctrl_reg_wr_data[17]; + end + end + default: ctrl_reg_wr_ack_reg <= 1'b0; + endcase + end + + if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin + // read operation + ctrl_reg_rd_ack_reg <= 1'b1; + case ({ctrl_reg_rd_addr >> 2, 2'b00}) + // I2C 0 + RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header + RBB+8'h0C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp0_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp0_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp0_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp0_i2c_sda_o_reg; + end + // I2C 1 + RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header + RBB+8'h1C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp1_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp1_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp1_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp1_i2c_sda_o_reg; + end + // I2C 2 + RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // I2C ctrl: Next header + RBB+8'h2C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp2_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp2_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp2_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp2_i2c_sda_o_reg; + end + // I2C 3 + RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // I2C ctrl: Next header + RBB+8'h3C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp3_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp3_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp3_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp3_i2c_sda_o_reg; + end + // I2C 4 + RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h48: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // I2C ctrl: Next header + RBB+8'h4C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; + end + // XCVR GPIO + RBB+8'h50: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type + RBB+8'h54: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version + RBB+8'h58: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h60; // XCVR GPIO: Next header + RBB+8'h5C: begin + // XCVR GPIO: control 0123 + ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; + ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; + ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; + ctrl_reg_rd_data_reg[5] <= qsfp0_lpmode_reg; + ctrl_reg_rd_data_reg[8] <= !qsfp1_modprsl; + ctrl_reg_rd_data_reg[9] <= !qsfp1_intl; + ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; + ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; + ctrl_reg_rd_data_reg[16] <= !qsfp2_modprsl; + ctrl_reg_rd_data_reg[17] <= !qsfp2_intl; + ctrl_reg_rd_data_reg[20] <= qsfp2_reset_reg; + ctrl_reg_rd_data_reg[21] <= qsfp2_lpmode_reg; + ctrl_reg_rd_data_reg[24] <= !qsfp3_modprsl; + ctrl_reg_rd_data_reg[25] <= !qsfp3_intl; + ctrl_reg_rd_data_reg[28] <= qsfp3_reset_reg; + ctrl_reg_rd_data_reg[29] <= qsfp3_lpmode_reg; + end + // QSPI flash + RBB+8'h60: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type + RBB+8'h64: ctrl_reg_rd_data_reg <= 32'h00000200; // SPI flash ctrl: Version + RBB+8'h68: ctrl_reg_rd_data_reg <= 0; // SPI flash ctrl: Next header + RBB+8'h6C: begin + // SPI flash ctrl: format + ctrl_reg_rd_data_reg[3:0] <= 2; // configuration (two segments) + ctrl_reg_rd_data_reg[7:4] <= 0; // default segment + ctrl_reg_rd_data_reg[11:8] <= 1; // fallback segment + ctrl_reg_rd_data_reg[31:12] <= 32'h0C000000 >> 12; // first segment size (192 M) + end + RBB+8'h70: begin + // SPI flash ctrl: control 0 + ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; + ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; + ctrl_reg_rd_data_reg[16] <= qspi_clk; + ctrl_reg_rd_data_reg[17] <= qspi_cs; + end + default: ctrl_reg_rd_ack_reg <= 1'b0; + endcase + end + + if (rst_250mhz) begin + ctrl_reg_wr_ack_reg <= 1'b0; + ctrl_reg_rd_ack_reg <= 1'b0; + + qsfp0_reset_reg <= 1'b0; + qsfp1_reset_reg <= 1'b0; + qsfp2_reset_reg <= 1'b0; + qsfp3_reset_reg <= 1'b0; + + qsfp0_lpmode_reg <= 1'b0; + qsfp1_lpmode_reg <= 1'b0; + qsfp2_lpmode_reg <= 1'b0; + qsfp3_lpmode_reg <= 1'b0; + + eeprom_i2c_scl_o_reg <= 1'b1; + eeprom_i2c_sda_o_reg <= 1'b1; + + qsfp0_i2c_scl_o_reg <= 1'b1; + qsfp0_i2c_sda_o_reg <= 1'b1; + + qsfp1_i2c_scl_o_reg <= 1'b1; + qsfp1_i2c_sda_o_reg <= 1'b1; + + qsfp2_i2c_scl_o_reg <= 1'b1; + qsfp2_i2c_sda_o_reg <= 1'b1; + + qsfp3_i2c_scl_o_reg <= 1'b1; + qsfp3_i2c_sda_o_reg <= 1'b1; + + fpga_boot_reg <= 1'b0; + + qspi_clk_reg <= 1'b0; + qspi_cs_reg <= 1'b1; + qspi_dq_o_reg <= 4'd0; + qspi_dq_oe_reg <= 4'd0; + end +end + +reg [26:0] pps_led_counter_reg = 0; +reg pps_led_reg = 0; + +always @(posedge clk_250mhz) begin + if (ptp_pps) begin + pps_led_counter_reg <= 125000000; + end else if (pps_led_counter_reg > 0) begin + pps_led_counter_reg <= pps_led_counter_reg - 1; + end + + pps_led_reg <= pps_led_counter_reg > 0; +end + +assign led[2:0] = 3'b111; +assign led[3] = !pps_led_reg; + +wire [PORT_COUNT-1:0] eth_tx_clk; +wire [PORT_COUNT-1:0] eth_tx_rst; + +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_tx_ptp_ts_96; +wire [PORT_COUNT-1:0] eth_tx_ptp_ts_step; + +wire [PORT_COUNT*AXIS_ETH_DATA_WIDTH-1:0] axis_eth_tx_tdata; +wire [PORT_COUNT*AXIS_ETH_KEEP_WIDTH-1:0] axis_eth_tx_tkeep; +wire [PORT_COUNT-1:0] axis_eth_tx_tvalid; +wire [PORT_COUNT-1:0] axis_eth_tx_tready; +wire [PORT_COUNT-1:0] axis_eth_tx_tlast; +wire [PORT_COUNT*AXIS_ETH_TX_USER_WIDTH-1:0] axis_eth_tx_tuser; + +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] axis_eth_tx_ptp_ts; +wire [PORT_COUNT*PTP_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; +wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; +wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; + +wire [PORT_COUNT-1:0] eth_rx_clk; +wire [PORT_COUNT-1:0] eth_rx_rst; + +wire [PORT_COUNT-1:0] eth_rx_ptp_clk; +wire [PORT_COUNT-1:0] eth_rx_ptp_rst; +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; +wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; + +wire [PORT_COUNT*AXIS_ETH_DATA_WIDTH-1:0] axis_eth_rx_tdata; +wire [PORT_COUNT*AXIS_ETH_KEEP_WIDTH-1:0] axis_eth_rx_tkeep; +wire [PORT_COUNT-1:0] axis_eth_rx_tvalid; +wire [PORT_COUNT-1:0] axis_eth_rx_tready; +wire [PORT_COUNT-1:0] axis_eth_rx_tlast; +wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; + +wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp2_tx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp3_tx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp0_rx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp1_rx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp2_rx_ptp_time_int; +wire [PTP_TS_WIDTH-1:0] qsfp3_rx_ptp_time_int; + +assign qsfp0_tx_ptp_time = qsfp0_tx_ptp_time_int >> 16; +assign qsfp1_tx_ptp_time = qsfp1_tx_ptp_time_int >> 16; +assign qsfp2_tx_ptp_time = qsfp2_tx_ptp_time_int >> 16; +assign qsfp3_tx_ptp_time = qsfp3_tx_ptp_time_int >> 16; +assign qsfp0_rx_ptp_time = qsfp0_rx_ptp_time_int >> 16; +assign qsfp1_rx_ptp_time = qsfp1_rx_ptp_time_int >> 16; +assign qsfp2_rx_ptp_time = qsfp2_rx_ptp_time_int >> 16; +assign qsfp3_rx_ptp_time = qsfp3_rx_ptp_time_int >> 16; + +mqnic_port_map_mac_axis #( + .MAC_COUNT(4), + .PORT_MASK(PORT_MASK), + .PORT_GROUP_SIZE(1), + + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + + .PORT_COUNT(PORT_COUNT), + + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .AXIS_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .AXIS_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .AXIS_TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .AXIS_RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) +) +mqnic_port_map_mac_axis_inst ( + // towards MAC + .mac_tx_clk({qsfp3_tx_clk, qsfp2_tx_clk, qsfp1_tx_clk, qsfp0_tx_clk}), + .mac_tx_rst({qsfp3_tx_rst, qsfp2_tx_rst, qsfp1_tx_rst, qsfp0_tx_rst}), + + .mac_tx_ptp_ts_96({qsfp3_tx_ptp_time_int, qsfp2_tx_ptp_time_int, qsfp1_tx_ptp_time_int, qsfp0_tx_ptp_time_int}), + .mac_tx_ptp_ts_step(), + + .m_axis_mac_tx_tdata({qsfp3_tx_axis_tdata, qsfp2_tx_axis_tdata, qsfp1_tx_axis_tdata, qsfp0_tx_axis_tdata}), + .m_axis_mac_tx_tkeep({qsfp3_tx_axis_tkeep, qsfp2_tx_axis_tkeep, qsfp1_tx_axis_tkeep, qsfp0_tx_axis_tkeep}), + .m_axis_mac_tx_tvalid({qsfp3_tx_axis_tvalid, qsfp2_tx_axis_tvalid, qsfp1_tx_axis_tvalid, qsfp0_tx_axis_tvalid}), + .m_axis_mac_tx_tready({qsfp3_tx_axis_tready, qsfp2_tx_axis_tready, qsfp1_tx_axis_tready, qsfp0_tx_axis_tready}), + .m_axis_mac_tx_tlast({qsfp3_tx_axis_tlast, qsfp2_tx_axis_tlast, qsfp1_tx_axis_tlast, qsfp0_tx_axis_tlast}), + .m_axis_mac_tx_tuser({qsfp3_tx_axis_tuser, qsfp2_tx_axis_tuser, qsfp1_tx_axis_tuser, qsfp0_tx_axis_tuser}), + + .s_axis_mac_tx_ptp_ts({{qsfp3_tx_ptp_ts, 16'd0}, {qsfp2_tx_ptp_ts, 16'd0}, {qsfp1_tx_ptp_ts, 16'd0}, {qsfp0_tx_ptp_ts, 16'd0}}), + .s_axis_mac_tx_ptp_ts_tag({qsfp3_tx_ptp_ts_tag, qsfp2_tx_ptp_ts_tag, qsfp1_tx_ptp_ts_tag, qsfp0_tx_ptp_ts_tag}), + .s_axis_mac_tx_ptp_ts_valid({qsfp3_tx_ptp_ts_valid, qsfp2_tx_ptp_ts_valid, qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), + .s_axis_mac_tx_ptp_ts_ready(), + + .mac_rx_clk({qsfp3_rx_clk, qsfp2_rx_clk, qsfp1_rx_clk, qsfp0_rx_clk}), + .mac_rx_rst({qsfp3_rx_rst, qsfp2_rx_rst, qsfp1_rx_rst, qsfp0_rx_rst}), + + .mac_rx_ptp_clk({qsfp3_rx_ptp_clk, qsfp2_rx_ptp_clk, qsfp1_rx_ptp_clk, qsfp0_rx_ptp_clk}), + .mac_rx_ptp_rst({qsfp3_rx_ptp_rst, qsfp2_rx_ptp_rst, qsfp1_rx_ptp_rst, qsfp0_rx_ptp_rst}), + .mac_rx_ptp_ts_96({qsfp3_rx_ptp_time_int, qsfp2_rx_ptp_time_int, qsfp1_rx_ptp_time_int, qsfp0_rx_ptp_time_int}), + .mac_rx_ptp_ts_step(), + + .s_axis_mac_rx_tdata({qsfp3_rx_axis_tdata, qsfp2_rx_axis_tdata, qsfp1_rx_axis_tdata, qsfp0_rx_axis_tdata}), + .s_axis_mac_rx_tkeep({qsfp3_rx_axis_tkeep, qsfp2_rx_axis_tkeep, qsfp1_rx_axis_tkeep, qsfp0_rx_axis_tkeep}), + .s_axis_mac_rx_tvalid({qsfp3_rx_axis_tvalid, qsfp2_rx_axis_tvalid, qsfp1_rx_axis_tvalid, qsfp0_rx_axis_tvalid}), + .s_axis_mac_rx_tready(), + .s_axis_mac_rx_tlast({qsfp3_rx_axis_tlast, qsfp2_rx_axis_tlast, qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), + .s_axis_mac_rx_tuser({{qsfp3_rx_axis_tuser[80:1], 16'd0, qsfp3_rx_axis_tuser[0]}, {qsfp2_rx_axis_tuser[80:1], 16'd0, qsfp2_rx_axis_tuser[0]}, {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + + // towards datapath + .tx_clk(eth_tx_clk), + .tx_rst(eth_tx_rst), + + .tx_ptp_ts_96(eth_tx_ptp_ts_96), + .tx_ptp_ts_step(eth_tx_ptp_ts_step), + + .s_axis_tx_tdata(axis_eth_tx_tdata), + .s_axis_tx_tkeep(axis_eth_tx_tkeep), + .s_axis_tx_tvalid(axis_eth_tx_tvalid), + .s_axis_tx_tready(axis_eth_tx_tready), + .s_axis_tx_tlast(axis_eth_tx_tlast), + .s_axis_tx_tuser(axis_eth_tx_tuser), + + .m_axis_tx_ptp_ts(axis_eth_tx_ptp_ts), + .m_axis_tx_ptp_ts_tag(axis_eth_tx_ptp_ts_tag), + .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), + .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + + .rx_clk(eth_rx_clk), + .rx_rst(eth_rx_rst), + + .rx_ptp_clk(eth_rx_ptp_clk), + .rx_ptp_rst(eth_rx_ptp_rst), + .rx_ptp_ts_96(eth_rx_ptp_ts_96), + .rx_ptp_ts_step(eth_rx_ptp_ts_step), + + .m_axis_rx_tdata(axis_eth_rx_tdata), + .m_axis_rx_tkeep(axis_eth_rx_tkeep), + .m_axis_rx_tvalid(axis_eth_rx_tvalid), + .m_axis_rx_tready(axis_eth_rx_tready), + .m_axis_rx_tlast(axis_eth_rx_tlast), + .m_axis_rx_tuser(axis_eth_rx_tuser) +); + +mqnic_core_pcie_us #( + // FW and board IDs + .FPGA_ID(FPGA_ID), + .FW_ID(FW_ID), + .FW_VER(FW_VER), + .BOARD_ID(BOARD_ID), + .BOARD_VER(BOARD_VER), + .BUILD_DATE(BUILD_DATE), + .GIT_HASH(GIT_HASH), + .RELEASE_INFO(RELEASE_INFO), + + // Structural configuration + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + .SCHED_PER_IF(SCHED_PER_IF), + + .PORT_COUNT(PORT_COUNT), + + // PTP configuration + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .PTP_PERIOD_NS_WIDTH(PTP_PERIOD_NS_WIDTH), + .PTP_OFFSET_NS_WIDTH(PTP_OFFSET_NS_WIDTH), + .PTP_FNS_WIDTH(PTP_FNS_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_CLOCK_PIPELINE(PTP_CLOCK_PIPELINE), + .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(PTP_SEPARATE_RX_CLOCK), + .PTP_PORT_CDC_PIPELINE(PTP_PORT_CDC_PIPELINE), + .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), + .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), + + // Queue manager configuration (interface) + .EVENT_QUEUE_OP_TABLE_SIZE(EVENT_QUEUE_OP_TABLE_SIZE), + .TX_QUEUE_OP_TABLE_SIZE(TX_QUEUE_OP_TABLE_SIZE), + .RX_QUEUE_OP_TABLE_SIZE(RX_QUEUE_OP_TABLE_SIZE), + .TX_CPL_QUEUE_OP_TABLE_SIZE(TX_CPL_QUEUE_OP_TABLE_SIZE), + .RX_CPL_QUEUE_OP_TABLE_SIZE(RX_CPL_QUEUE_OP_TABLE_SIZE), + .EVENT_QUEUE_INDEX_WIDTH(EVENT_QUEUE_INDEX_WIDTH), + .TX_QUEUE_INDEX_WIDTH(TX_QUEUE_INDEX_WIDTH), + .RX_QUEUE_INDEX_WIDTH(RX_QUEUE_INDEX_WIDTH), + .TX_CPL_QUEUE_INDEX_WIDTH(TX_CPL_QUEUE_INDEX_WIDTH), + .RX_CPL_QUEUE_INDEX_WIDTH(RX_CPL_QUEUE_INDEX_WIDTH), + .EVENT_QUEUE_PIPELINE(EVENT_QUEUE_PIPELINE), + .TX_QUEUE_PIPELINE(TX_QUEUE_PIPELINE), + .RX_QUEUE_PIPELINE(RX_QUEUE_PIPELINE), + .TX_CPL_QUEUE_PIPELINE(TX_CPL_QUEUE_PIPELINE), + .RX_CPL_QUEUE_PIPELINE(RX_CPL_QUEUE_PIPELINE), + + // TX and RX engine configuration (port) + .TX_DESC_TABLE_SIZE(TX_DESC_TABLE_SIZE), + .RX_DESC_TABLE_SIZE(RX_DESC_TABLE_SIZE), + + // Scheduler configuration (port) + .TX_SCHEDULER_OP_TABLE_SIZE(TX_SCHEDULER_OP_TABLE_SIZE), + .TX_SCHEDULER_PIPELINE(TX_SCHEDULER_PIPELINE), + .TDMA_INDEX_WIDTH(TDMA_INDEX_WIDTH), + + // Timestamping configuration (port) + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TS_FIFO_DEPTH(TX_PTP_TS_FIFO_DEPTH), + .RX_PTP_TS_FIFO_DEPTH(RX_PTP_TS_FIFO_DEPTH), + + // Interface configuration (port) + .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), + .RX_RSS_ENABLE(RX_RSS_ENABLE), + .RX_HASH_ENABLE(RX_HASH_ENABLE), + .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .TX_FIFO_DEPTH(TX_FIFO_DEPTH), + .RX_FIFO_DEPTH(RX_FIFO_DEPTH), + .MAX_TX_SIZE(MAX_TX_SIZE), + .MAX_RX_SIZE(MAX_RX_SIZE), + .TX_RAM_SIZE(TX_RAM_SIZE), + .RX_RAM_SIZE(RX_RAM_SIZE), + + // Application block configuration + .APP_ENABLE(APP_ENABLE), + .APP_CTRL_ENABLE(APP_CTRL_ENABLE), + .APP_DMA_ENABLE(APP_DMA_ENABLE), + .APP_AXIS_DIRECT_ENABLE(APP_AXIS_DIRECT_ENABLE), + .APP_AXIS_SYNC_ENABLE(APP_AXIS_SYNC_ENABLE), + .APP_AXIS_IF_ENABLE(APP_AXIS_IF_ENABLE), + .APP_STAT_ENABLE(APP_STAT_ENABLE), + .APP_GPIO_IN_WIDTH(32), + .APP_GPIO_OUT_WIDTH(32), + + // DMA interface configuration + .DMA_LEN_WIDTH(DMA_LEN_WIDTH), + .DMA_TAG_WIDTH(DMA_TAG_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), + .RAM_PIPELINE(RAM_PIPELINE), + + // PCIe interface configuration + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .PF_COUNT(PF_COUNT), + .VF_COUNT(VF_COUNT), + .F_COUNT(F_COUNT), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .PCIE_DMA_READ_OP_TABLE_SIZE(PCIE_DMA_READ_OP_TABLE_SIZE), + .PCIE_DMA_READ_TX_LIMIT(PCIE_DMA_READ_TX_LIMIT), + .PCIE_DMA_READ_TX_FC_ENABLE(PCIE_DMA_READ_TX_FC_ENABLE), + .PCIE_DMA_WRITE_OP_TABLE_SIZE(PCIE_DMA_WRITE_OP_TABLE_SIZE), + .PCIE_DMA_WRITE_TX_LIMIT(PCIE_DMA_WRITE_TX_LIMIT), + .PCIE_DMA_WRITE_TX_FC_ENABLE(PCIE_DMA_WRITE_TX_FC_ENABLE), + .MSI_COUNT(MSI_COUNT), + + // AXI lite interface configuration (control) + .AXIL_CTRL_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .AXIL_CTRL_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH), + .AXIL_CTRL_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), + .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .AXIL_CSR_PASSTHROUGH_ENABLE(0), + .RB_NEXT_PTR(RB_BASE_ADDR), + + // AXI lite interface configuration (application control) + .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), + .AXIL_APP_CTRL_ADDR_WIDTH(AXIL_APP_CTRL_ADDR_WIDTH), + + // Ethernet interface configuration + .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .AXIS_ETH_SYNC_DATA_WIDTH(AXIS_ETH_SYNC_DATA_WIDTH), + .AXIS_ETH_TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .AXIS_ETH_RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .AXIS_ETH_RX_USE_READY(0), + .AXIS_ETH_TX_PIPELINE(AXIS_ETH_TX_PIPELINE), + .AXIS_ETH_TX_FIFO_PIPELINE(AXIS_ETH_TX_FIFO_PIPELINE), + .AXIS_ETH_TX_TS_PIPELINE(AXIS_ETH_TX_TS_PIPELINE), + .AXIS_ETH_RX_PIPELINE(AXIS_ETH_RX_PIPELINE), + .AXIS_ETH_RX_FIFO_PIPELINE(AXIS_ETH_RX_FIFO_PIPELINE), + + // Statistics counter subsystem + .STAT_ENABLE(STAT_ENABLE), + .STAT_DMA_ENABLE(STAT_DMA_ENABLE), + .STAT_PCIE_ENABLE(STAT_PCIE_ENABLE), + .STAT_INC_WIDTH(STAT_INC_WIDTH), + .STAT_ID_WIDTH(STAT_ID_WIDTH) +) +core_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * AXI input (RC) + */ + .s_axis_rc_tdata(s_axis_rc_tdata), + .s_axis_rc_tkeep(s_axis_rc_tkeep), + .s_axis_rc_tvalid(s_axis_rc_tvalid), + .s_axis_rc_tready(s_axis_rc_tready), + .s_axis_rc_tlast(s_axis_rc_tlast), + .s_axis_rc_tuser(s_axis_rc_tuser), + + /* + * AXI output (RQ) + */ + .m_axis_rq_tdata(m_axis_rq_tdata), + .m_axis_rq_tkeep(m_axis_rq_tkeep), + .m_axis_rq_tvalid(m_axis_rq_tvalid), + .m_axis_rq_tready(m_axis_rq_tready), + .m_axis_rq_tlast(m_axis_rq_tlast), + .m_axis_rq_tuser(m_axis_rq_tuser), + + /* + * AXI input (CQ) + */ + .s_axis_cq_tdata(s_axis_cq_tdata), + .s_axis_cq_tkeep(s_axis_cq_tkeep), + .s_axis_cq_tvalid(s_axis_cq_tvalid), + .s_axis_cq_tready(s_axis_cq_tready), + .s_axis_cq_tlast(s_axis_cq_tlast), + .s_axis_cq_tuser(s_axis_cq_tuser), + + /* + * AXI output (CC) + */ + .m_axis_cc_tdata(m_axis_cc_tdata), + .m_axis_cc_tkeep(m_axis_cc_tkeep), + .m_axis_cc_tvalid(m_axis_cc_tvalid), + .m_axis_cc_tready(m_axis_cc_tready), + .m_axis_cc_tlast(m_axis_cc_tlast), + .m_axis_cc_tuser(m_axis_cc_tuser), + + /* + * Transmit sequence number input + */ + .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), + .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), + .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), + .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), + + /* + * Flow control + */ + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + /* + * Configuration inputs + */ + .cfg_max_read_req(cfg_max_read_req), + .cfg_max_payload(cfg_max_payload), + + /* + * Configuration interface + */ + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + /* + * Interrupt interface + */ + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(8'd0), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * PCIe error outputs + */ + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor), + + /* + * AXI-Lite master interface (passthrough for NIC control and status) + */ + .m_axil_csr_awaddr(), + .m_axil_csr_awprot(), + .m_axil_csr_awvalid(), + .m_axil_csr_awready(1), + .m_axil_csr_wdata(), + .m_axil_csr_wstrb(), + .m_axil_csr_wvalid(), + .m_axil_csr_wready(1), + .m_axil_csr_bresp(0), + .m_axil_csr_bvalid(0), + .m_axil_csr_bready(), + .m_axil_csr_araddr(), + .m_axil_csr_arprot(), + .m_axil_csr_arvalid(), + .m_axil_csr_arready(1), + .m_axil_csr_rdata(0), + .m_axil_csr_rresp(0), + .m_axil_csr_rvalid(0), + .m_axil_csr_rready(), + + /* + * Control register interface + */ + .ctrl_reg_wr_addr(ctrl_reg_wr_addr), + .ctrl_reg_wr_data(ctrl_reg_wr_data), + .ctrl_reg_wr_strb(ctrl_reg_wr_strb), + .ctrl_reg_wr_en(ctrl_reg_wr_en), + .ctrl_reg_wr_wait(ctrl_reg_wr_wait), + .ctrl_reg_wr_ack(ctrl_reg_wr_ack), + .ctrl_reg_rd_addr(ctrl_reg_rd_addr), + .ctrl_reg_rd_en(ctrl_reg_rd_en), + .ctrl_reg_rd_data(ctrl_reg_rd_data), + .ctrl_reg_rd_wait(ctrl_reg_rd_wait), + .ctrl_reg_rd_ack(ctrl_reg_rd_ack), + + /* + * PTP clock + */ + .ptp_sample_clk(clk_250mhz), + .ptp_pps(ptp_pps), + .ptp_ts_96(ptp_ts_96), + .ptp_ts_step(ptp_ts_step), + .ptp_perout_locked(ptp_perout_locked), + .ptp_perout_error(ptp_perout_error), + .ptp_perout_pulse(ptp_perout_pulse), + + /* + * Ethernet + */ + .eth_tx_clk(eth_tx_clk), + .eth_tx_rst(eth_tx_rst), + + .eth_tx_ptp_ts_96(eth_tx_ptp_ts_96), + .eth_tx_ptp_ts_step(eth_tx_ptp_ts_step), + + .m_axis_eth_tx_tdata(axis_eth_tx_tdata), + .m_axis_eth_tx_tkeep(axis_eth_tx_tkeep), + .m_axis_eth_tx_tvalid(axis_eth_tx_tvalid), + .m_axis_eth_tx_tready(axis_eth_tx_tready), + .m_axis_eth_tx_tlast(axis_eth_tx_tlast), + .m_axis_eth_tx_tuser(axis_eth_tx_tuser), + + .s_axis_eth_tx_ptp_ts(axis_eth_tx_ptp_ts), + .s_axis_eth_tx_ptp_ts_tag(axis_eth_tx_ptp_ts_tag), + .s_axis_eth_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), + .s_axis_eth_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + + .eth_rx_clk(eth_rx_clk), + .eth_rx_rst(eth_rx_rst), + + .eth_rx_ptp_clk(eth_rx_ptp_clk), + .eth_rx_ptp_rst(eth_rx_ptp_rst), + .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), + .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), + + .s_axis_eth_rx_tdata(axis_eth_rx_tdata), + .s_axis_eth_rx_tkeep(axis_eth_rx_tkeep), + .s_axis_eth_rx_tvalid(axis_eth_rx_tvalid), + .s_axis_eth_rx_tready(axis_eth_rx_tready), + .s_axis_eth_rx_tlast(axis_eth_rx_tlast), + .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + + /* + * Statistics input + */ + .s_axis_stat_tdata(0), + .s_axis_stat_tid(0), + .s_axis_stat_tvalid(1'b0), + .s_axis_stat_tready(), + + /* + * GPIO + */ + .app_gpio_in(0), + .app_gpio_out(), + + /* + * JTAG + */ + .app_jtag_tdi(1'b0), + .app_jtag_tdo(), + .app_jtag_tms(1'b0), + .app_jtag_tck(1'b0) +); + +endmodule + +`resetall diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/sync_signal.v b/fpga/mqnic/XUPP3R/fpga_100g/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/sync_signal.v @@ -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 diff --git a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..5ed120477 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,421 @@ +# 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_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_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_mac_axis.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/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 += ../../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 ?= 4 +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_CLOCK_PIPELINE ?= 0 +export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_SEPARATE_RX_CLOCK ?= 0 +export PARAM_PTP_PORT_CDC_PIPELINE ?= 0 +export PARAM_PTP_PEROUT_ENABLE ?= 0 +export PARAM_PTP_PEROUT_COUNT ?= 1 + +# Queue manager configuration (interface) +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 (port) +export PARAM_TX_DESC_TABLE_SIZE ?= 32 +export PARAM_RX_DESC_TABLE_SIZE ?= 32 + +# Scheduler configuration (port) +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 + +# Timestamping configuration (port) +export PARAM_PTP_TS_ENABLE ?= 1 +export PARAM_TX_PTP_TS_FIFO_DEPTH ?= 32 +export PARAM_RX_PTP_TS_FIFO_DEPTH ?= 32 + +# Interface configuration (port) +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 ?= 131072 +export PARAM_MAX_TX_SIZE ?= 9214 +export PARAM_MAX_RX_SIZE ?= 9214 +export PARAM_TX_RAM_SIZE ?= 131072 +export PARAM_RX_RAM_SIZE ?= 131072 + +# Application block configuration +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_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 ?= 512 +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 ?= 25 + +# 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 ?= 25 + +# Ethernet interface configuration +export PARAM_AXIS_ETH_TX_PIPELINE ?= 4 +export PARAM_AXIS_ETH_TX_FIFO_PIPELINE ?= 4 +export PARAM_AXIS_ETH_TX_TS_PIPELINE ?= 4 +export PARAM_AXIS_ETH_RX_PIPELINE ?= 4 +export PARAM_AXIS_ETH_RX_FIFO_PIPELINE ?= 4 + +# 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_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_PIPELINE) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -P $(TOPLEVEL).PTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_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_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) + COMPILE_ARGS += -P $(TOPLEVEL).RX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_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_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_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_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_PIPELINE) + COMPILE_ARGS += -GPTP_USE_SAMPLE_CLOCK=$(PARAM_PTP_USE_SAMPLE_CLOCK) + COMPILE_ARGS += -GPTP_SEPARATE_RX_CLOCK=$(PARAM_PTP_SEPARATE_RX_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_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) + COMPILE_ARGS += -GRX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_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_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_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 diff --git a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..81e5551e1 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,796 @@ +""" + +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 EthMac +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=16, + 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) + + # Ethernet + cocotb.start_soon(Clock(dut.qsfp0_rx_clk, 3.102, units="ns").start()) + cocotb.start_soon(Clock(dut.qsfp0_tx_clk, 3.102, units="ns").start()) + + self.qsfp0_mac = EthMac( + tx_clk=dut.qsfp0_tx_clk, + tx_rst=dut.qsfp0_tx_rst, + tx_bus=AxiStreamBus.from_prefix(dut, "qsfp0_tx_axis"), + tx_ptp_time=dut.qsfp0_tx_ptp_time, + tx_ptp_ts=dut.qsfp0_tx_ptp_ts, + tx_ptp_ts_tag=dut.qsfp0_tx_ptp_ts_tag, + tx_ptp_ts_valid=dut.qsfp0_tx_ptp_ts_valid, + rx_clk=dut.qsfp0_rx_clk, + rx_rst=dut.qsfp0_rx_rst, + rx_bus=AxiStreamBus.from_prefix(dut, "qsfp0_rx_axis"), + rx_ptp_time=dut.qsfp0_rx_ptp_time, + ifg=12, speed=100e9 + ) + + cocotb.start_soon(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + cocotb.start_soon(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + + self.qsfp1_mac = EthMac( + tx_clk=dut.qsfp1_tx_clk, + tx_rst=dut.qsfp1_tx_rst, + tx_bus=AxiStreamBus.from_prefix(dut, "qsfp1_tx_axis"), + tx_ptp_time=dut.qsfp1_tx_ptp_time, + tx_ptp_ts=dut.qsfp1_tx_ptp_ts, + tx_ptp_ts_tag=dut.qsfp1_tx_ptp_ts_tag, + tx_ptp_ts_valid=dut.qsfp1_tx_ptp_ts_valid, + rx_clk=dut.qsfp1_rx_clk, + rx_rst=dut.qsfp1_rx_rst, + rx_bus=AxiStreamBus.from_prefix(dut, "qsfp1_rx_axis"), + rx_ptp_time=dut.qsfp1_rx_ptp_time, + ifg=12, speed=100e9 + ) + + cocotb.start_soon(Clock(dut.qsfp2_rx_clk, 3.102, units="ns").start()) + cocotb.start_soon(Clock(dut.qsfp2_tx_clk, 3.102, units="ns").start()) + + self.qsfp2_mac = EthMac( + tx_clk=dut.qsfp2_tx_clk, + tx_rst=dut.qsfp2_tx_rst, + tx_bus=AxiStreamBus.from_prefix(dut, "qsfp2_tx_axis"), + tx_ptp_time=dut.qsfp2_tx_ptp_time, + tx_ptp_ts=dut.qsfp2_tx_ptp_ts, + tx_ptp_ts_tag=dut.qsfp2_tx_ptp_ts_tag, + tx_ptp_ts_valid=dut.qsfp2_tx_ptp_ts_valid, + rx_clk=dut.qsfp2_rx_clk, + rx_rst=dut.qsfp2_rx_rst, + rx_bus=AxiStreamBus.from_prefix(dut, "qsfp2_rx_axis"), + rx_ptp_time=dut.qsfp2_rx_ptp_time, + ifg=12, speed=100e9 + ) + + cocotb.start_soon(Clock(dut.qsfp3_rx_clk, 3.102, units="ns").start()) + cocotb.start_soon(Clock(dut.qsfp3_tx_clk, 3.102, units="ns").start()) + + self.qsfp3_mac = EthMac( + tx_clk=dut.qsfp3_tx_clk, + tx_rst=dut.qsfp3_tx_rst, + tx_bus=AxiStreamBus.from_prefix(dut, "qsfp3_tx_axis"), + tx_ptp_time=dut.qsfp3_tx_ptp_time, + tx_ptp_ts=dut.qsfp3_tx_ptp_ts, + tx_ptp_ts_tag=dut.qsfp3_tx_ptp_ts_tag, + tx_ptp_ts_valid=dut.qsfp3_tx_ptp_ts_valid, + rx_clk=dut.qsfp3_rx_clk, + rx_rst=dut.qsfp3_rx_rst, + rx_bus=AxiStreamBus.from_prefix(dut, "qsfp3_rx_axis"), + rx_ptp_time=dut.qsfp3_rx_ptp_time, + ifg=12, speed=100e9 + ) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp0_i2c_scl_i.setimmediatevalue(1) + dut.qsfp0_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qsfp1_i2c_scl_i.setimmediatevalue(1) + dut.qsfp1_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp2_modprsl.setimmediatevalue(0) + dut.qsfp2_intl.setimmediatevalue(1) + + dut.qsfp2_i2c_scl_i.setimmediatevalue(1) + dut.qsfp2_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp3_modprsl.setimmediatevalue(0) + dut.qsfp3_intl.setimmediatevalue(1) + + dut.qsfp3_i2c_scl_i.setimmediatevalue(1) + dut.qsfp3_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.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + self.dut.qsfp2_rx_rst.setimmediatevalue(0) + self.dut.qsfp2_tx_rst.setimmediatevalue(0) + self.dut.qsfp3_rx_rst.setimmediatevalue(0) + self.dut.qsfp3_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(1) + self.dut.qsfp0_tx_rst.setimmediatevalue(1) + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + self.dut.qsfp2_rx_rst.setimmediatevalue(1) + self.dut.qsfp2_tx_rst.setimmediatevalue(1) + self.dut.qsfp3_rx_rst.setimmediatevalue(1) + self.dut.qsfp3_tx_rst.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.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + self.dut.qsfp2_rx_rst.setimmediatevalue(0) + self.dut.qsfp2_tx_rst.setimmediatevalue(0) + self.dut.qsfp3_rx_rst.setimmediatevalue(0) + self.dut.qsfp3_tx_rst.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.qsfp0_mac.tx.empty(): + await self.qsfp0_mac.rx.send(await self.qsfp0_mac.tx.recv()) + if not self.qsfp1_mac.tx.empty(): + await self.qsfp1_mac.rx.send(await self.qsfp1_mac.tx.recv()) + if not self.qsfp2_mac.tx.empty(): + await self.qsfp2_mac.rx.send(await self.qsfp2_mac.tx.recv()) + if not self.qsfp3_mac.tx.empty(): + await self.qsfp3_mac.rx.send(await self.qsfp3_mac.tx.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.qsfp0_mac.tx.recv() + tb.log.info("Packet: %s", pkt) + + await tb.qsfp0_mac.rx.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.qsfp1_mac.tx.recv() + # tb.log.info("Packet: %s", pkt) + + # await tb.qsfp1_mac.rx.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.qsfp0_mac.tx.recv() + tb.log.info("Packet: %s", pkt) + + await tb.qsfp0_mac.rx.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("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 + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) 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_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_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_mac_axis.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", "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(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'] = 4 + parameters['PORTS_PER_IF'] = 1 + parameters['SCHED_PER_IF'] = parameters['PORTS_PER_IF'] + parameters['PORT_MASK'] = 0 + + # PTP configuration + parameters['PTP_CLOCK_PIPELINE'] = 0 + parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_SEPARATE_RX_CLOCK'] = 0 + parameters['PTP_PORT_CDC_PIPELINE'] = 0 + parameters['PTP_PEROUT_ENABLE'] = 0 + parameters['PTP_PEROUT_COUNT'] = 1 + + # Queue manager configuration (interface) + 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 (port) + parameters['TX_DESC_TABLE_SIZE'] = 32 + parameters['RX_DESC_TABLE_SIZE'] = 32 + + # Scheduler configuration (port) + parameters['TX_SCHEDULER_OP_TABLE_SIZE'] = parameters['TX_DESC_TABLE_SIZE'] + parameters['TX_SCHEDULER_PIPELINE'] = parameters['TX_QUEUE_PIPELINE'] + parameters['TDMA_INDEX_WIDTH'] = 6 + + # Timestamping configuration (port) + parameters['PTP_TS_ENABLE'] = 1 + parameters['TX_PTP_TS_FIFO_DEPTH'] = 32 + parameters['RX_PTP_TS_FIFO_DEPTH'] = 32 + + # Interface configuration (port) + 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'] = 131072 + parameters['MAX_TX_SIZE'] = 9214 + parameters['MAX_RX_SIZE'] = 9214 + parameters['TX_RAM_SIZE'] = 131072 + parameters['RX_RAM_SIZE'] = 131072 + + # Application block configuration + 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_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'] = 512 + 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'] = 25 + + # AXI lite interface configuration (application control) + parameters['AXIL_APP_CTRL_DATA_WIDTH'] = parameters['AXIL_CTRL_DATA_WIDTH'] + parameters['AXIL_APP_CTRL_ADDR_WIDTH'] = 25 + + # Ethernet interface configuration + parameters['AXIS_ETH_TX_PIPELINE'] = 4 + parameters['AXIS_ETH_TX_FIFO_PIPELINE'] = 4 + parameters['AXIS_ETH_TX_TS_PIPELINE'] = 4 + parameters['AXIS_ETH_RX_PIPELINE'] = 4 + parameters['AXIS_ETH_RX_FIFO_PIPELINE'] = 4 + + # 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, + ) diff --git a/fpga/mqnic/XUPP3R/fpga_25g/README.md b/fpga/mqnic/XUPP3R/fpga_25g/README.md new file mode 100644 index 000000000..fe66bf46c --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/README.md @@ -0,0 +1,22 @@ +# Corundum mqnic for XUP-P3R + +## Introduction + +This design targets the BittWare XUP-P3R FPGA board. + +* FPGA: xcvu9p-flgb2104-2-e +* PHY: 10G 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 XUP-P3R board with Vivado. Then load the +driver with insmod mqnic.ko. Check dmesg for output from driver +initialization. diff --git a/fpga/mqnic/XUPP3R/fpga_25g/app b/fpga/mqnic/XUPP3R/fpga_25g/app new file mode 120000 index 000000000..4d46690fb --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/app @@ -0,0 +1 @@ +../../../app/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_25g/boot.xdc b/fpga/mqnic/XUPP3R/fpga_25g/boot.xdc new file mode 100644 index 000000000..5fb323e94 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/boot.xdc @@ -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"] diff --git a/fpga/mqnic/XUPP3R/fpga_25g/common/vivado.mk b/fpga/mqnic/XUPP3R/fpga_25g/common/vivado.mk new file mode 100644 index 000000000..df3528189 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/common/vivado.mk @@ -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"; diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga.xdc b/fpga/mqnic/XUPP3R/fpga_25g/fpga.xdc new file mode 100644 index 000000000..611b9d747 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga.xdc @@ -0,0 +1,381 @@ +# XDC constraints for the Xilinx VCU1525 board +# part: xcvu9p-flgb2104-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.CONFIGFALLBACK ENABLE [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [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.UNUSEDPIN PULLUP [current_design] + +# System clocks +# 48 MHz system clock +set_property -dict {LOC AV23 IOSTANDARD LVCMOS18} [get_ports clk_48mhz] +create_clock -period 20.833 -name clk_48mhz [get_ports clk_48mhz] + +# 322.265625 MHz clock from Si5338 B ch 1 +#set_property -dict {LOC AY23 IOSTANDARD DIFF_SSTL18_I} [get_ports clk_b1_p] +#set_property -dict {LOC BA23 IOSTANDARD DIFF_SSTL18_I} [get_ports clk_b1_n] +#create_clock -period 3.103 -name clk_b1 [get_ports clk_b1_p] + +# 322.265625 MHz clock from Si5338 B ch 2 +#set_property -dict {LOC BB9 IOSTANDARD DIFF_SSTL15_DCI ODT RTT_48} [get_ports clk_b2_p] +#set_property -dict {LOC BC9 IOSTANDARD DIFF_SSTL15_DCI ODT RTT_48} [get_ports clk_b2_n] +#create_clock -period 3.103 -name clk_b2 [get_ports clk_b2_p] + +# 100 MHz DDR4 module 1 clock from Si5338 A ch 0 +#set_property -dict {LOC AV18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_1_p] +#set_property -dict {LOC AW18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_1_n] +#create_clock -period 10.000 -name clk_ddr_1 [get_ports clk_ddr_1_p] + +# 100 MHz DDR4 module 2 clock from Si5338 A ch 1 +#set_property -dict {LOC BB36 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_2_p] +#set_property -dict {LOC BC36 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_2_n] +#create_clock -period 10.000 -name clk_ddr_2 [get_ports clk_ddr_2_p] + +# 100 MHz DDR4 module 3 clock from Si5338 A ch 2 +#set_property -dict {LOC E38 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_3_p] +#set_property -dict {LOC D38 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_3_n] +#create_clock -period 10.000 -name clk_ddr_3 [get_ports clk_ddr_3_p] + +# 100 MHz DDR4 module 4 clock from Si5338 A ch 3 +#set_property -dict {LOC K18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_4_p] +#set_property -dict {LOC J18 IOSTANDARD DIFF_SSTL12_DCI ODT RTT_48} [get_ports clk_ddr_4_n] +#create_clock -period 10.000 -name clk_ddr_4 [get_ports clk_ddr_4_p] + +# LEDs +set_property -dict {LOC AR22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AT22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AR23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC AV22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[3]}] + +set_false_path -to [get_ports {led[*]}] +set_output_delay 0 [get_ports {led[*]}] + +# Reset +#set_property -dict {LOC IOSTANDARD LVCMOS12} [get_ports reset] + +#set_false_path -from [get_ports {reset}] +#set_input_delay 0 [get_ports {reset}] + +# UART +#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] +#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] + +#set_false_path -to [get_ports {uart_txd}] +#set_output_delay 0 [get_ports {uart_txd}] +#set_false_path -from [get_ports {uart_rxd}] +#set_input_delay 0 [get_ports {uart_rxd}] + +# EEPROM I2C interface +set_property -dict {LOC AN24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports eeprom_i2c_scl] +set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [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}] + +# I2C-related signals +set_property -dict {LOC AT24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports fpga_i2c_master_l] +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_ctl_en] + +set_false_path -to [get_ports {fpga_i2c_master_l qsfp_ctl_en}] +set_output_delay 0 [get_ports {fpga_i2c_master_l qsfp_ctl_en}] + +# QSFP28 Interfaces +set_property -dict {LOC BC45} [get_ports qsfp0_rx1_p] ;# MGTYRXP0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BC46} [get_ports qsfp0_rx1_n] ;# MGTYRXN0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BF42} [get_ports qsfp0_tx1_p] ;# MGTYTXP0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BF43} [get_ports qsfp0_tx1_n] ;# MGTYTXN0_120 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA45} [get_ports qsfp0_rx2_p] ;# MGTYRXP1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA46} [get_ports qsfp0_rx2_n] ;# MGTYRXN1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BD42} [get_ports qsfp0_tx2_p] ;# MGTYTXP1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BD43} [get_ports qsfp0_tx2_n] ;# MGTYTXN1_120 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW45} [get_ports qsfp0_rx3_p] ;# MGTYRXP2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW46} [get_ports qsfp0_rx3_n] ;# MGTYRXN2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BB42} [get_ports qsfp0_tx3_p] ;# MGTYTXP2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BB43} [get_ports qsfp0_tx3_n] ;# MGTYTXN2_120 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AV43} [get_ports qsfp0_rx4_p] ;# MGTYRXP3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AV44} [get_ports qsfp0_rx4_n] ;# MGTYRXN3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW40} [get_ports qsfp0_tx4_p] ;# MGTYTXP3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC AW41} [get_ports qsfp0_tx4_n] ;# MGTYTXN3_120 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1 +set_property -dict {LOC BA40} [get_ports qsfp0_mgt_refclk_b0_p] ;# MGTREFCLK0P_120 from Si5338 B ch 0 +set_property -dict {LOC BA41} [get_ports qsfp0_mgt_refclk_b0_n] ;# MGTREFCLK0N_120 from Si5338 B ch 0 +#set_property -dict {LOC AY38} [get_ports qsfp0_mgt_refclk_b1_p] ;# MGTREFCLK1P_120 from Si5338 B ch 1 +#set_property -dict {LOC AY39} [get_ports qsfp0_mgt_refclk_b1_n] ;# MGTREFCLK1N_120 from Si5338 B ch 1 +#set_property -dict {LOC AU36} [get_ports qsfp0_mgt_refclk_c0_p] ;# MGTREFCLK0P_121 from Si5338 C ch 0 +#set_property -dict {LOC AU37} [get_ports qsfp0_mgt_refclk_c0_n] ;# MGTREFCLK0N_121 from Si5338 C ch 0 +#set_property -dict {LOC AV38} [get_ports qsfp0_mgt_refclk_c1_p] ;# MGTREFCLK1P_121 from Si5338 C ch 1 +#set_property -dict {LOC AV39} [get_ports qsfp0_mgt_refclk_c1_n] ;# MGTREFCLK1N_121 from Si5338 C ch 1 +set_property -dict {LOC BD24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl] +set_property -dict {LOC BD23 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp0_modprsl] +set_property -dict {LOC BE23 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp0_intl] +set_property -dict {LOC BC24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode] +set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp0_i2c_scl] +set_property -dict {LOC BF23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp0_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +create_clock -period 3.103 -name qsfp0_mgt_refclk_b0 [get_ports qsfp0_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 1) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_b1 [get_ports qsfp0_mgt_refclk_b1_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 0) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_c0 [get_ports qsfp0_mgt_refclk_c0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 1) +#create_clock -period 3.103 -name qsfp0_mgt_refclk_c1 [get_ports qsfp0_mgt_refclk_c1_p] + +set_false_path -to [get_ports {qsfp0_resetl qsfp0_lpmode}] +set_output_delay 0 [get_ports {qsfp0_resetl qsfp0_lpmode}] +set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}] +set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}] + +set_false_path -to [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_output_delay 0 [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_false_path -from [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] +set_input_delay 0 [get_ports {qsfp0_i2c_scl qsfp0_i2c_sda}] + +set_property -dict {LOC AN45} [get_ports qsfp1_rx1_p] ;# MGTYRXP0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN46} [get_ports qsfp1_rx1_n] ;# MGTYRXN0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN40} [get_ports qsfp1_tx1_p] ;# MGTYTXP0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AN41} [get_ports qsfp1_tx1_n] ;# MGTYTXN0_122 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM43} [get_ports qsfp1_rx2_p] ;# MGTYRXP1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM44} [get_ports qsfp1_rx2_n] ;# MGTYRXN1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM38} [get_ports qsfp1_tx2_p] ;# MGTYTXP1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AM39} [get_ports qsfp1_tx2_n] ;# MGTYTXN1_122 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL45} [get_ports qsfp1_rx3_p] ;# MGTYRXP2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL46} [get_ports qsfp1_rx3_n] ;# MGTYRXN2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL40} [get_ports qsfp1_tx3_p] ;# MGTYTXP2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AL41} [get_ports qsfp1_tx3_n] ;# MGTYTXN2_122 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK43} [get_ports qsfp1_rx4_p] ;# MGTYRXP3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK44} [get_ports qsfp1_rx4_n] ;# MGTYRXN3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK38} [get_ports qsfp1_tx4_p] ;# MGTYTXP3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AK39} [get_ports qsfp1_tx4_n] ;# MGTYTXN3_122 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC AR36} [get_ports qsfp1_mgt_refclk_b0_p] ;# MGTREFCLK0P_122 from Si5338 B ch 0 +set_property -dict {LOC AR37} [get_ports qsfp1_mgt_refclk_b0_n] ;# MGTREFCLK0N_122 from Si5338 B ch 0 +#set_property -dict {LOC AN36} [get_ports qsfp1_mgt_refclk_b1_p] ;# MGTREFCLK1P_122 from Si5338 B ch 1 +#set_property -dict {LOC AN37} [get_ports qsfp1_mgt_refclk_b1_n] ;# MGTREFCLK1N_122 from Si5338 B ch 1 +#set_property -dict {LOC AL36} [get_ports qsfp1_mgt_refclk_c2_p] ;# MGTREFCLK0P_123 from Si5338 C ch 2 +#set_property -dict {LOC AL37} [get_ports qsfp1_mgt_refclk_c2_n] ;# MGTREFCLK0N_123 from Si5338 C ch 2 +#set_property -dict {LOC AJ36} [get_ports qsfp1_mgt_refclk_c3_p] ;# MGTREFCLK1P_123 from Si5338 C ch 3 +#set_property -dict {LOC AJ37} [get_ports qsfp1_mgt_refclk_c3_n] ;# MGTREFCLK1N_123 from Si5338 C ch 3 +set_property -dict {LOC BE20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl] +set_property -dict {LOC BD21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp1_modprsl] +set_property -dict {LOC BE21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp1_intl] +set_property -dict {LOC BD20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode] +set_property -dict {LOC BE22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp1_i2c_scl] +set_property -dict {LOC BF22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp1_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +create_clock -period 3.103 -name qsfp1_mgt_refclk_b0 [get_ports qsfp1_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 1) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_b1 [get_ports qsfp1_mgt_refclk_b1_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 2) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_c2 [get_ports qsfp1_mgt_refclk_c2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 C ch 3) +#create_clock -period 3.103 -name qsfp1_mgt_refclk_c3 [get_ports qsfp1_mgt_refclk_c3_p] + +set_false_path -to [get_ports {qsfp1_resetl qsfp1_lpmode}] +set_output_delay 0 [get_ports {qsfp1_resetl qsfp1_lpmode}] +set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}] +set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}] + +set_false_path -to [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_output_delay 0 [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_false_path -from [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] +set_input_delay 0 [get_ports {qsfp1_i2c_scl qsfp1_i2c_sda}] + +set_property -dict {LOC AA45} [get_ports qsfp2_rx1_p] ;# MGTYRXP0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA46} [get_ports qsfp2_rx1_n] ;# MGTYRXN0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA40} [get_ports qsfp2_tx1_p] ;# MGTYTXP0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AA41} [get_ports qsfp2_tx1_n] ;# MGTYTXN0_125 GTYE4_CHANNEL_X0Y24 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y43 } [get_ports qsfp2_rx2_p] ;# MGTYRXP1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y44 } [get_ports qsfp2_rx2_n] ;# MGTYRXN1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y38 } [get_ports qsfp2_tx2_p] ;# MGTYTXP1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC Y39 } [get_ports qsfp2_tx2_n] ;# MGTYTXN1_125 GTYE4_CHANNEL_X0Y25 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W45 } [get_ports qsfp2_rx3_p] ;# MGTYRXP2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W46 } [get_ports qsfp2_rx3_n] ;# MGTYRXN2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W40 } [get_ports qsfp2_tx3_p] ;# MGTYTXP2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC W41 } [get_ports qsfp2_tx3_n] ;# MGTYTXN2_125 GTYE4_CHANNEL_X0Y26 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V43 } [get_ports qsfp2_rx4_p] ;# MGTYRXP3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V44 } [get_ports qsfp2_rx4_n] ;# MGTYRXN3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V38 } [get_ports qsfp2_tx4_p] ;# MGTYTXP3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC V39 } [get_ports qsfp2_tx4_n] ;# MGTYTXN3_125 GTYE4_CHANNEL_X0Y27 / GTYE4_COMMON_X0Y6 +set_property -dict {LOC AC36} [get_ports qsfp2_mgt_refclk_b0_p] ;# MGTREFCLK0P_125 from Si5338 B ch 0 +set_property -dict {LOC AC37} [get_ports qsfp2_mgt_refclk_b0_n] ;# MGTREFCLK0N_125 from Si5338 B ch 0 +#set_property -dict {LOC AA36} [get_ports qsfp2_mgt_refclk_b2_p] ;# MGTREFCLK1P_125 from Si5338 B ch 2 +#set_property -dict {LOC AA37} [get_ports qsfp2_mgt_refclk_b2_n] ;# MGTREFCLK1N_125 from Si5338 B ch 2 +#set_property -dict {LOC W36 } [get_ports qsfp2_mgt_refclk_d0_p] ;# MGTREFCLK0P_126 from Si5338 D ch 0 +#set_property -dict {LOC W37 } [get_ports qsfp2_mgt_refclk_d0_n] ;# MGTREFCLK0N_126 from Si5338 D ch 0 +#set_property -dict {LOC U36 } [get_ports qsfp2_mgt_refclk_d1_p] ;# MGTREFCLK1P_126 from Si5338 D ch 1 +#set_property -dict {LOC U37 } [get_ports qsfp2_mgt_refclk_d1_n] ;# MGTREFCLK1N_126 from Si5338 D ch 1 +set_property -dict {LOC BB22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp2_resetl] +set_property -dict {LOC BB20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp2_modprsl] +set_property -dict {LOC BB21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp2_intl] +set_property -dict {LOC BC21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp2_lpmode] +set_property -dict {LOC BF20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp2_i2c_scl] +set_property -dict {LOC BA20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp2_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +create_clock -period 3.103 -name qsfp2_mgt_refclk_b0 [get_ports qsfp2_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 2) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_b2 [get_ports qsfp2_mgt_refclk_b2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 0) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_d0 [get_ports qsfp2_mgt_refclk_d0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 1) +#create_clock -period 3.103 -name qsfp2_mgt_refclk_d1 [get_ports qsfp2_mgt_refclk_d1_p] + +set_false_path -to [get_ports {qsfp2_resetl qsfp2_lpmode}] +set_output_delay 0 [get_ports {qsfp2_resetl qsfp2_lpmode}] +set_false_path -from [get_ports {qsfp2_modprsl qsfp2_intl}] +set_input_delay 0 [get_ports {qsfp2_modprsl qsfp2_intl}] + +set_false_path -to [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_output_delay 0 [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_false_path -from [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] +set_input_delay 0 [get_ports {qsfp2_i2c_scl qsfp2_i2c_sda}] + +set_property -dict {LOC N45 } [get_ports qsfp3_rx1_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N46 } [get_ports qsfp3_rx1_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N40 } [get_ports qsfp3_tx1_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC N41 } [get_ports qsfp3_tx1_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y32 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M43 } [get_ports qsfp3_rx2_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M44 } [get_ports qsfp3_rx2_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M38 } [get_ports qsfp3_tx2_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC M39 } [get_ports qsfp3_tx2_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y33 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L45 } [get_ports qsfp3_rx3_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L46 } [get_ports qsfp3_rx3_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L40 } [get_ports qsfp3_tx3_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC L41 } [get_ports qsfp3_tx3_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y34 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC K43 } [get_ports qsfp3_rx4_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC K44 } [get_ports qsfp3_rx4_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC J40 } [get_ports qsfp3_tx4_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC J41 } [get_ports qsfp3_tx4_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y35 / GTYE4_COMMON_X0Y8 +set_property -dict {LOC R36 } [get_ports qsfp3_mgt_refclk_b0_p] ;# MGTREFCLK0P_127 from Si5338 B ch 0 +set_property -dict {LOC R37 } [get_ports qsfp3_mgt_refclk_b0_n] ;# MGTREFCLK0N_127 from Si5338 B ch 0 +#set_property -dict {LOC N36 } [get_ports qsfp3_mgt_refclk_b3_p] ;# MGTREFCLK1P_127 from Si5338 B ch 3 +#set_property -dict {LOC N37 } [get_ports qsfp3_mgt_refclk_b3_n] ;# MGTREFCLK1N_127 from Si5338 B ch 3 +#set_property -dict {LOC L36 } [get_ports qsfp3_mgt_refclk_d2_p] ;# MGTREFCLK0P_128 from Si5338 D ch 2 +#set_property -dict {LOC L37 } [get_ports qsfp3_mgt_refclk_d2_n] ;# MGTREFCLK0N_128 from Si5338 D ch 2 +#set_property -dict {LOC K38 } [get_ports qsfp3_mgt_refclk_d3_p] ;# MGTREFCLK1P_128 from Si5338 D ch 3 +#set_property -dict {LOC K39 } [get_ports qsfp3_mgt_refclk_d3_n] ;# MGTREFCLK1N_128 from Si5338 D ch 3 +set_property -dict {LOC BC23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp3_resetl] +set_property -dict {LOC BB24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp3_modprsl] +set_property -dict {LOC AY22 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp3_intl] +set_property -dict {LOC BA22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp3_lpmode] +set_property -dict {LOC BC22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp3_i2c_scl] +set_property -dict {LOC BA24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports qsfp3_i2c_sda] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 0) +create_clock -period 3.103 -name qsfp3_mgt_refclk_b0 [get_ports qsfp3_mgt_refclk_b0_p] + +# 322.265625 MHz MGT reference clock (from Si5338 B ch 2) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_b3 [get_ports qsfp3_mgt_refclk_b3_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 2) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_d2 [get_ports qsfp3_mgt_refclk_d2_p] + +# 322.265625 MHz MGT reference clock (from Si5338 D ch 3) +#create_clock -period 3.103 -name qsfp3_mgt_refclk_d3 [get_ports qsfp3_mgt_refclk_d3_p] + +set_false_path -to [get_ports {qsfp3_resetl qsfp3_lpmode}] +set_output_delay 0 [get_ports {qsfp3_resetl qsfp3_lpmode}] +set_false_path -from [get_ports {qsfp3_modprsl qsfp3_intl}] +set_input_delay 0 [get_ports {qsfp3_modprsl qsfp3_intl}] + +set_false_path -to [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_output_delay 0 [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_false_path -from [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] +set_input_delay 0 [get_ports {qsfp3_i2c_scl qsfp3_i2c_sda}] + +# PCIe Interface +set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +set_property -dict {LOC AT11 } [get_ports pcie_refclk_0_p] ;# MGTREFCLK0P_225 +set_property -dict {LOC AT10 } [get_ports pcie_refclk_0_n] ;# MGTREFCLK0N_225 +# set_property -dict {LOC AM11 } [get_ports pcie_refclk_b1_p] ;# MGTREFCLK0P_226 from Si5338 B ch 1 +# set_property -dict {LOC AM10 } [get_ports pcie_refclk_b1_n] ;# MGTREFCLK0N_226 from Si5338 B ch 1 +# set_property -dict {LOC AH11 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_227 +# set_property -dict {LOC AH10 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_227 +set_property -dict {LOC AR26 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports pcie_refclk_0_p] + +set_false_path -from [get_ports {pcie_reset_n}] +set_input_delay 0 [get_ports {pcie_reset_n}] diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile b/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile new file mode 100644 index 000000000..b01c32d05 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile @@ -0,0 +1,252 @@ + +# FPGA settings +FPGA_PART = xcvu9p-flgb2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# 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_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_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 += placement.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/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 + +%_fallback.bit: %.bit + echo "open_project $*.xpr" > generate_fallback_bit.tcl + echo "open_run impl_1" >> generate_fallback_bit.tcl + echo "startgroup" >> generate_fallback_bit.tcl + echo "set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]" >> generate_fallback_bit.tcl + echo "endgroup" >> generate_fallback_bit.tcl + echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl + echo "undo" >> generate_fallback_bit.tcl + echo "exit" >> generate_fallback_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT"; + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +%.mcs %.prm: %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +%_fallback.mcs %_fallback.prm: %_fallback.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x0C000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl + echo "exit" >> generate_fallback_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_fallback_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \ + echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done; + +%_full.mcs %_full.prm: %_fallback.bit %.bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit up 0x0C000000 $*_fallback.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl + echo "exit" >> generate_full_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_full_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*_full$$x rev/$*_full_rev$$COUNT$$x; \ + echo "Output: rev/$*_full_rev$$COUNT$$x"; done; + +flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm + echo "open_hw" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl + +flash%: $(FPGA_TOP)%.mcs $(FPGA_TOP)%.prm + echo "open_hw" > flash$*.tcl + echo "connect_hw_server" >> flash$*.tcl + echo "open_hw_target" >> flash$*.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash$*.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash$*.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash$*.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash$*.tcl + echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)$*.prm\"] [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash$*.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash$*.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash$*.tcl + echo "program_hw_devices [current_hw_device]" >> flash$*.tcl + echo "refresh_hw_device [current_hw_device]" >> flash$*.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash$*.tcl + echo "boot_hw_device [current_hw_device]" >> flash$*.tcl + echo "exit" >> flash$*.tcl + vivado -nojournal -nolog -mode batch -source flash$*.tcl diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl b/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl new file mode 100644 index 000000000..c2aee23f7 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl @@ -0,0 +1,279 @@ +# 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 0x4B31093] +set fw_id [expr 0x00000000] +set fw_ver $tag_ver +set board_vendor_id [expr 0x12ba] +set board_device_id [expr 0x9823] +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 {322.265625} +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 "4" +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_PORT_CDC_PIPELINE "0" +dict set params PTP_PEROUT_ENABLE "0" +dict set params PTP_PEROUT_COUNT "1" + +# Queue manager configuration (interface) +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 (port) +dict set params TX_DESC_TABLE_SIZE "32" +dict set params RX_DESC_TABLE_SIZE "32" + +# Scheduler configuration (port) +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" + +# Timestamping configuration (port) +dict set params PTP_TS_ENABLE "1" +dict set params TX_PTP_TS_FIFO_DEPTH "32" +dict set params RX_PTP_TS_FIFO_DEPTH "32" + +# Interface configuration (port) +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_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_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 "25" + +# 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 "25" + +# 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 "4" +dict set params AXIS_ETH_TX_FIFO_PIPELINE "4" +dict set params AXIS_ETH_TX_TS_PIPELINE "4" +dict set params AXIS_ETH_RX_PIPELINE "4" +dict set params AXIS_ETH_RX_FIFO_PIPELINE "4" + +# 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] diff --git a/fpga/mqnic/XUPP3R/fpga_25g/ip/eth_xcvr_gty.tcl b/fpga/mqnic/XUPP3R/fpga_25g/ip/eth_xcvr_gty.tcl new file mode 100644 index 000000000..5880dbf28 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/ip/eth_xcvr_gty.tcl @@ -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 {322.265625} +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 diff --git a/fpga/mqnic/XUPP3R/fpga_25g/ip/pcie4_uscale_plus_0.tcl b/fpga/mqnic/XUPP3R/fpga_25g/ip/pcie4_uscale_plus_0.tcl new file mode 100644 index 000000000..92d15de62 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/ip/pcie4_uscale_plus_0.tcl @@ -0,0 +1,22 @@ + +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 {X16} \ + CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \ + CONFIG.axisten_if_enable_client_tag {true} \ + CONFIG.axisten_if_width {512_bit} \ + 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 {9823} \ + CONFIG.PF0_SUBSYSTEM_VENDOR_ID {12ba} \ + 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} \ +] [get_ips pcie4_uscale_plus_0] diff --git a/fpga/mqnic/XUPP3R/fpga_25g/lib b/fpga/mqnic/XUPP3R/fpga_25g/lib new file mode 120000 index 000000000..9512b3d5e --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/lib @@ -0,0 +1 @@ +../../../lib/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_25g/placement.xdc b/fpga/mqnic/XUPP3R/fpga_25g/placement.xdc new file mode 100644 index 000000000..68b679a41 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/placement.xdc @@ -0,0 +1,32 @@ +# Placement constraints +#create_pblock pblock_slr0 +#add_cells_to_pblock [get_pblocks pblock_slr0] [get_cells -quiet ""] +#resize_pblock [get_pblocks pblock_slr0] -add {SLR0} + +create_pblock pblock_slr1 +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux_inst"] +add_cells_to_pblock -quiet [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux.dma_if_mux_ctrl_inst"] +add_cells_to_pblock -quiet [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/dma_if_mux.dma_if_mux_data_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].interface_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].tx_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_slr1] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].rx_fifo_inst"] +resize_pblock [get_pblocks pblock_slr1] -add {SLR1} + +#create_pblock pblock_slr2 +#add_cells_to_pblock [get_pblocks pblock_slr2] [get_cells -quiet ""] +#resize_pblock [get_pblocks pblock_slr2] -add {SLR2} + +create_pblock pblock_pcie +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "pcie4_uscale_plus_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/pcie_if_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/pcie_axil_master_inst"] +add_cells_to_pblock [get_pblocks pblock_pcie] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/dma_if_pcie_inst"] +resize_pblock [get_pblocks pblock_pcie] -add {CLOCKREGION_X4Y5:CLOCKREGION_X5Y8} + +create_pblock pblock_eth +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "qsfp0_phy_quad_inst qsfp1_phy_quad_inst qsfp2_phy_quad_inst qsfp3_phy_quad_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/mac[*].eth_mac_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].tx_async_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].rx_async_fifo_inst"] +add_cells_to_pblock [get_pblocks pblock_eth] [get_cells -quiet "core_inst/core_inst/core_pcie_inst/core_inst/iface[*].port[*].ptp.tx_ptp_ts_fifo_inst"] +resize_pblock [get_pblocks pblock_eth] -add {CLOCKREGION_X0Y1:CLOCKREGION_X0Y8} diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/common b/fpga/mqnic/XUPP3R/fpga_25g/rtl/common new file mode 120000 index 000000000..449c9409c --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/common @@ -0,0 +1 @@ +../../../../common/rtl/ \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v new file mode 100644 index 000000000..f2fd05e78 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v @@ -0,0 +1,2346 @@ +/* + +Copyright 2019-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. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga # +( + // FW and board IDs + parameter FPGA_ID = 32'h4B31093, + parameter FW_ID = 32'h00000000, + parameter FW_VER = 32'h00_00_01_00, + parameter BOARD_ID = 32'h12ba_9823, + parameter BOARD_VER = 32'h01_00_00_00, + parameter BUILD_DATE = 32'd602976000, + parameter GIT_HASH = 32'hdce357bf, + parameter RELEASE_INFO = 32'h00000000, + + // Structural configuration + parameter IF_COUNT = 2, + parameter PORTS_PER_IF = 1, + parameter SCHED_PER_IF = PORTS_PER_IF, + parameter PORT_MASK = 0, + + // PTP configuration + parameter PTP_CLOCK_PIPELINE = 0, + parameter PTP_PORT_CDC_PIPELINE = 0, + parameter PTP_PEROUT_ENABLE = 0, + parameter PTP_PEROUT_COUNT = 1, + + // Queue manager configuration (interface) + parameter EVENT_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_QUEUE_OP_TABLE_SIZE = 32, + parameter RX_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_CPL_QUEUE_OP_TABLE_SIZE = TX_QUEUE_OP_TABLE_SIZE, + parameter RX_CPL_QUEUE_OP_TABLE_SIZE = RX_QUEUE_OP_TABLE_SIZE, + parameter EVENT_QUEUE_INDEX_WIDTH = 5, + parameter TX_QUEUE_INDEX_WIDTH = 13, + parameter RX_QUEUE_INDEX_WIDTH = 8, + parameter TX_CPL_QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH, + parameter RX_CPL_QUEUE_INDEX_WIDTH = RX_QUEUE_INDEX_WIDTH, + parameter EVENT_QUEUE_PIPELINE = 3, + parameter TX_QUEUE_PIPELINE = 3+(TX_QUEUE_INDEX_WIDTH > 12 ? TX_QUEUE_INDEX_WIDTH-12 : 0), + parameter RX_QUEUE_PIPELINE = 3+(RX_QUEUE_INDEX_WIDTH > 12 ? RX_QUEUE_INDEX_WIDTH-12 : 0), + parameter TX_CPL_QUEUE_PIPELINE = TX_QUEUE_PIPELINE, + parameter RX_CPL_QUEUE_PIPELINE = RX_QUEUE_PIPELINE, + + // TX and RX engine configuration (port) + parameter TX_DESC_TABLE_SIZE = 32, + parameter RX_DESC_TABLE_SIZE = 32, + + // Scheduler configuration (port) + parameter TX_SCHEDULER_OP_TABLE_SIZE = TX_DESC_TABLE_SIZE, + parameter TX_SCHEDULER_PIPELINE = TX_QUEUE_PIPELINE, + parameter TDMA_INDEX_WIDTH = 6, + + // Timestamping configuration (port) + parameter PTP_TS_ENABLE = 1, + parameter TX_PTP_TS_FIFO_DEPTH = 32, + parameter RX_PTP_TS_FIFO_DEPTH = 32, + + // Interface configuration (port) + parameter TX_CHECKSUM_ENABLE = 1, + parameter RX_RSS_ENABLE = 1, + parameter RX_HASH_ENABLE = 1, + parameter RX_CHECKSUM_ENABLE = 1, + parameter TX_FIFO_DEPTH = 32768, + parameter RX_FIFO_DEPTH = 32768, + parameter MAX_TX_SIZE = 9214, + parameter MAX_RX_SIZE = 9214, + parameter TX_RAM_SIZE = 32768, + parameter RX_RAM_SIZE = 32768, + + // Application block configuration + parameter APP_ENABLE = 0, + parameter APP_CTRL_ENABLE = 1, + parameter APP_DMA_ENABLE = 1, + parameter APP_AXIS_DIRECT_ENABLE = 1, + parameter APP_AXIS_SYNC_ENABLE = 1, + parameter APP_AXIS_IF_ENABLE = 1, + parameter APP_STAT_ENABLE = 1, + + // DMA interface configuration + parameter DMA_LEN_WIDTH = 16, + parameter DMA_TAG_WIDTH = 16, + parameter RAM_ADDR_WIDTH = $clog2(TX_RAM_SIZE > RX_RAM_SIZE ? TX_RAM_SIZE : RX_RAM_SIZE), + parameter RAM_PIPELINE = 2, + + // PCIe interface configuration + parameter AXIS_PCIE_DATA_WIDTH = 512, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161, + parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 62 : 137, + parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183, + parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter PF_COUNT = 1, + parameter VF_COUNT = 0, + parameter PCIE_TAG_COUNT = 64, + parameter PCIE_DMA_READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + parameter PCIE_DMA_READ_TX_LIMIT = 16, + parameter PCIE_DMA_READ_TX_FC_ENABLE = 1, + parameter PCIE_DMA_WRITE_OP_TABLE_SIZE = 16, + parameter PCIE_DMA_WRITE_TX_LIMIT = 3, + parameter PCIE_DMA_WRITE_TX_FC_ENABLE = 1, + + // AXI lite interface configuration (control) + parameter AXIL_CTRL_DATA_WIDTH = 32, + parameter AXIL_CTRL_ADDR_WIDTH = 24, + + // AXI lite interface configuration (application control) + parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, + parameter AXIL_APP_CTRL_ADDR_WIDTH = 24, + + // Ethernet interface configuration + parameter AXIS_ETH_SYNC_DATA_WIDTH_DOUBLE = 1, + parameter AXIS_ETH_TX_PIPELINE = 4, + parameter AXIS_ETH_TX_FIFO_PIPELINE = 4, + parameter AXIS_ETH_TX_TS_PIPELINE = 4, + parameter AXIS_ETH_RX_PIPELINE = 4, + parameter AXIS_ETH_RX_FIFO_PIPELINE = 4, + + // Statistics counter subsystem + parameter STAT_ENABLE = 1, + parameter STAT_DMA_ENABLE = 1, + parameter STAT_PCIE_ENABLE = 1, + parameter STAT_INC_WIDTH = 24, + parameter STAT_ID_WIDTH = 12 +) +( + /* + * Clock: 48MHz LVDS + */ + input wire clk_48mhz, + + /* + * GPIO + */ + output wire [3:0] led, + + /* + * I2C and related signals + */ + inout wire eeprom_i2c_scl, + inout wire eeprom_i2c_sda, + output wire fpga_i2c_master_l, + output wire qsfp_ctl_en, + + /* + * PCI express + */ + input wire [15:0] pcie_rx_p, + input wire [15:0] pcie_rx_n, + output wire [15:0] pcie_tx_p, + output wire [15:0] pcie_tx_n, + input wire pcie_refclk_0_p, + input wire pcie_refclk_0_n, + // input wire pcie_refclk_b1_p, + // input wire pcie_refclk_b1_n, + // input wire pcie_refclk_1_p, + // input wire pcie_refclk_1_n, + input wire pcie_reset_n, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp0_tx1_p, + output wire qsfp0_tx1_n, + input wire qsfp0_rx1_p, + input wire qsfp0_rx1_n, + output wire qsfp0_tx2_p, + output wire qsfp0_tx2_n, + input wire qsfp0_rx2_p, + input wire qsfp0_rx2_n, + output wire qsfp0_tx3_p, + output wire qsfp0_tx3_n, + input wire qsfp0_rx3_p, + input wire qsfp0_rx3_n, + output wire qsfp0_tx4_p, + output wire qsfp0_tx4_n, + input wire qsfp0_rx4_p, + input wire qsfp0_rx4_n, + input wire qsfp0_mgt_refclk_b0_p, + input wire qsfp0_mgt_refclk_b0_n, + // input wire qsfp0_mgt_refclk_b1_p, + // input wire qsfp0_mgt_refclk_b1_n, + // input wire qsfp0_mgt_refclk_c0_p, + // input wire qsfp0_mgt_refclk_c0_n, + // input wire qsfp0_mgt_refclk_c1_p, + // input wire qsfp0_mgt_refclk_c1_n, + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + inout wire qsfp0_i2c_scl, + inout wire qsfp0_i2c_sda, + + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + input wire qsfp1_mgt_refclk_b0_p, + input wire qsfp1_mgt_refclk_b0_n, + // input wire qsfp1_mgt_refclk_b1_p, + // input wire qsfp1_mgt_refclk_b1_n, + // input wire qsfp1_mgt_refclk_c2_p, + // input wire qsfp1_mgt_refclk_c2_n, + // input wire qsfp1_mgt_refclk_c3_p, + // input wire qsfp1_mgt_refclk_c3_n, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + inout wire qsfp1_i2c_scl, + inout wire qsfp1_i2c_sda, + + output wire qsfp2_tx1_p, + output wire qsfp2_tx1_n, + input wire qsfp2_rx1_p, + input wire qsfp2_rx1_n, + output wire qsfp2_tx2_p, + output wire qsfp2_tx2_n, + input wire qsfp2_rx2_p, + input wire qsfp2_rx2_n, + output wire qsfp2_tx3_p, + output wire qsfp2_tx3_n, + input wire qsfp2_rx3_p, + input wire qsfp2_rx3_n, + output wire qsfp2_tx4_p, + output wire qsfp2_tx4_n, + input wire qsfp2_rx4_p, + input wire qsfp2_rx4_n, + input wire qsfp2_mgt_refclk_b0_p, + input wire qsfp2_mgt_refclk_b0_n, + // input wire qsfp2_mgt_refclk_b2_p, + // input wire qsfp2_mgt_refclk_b2_n, + // input wire qsfp2_mgt_refclk_d0_p, + // input wire qsfp2_mgt_refclk_d0_n, + // input wire qsfp2_mgt_refclk_d1_p, + // input wire qsfp2_mgt_refclk_d1_n, + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + inout wire qsfp2_i2c_scl, + inout wire qsfp2_i2c_sda, + + output wire qsfp3_tx1_p, + output wire qsfp3_tx1_n, + input wire qsfp3_rx1_p, + input wire qsfp3_rx1_n, + output wire qsfp3_tx2_p, + output wire qsfp3_tx2_n, + input wire qsfp3_rx2_p, + input wire qsfp3_rx2_n, + output wire qsfp3_tx3_p, + output wire qsfp3_tx3_n, + input wire qsfp3_rx3_p, + input wire qsfp3_rx3_n, + output wire qsfp3_tx4_p, + output wire qsfp3_tx4_n, + input wire qsfp3_rx4_p, + input wire qsfp3_rx4_n, + input wire qsfp3_mgt_refclk_b0_p, + input wire qsfp3_mgt_refclk_b0_n, + // input wire qsfp3_mgt_refclk_b3_p, + // input wire qsfp3_mgt_refclk_b3_n, + // input wire qsfp3_mgt_refclk_d2_p, + // input wire qsfp3_mgt_refclk_d2_n, + // input wire qsfp3_mgt_refclk_d3_p, + // input wire qsfp3_mgt_refclk_d3_n, + output wire qsfp3_resetl, + input wire qsfp3_modprsl, + input wire qsfp3_intl, + output wire qsfp3_lpmode, + inout wire qsfp3_i2c_scl, + inout wire qsfp3_i2c_sda +); + +// PTP configuration +parameter PTP_TS_WIDTH = 96; +parameter PTP_TAG_WIDTH = 16; +parameter PTP_PERIOD_NS_WIDTH = 4; +parameter PTP_OFFSET_NS_WIDTH = 32; +parameter PTP_FNS_WIDTH = 32; +parameter PTP_PERIOD_NS = 4'd4; +parameter PTP_PERIOD_FNS = 32'd0; +parameter PTP_USE_SAMPLE_CLOCK = 0; +parameter IF_PTP_PERIOD_NS = 6'h6; +parameter IF_PTP_PERIOD_FNS = 16'h6666; + +// PCIe interface configuration +parameter MSI_COUNT = 32; + +// Ethernet interface configuration +parameter XGMII_DATA_WIDTH = 64; +parameter XGMII_CTRL_WIDTH = XGMII_DATA_WIDTH/8; +parameter AXIS_ETH_DATA_WIDTH = XGMII_DATA_WIDTH; +parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; +parameter AXIS_ETH_SYNC_DATA_WIDTH = AXIS_ETH_DATA_WIDTH*(AXIS_ETH_SYNC_DATA_WIDTH_DOUBLE ? 2 : 1); +parameter AXIS_ETH_TX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TAG_WIDTH : 0) + 1; +parameter AXIS_ETH_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1; + +// Clock and reset +wire pcie_user_clk; +wire pcie_user_reset; + +wire cfgmclk_int; + +wire clk_125mhz_mmcm_out; + +// Internal 125 MHz clock +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst; +wire mmcm_locked; +wire mmcm_clkfb; + +// MMCM instance +// 48 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 125, D = 4 sets Fvco = 1500 MHz +// Divide by 12 to get output frequency of 125 MHz +MMCME4_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(12), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + .CLKFBOUT_MULT_F(125), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(4), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(20.833), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_48mhz), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .out(rst_125mhz_int) +); + +// GPIO +assign qsfp_ctl_en = 1'b1; +assign fpga_i2c_master_l = 1'b0; + +wire eeprom_i2c_scl_i; +wire eeprom_i2c_scl_o; +wire eeprom_i2c_scl_t; +wire eeprom_i2c_sda_i; +wire eeprom_i2c_sda_o; +wire eeprom_i2c_sda_t; + +wire qsfp0_modprsl_int; +wire qsfp0_intl_int; +wire qsfp0_i2c_scl_i; +wire qsfp0_i2c_scl_o; +wire qsfp0_i2c_scl_t; +wire qsfp0_i2c_sda_i; +wire qsfp0_i2c_sda_o; +wire qsfp0_i2c_sda_t; + +wire qsfp1_modprsl_int; +wire qsfp1_intl_int; +wire qsfp1_i2c_scl_i; +wire qsfp1_i2c_scl_o; +wire qsfp1_i2c_scl_t; +wire qsfp1_i2c_sda_i; +wire qsfp1_i2c_sda_o; +wire qsfp1_i2c_sda_t; + +wire qsfp2_modprsl_int; +wire qsfp2_intl_int; +wire qsfp2_i2c_scl_i; +wire qsfp2_i2c_scl_o; +wire qsfp2_i2c_scl_t; +wire qsfp2_i2c_sda_i; +wire qsfp2_i2c_sda_o; +wire qsfp2_i2c_sda_t; + +wire qsfp3_modprsl_int; +wire qsfp3_intl_int; +wire qsfp3_i2c_scl_i; +wire qsfp3_i2c_scl_o; +wire qsfp3_i2c_scl_t; +wire qsfp3_i2c_sda_i; +wire qsfp3_i2c_sda_o; +wire qsfp3_i2c_sda_t; + +reg eeprom_i2c_scl_o_reg; +reg eeprom_i2c_scl_t_reg; +reg eeprom_i2c_sda_o_reg; +reg eeprom_i2c_sda_t_reg; + +reg qsfp0_i2c_scl_o_reg; +reg qsfp0_i2c_scl_t_reg; +reg qsfp0_i2c_sda_o_reg; +reg qsfp0_i2c_sda_t_reg; + +reg qsfp1_i2c_scl_o_reg; +reg qsfp1_i2c_scl_t_reg; +reg qsfp1_i2c_sda_o_reg; +reg qsfp1_i2c_sda_t_reg; + +reg qsfp2_i2c_scl_o_reg; +reg qsfp2_i2c_scl_t_reg; +reg qsfp2_i2c_sda_o_reg; +reg qsfp2_i2c_sda_t_reg; + +reg qsfp3_i2c_scl_o_reg; +reg qsfp3_i2c_scl_t_reg; +reg qsfp3_i2c_sda_o_reg; +reg qsfp3_i2c_sda_t_reg; + +always @(posedge pcie_user_clk) begin + eeprom_i2c_scl_o_reg <= eeprom_i2c_scl_o; + eeprom_i2c_scl_t_reg <= eeprom_i2c_scl_t; + eeprom_i2c_sda_o_reg <= eeprom_i2c_sda_o; + eeprom_i2c_sda_t_reg <= eeprom_i2c_sda_t; + + qsfp0_i2c_scl_o_reg <= qsfp0_i2c_scl_o; + qsfp0_i2c_scl_t_reg <= qsfp0_i2c_scl_t; + qsfp0_i2c_sda_o_reg <= qsfp0_i2c_sda_o; + qsfp0_i2c_sda_t_reg <= qsfp0_i2c_sda_t; + + qsfp1_i2c_scl_o_reg <= qsfp1_i2c_scl_o; + qsfp1_i2c_scl_t_reg <= qsfp1_i2c_scl_t; + qsfp1_i2c_sda_o_reg <= qsfp1_i2c_sda_o; + qsfp1_i2c_sda_t_reg <= qsfp1_i2c_sda_t; + + qsfp2_i2c_scl_o_reg <= qsfp2_i2c_scl_o; + qsfp2_i2c_scl_t_reg <= qsfp2_i2c_scl_t; + qsfp2_i2c_sda_o_reg <= qsfp2_i2c_sda_o; + qsfp2_i2c_sda_t_reg <= qsfp2_i2c_sda_t; + + qsfp3_i2c_scl_o_reg <= qsfp3_i2c_scl_o; + qsfp3_i2c_scl_t_reg <= qsfp3_i2c_scl_t; + qsfp3_i2c_sda_o_reg <= qsfp3_i2c_sda_o; + qsfp3_i2c_sda_t_reg <= qsfp3_i2c_sda_t; +end + +sync_signal #( + .WIDTH(18), + .N(2) +) +sync_signal_inst ( + .clk(pcie_user_clk), + .in({eeprom_i2c_scl, eeprom_i2c_sda, + qsfp0_modprsl, qsfp0_intl, qsfp0_i2c_scl, qsfp0_i2c_sda, + qsfp1_modprsl, qsfp1_intl, qsfp1_i2c_scl, qsfp1_i2c_sda, + qsfp2_modprsl, qsfp2_intl, qsfp2_i2c_scl, qsfp2_i2c_sda, + qsfp3_modprsl, qsfp3_intl, qsfp3_i2c_scl, qsfp3_i2c_sda}), + .out({eeprom_i2c_scl_i, eeprom_i2c_sda_i, + qsfp0_modprsl_int, qsfp0_intl_int, qsfp0_i2c_scl_i, qsfp0_i2c_sda_i, + qsfp1_modprsl_int, qsfp1_intl_int, qsfp1_i2c_scl_i, qsfp1_i2c_sda_i, + qsfp2_modprsl_int, qsfp2_intl_int, qsfp2_i2c_scl_i, qsfp2_i2c_sda_i, + qsfp3_modprsl_int, qsfp3_intl_int, qsfp3_i2c_scl_i, qsfp3_i2c_sda_i}) +); + +assign eeprom_i2c_scl = eeprom_i2c_scl_t_reg ? 1'bz : eeprom_i2c_scl_o_reg; +assign eeprom_i2c_sda = eeprom_i2c_sda_t_reg ? 1'bz : eeprom_i2c_sda_o_reg; + +assign qsfp0_i2c_scl = qsfp0_i2c_scl_t_reg ? 1'bz : qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_sda = qsfp0_i2c_sda_t_reg ? 1'bz : qsfp0_i2c_sda_o_reg; + +assign qsfp1_i2c_scl = qsfp1_i2c_scl_t_reg ? 1'bz : qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_sda = qsfp1_i2c_sda_t_reg ? 1'bz : qsfp1_i2c_sda_o_reg; + +assign qsfp2_i2c_scl = qsfp2_i2c_scl_t_reg ? 1'bz : qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_sda = qsfp2_i2c_sda_t_reg ? 1'bz : qsfp2_i2c_sda_o_reg; + +assign qsfp3_i2c_scl = qsfp3_i2c_scl_t_reg ? 1'bz : qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_sda = qsfp3_i2c_sda_t_reg ? 1'bz : qsfp3_i2c_sda_o_reg; + +// Flash +wire qspi_clk_int; +wire [3:0] qspi_dq_int; +wire [3:0] qspi_dq_i_int; +wire [3:0] qspi_dq_o_int; +wire [3:0] qspi_dq_oe_int; +wire qspi_cs_int; + +reg qspi_clk_reg; +reg [3:0] qspi_dq_o_reg; +reg [3:0] qspi_dq_oe_reg; +reg qspi_cs_reg; + +always @(posedge pcie_user_clk) begin + qspi_clk_reg <= qspi_clk_int; + qspi_dq_o_reg <= qspi_dq_o_int; + qspi_dq_oe_reg <= qspi_dq_oe_int; + qspi_cs_reg <= qspi_cs_int; +end + +sync_signal #( + .WIDTH(4), + .N(2) +) +flash_sync_signal_inst ( + .clk(pcie_user_clk), + .in({qspi_dq_int}), + .out({qspi_dq_i_int}) +); + +// startupe3 instance +STARTUPE3 +startupe3_inst ( + .CFGCLK(), + .CFGMCLK(), + .DI(qspi_dq_int), + .DO(qspi_dq_o_reg), + .DTS(~qspi_dq_oe_reg), + .EOS(), + .FCSBO(qspi_cs_reg), + .FCSBTS(1'b0), + .GSR(1'b0), + .GTS(1'b0), + .KEYCLEARB(1'b1), + .PACK(1'b0), + .PREQ(), + .USRCCLKO(qspi_clk_reg), + .USRCCLKTS(1'b0), + .USRDONEO(1'b0), + .USRDONETS(1'b1) +); + +// FPGA boot +wire fpga_boot; + +reg fpga_boot_sync_reg_0 = 1'b0; +reg fpga_boot_sync_reg_1 = 1'b0; +reg fpga_boot_sync_reg_2 = 1'b0; + +wire icap_avail; +reg [2:0] icap_state = 0; +reg icap_csib_reg = 1'b1; +reg icap_rdwrb_reg = 1'b0; +reg [31:0] icap_di_reg = 32'hffffffff; + +wire [31:0] icap_di_rev; + +assign icap_di_rev[ 7] = icap_di_reg[ 0]; +assign icap_di_rev[ 6] = icap_di_reg[ 1]; +assign icap_di_rev[ 5] = icap_di_reg[ 2]; +assign icap_di_rev[ 4] = icap_di_reg[ 3]; +assign icap_di_rev[ 3] = icap_di_reg[ 4]; +assign icap_di_rev[ 2] = icap_di_reg[ 5]; +assign icap_di_rev[ 1] = icap_di_reg[ 6]; +assign icap_di_rev[ 0] = icap_di_reg[ 7]; + +assign icap_di_rev[15] = icap_di_reg[ 8]; +assign icap_di_rev[14] = icap_di_reg[ 9]; +assign icap_di_rev[13] = icap_di_reg[10]; +assign icap_di_rev[12] = icap_di_reg[11]; +assign icap_di_rev[11] = icap_di_reg[12]; +assign icap_di_rev[10] = icap_di_reg[13]; +assign icap_di_rev[ 9] = icap_di_reg[14]; +assign icap_di_rev[ 8] = icap_di_reg[15]; + +assign icap_di_rev[23] = icap_di_reg[16]; +assign icap_di_rev[22] = icap_di_reg[17]; +assign icap_di_rev[21] = icap_di_reg[18]; +assign icap_di_rev[20] = icap_di_reg[19]; +assign icap_di_rev[19] = icap_di_reg[20]; +assign icap_di_rev[18] = icap_di_reg[21]; +assign icap_di_rev[17] = icap_di_reg[22]; +assign icap_di_rev[16] = icap_di_reg[23]; + +assign icap_di_rev[31] = icap_di_reg[24]; +assign icap_di_rev[30] = icap_di_reg[25]; +assign icap_di_rev[29] = icap_di_reg[26]; +assign icap_di_rev[28] = icap_di_reg[27]; +assign icap_di_rev[27] = icap_di_reg[28]; +assign icap_di_rev[26] = icap_di_reg[29]; +assign icap_di_rev[25] = icap_di_reg[30]; +assign icap_di_rev[24] = icap_di_reg[31]; + +always @(posedge clk_125mhz_int) begin + case (icap_state) + 0: begin + icap_state <= 0; + icap_csib_reg <= 1'b1; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + + if (fpga_boot_sync_reg_2 && icap_avail) begin + icap_state <= 1; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + end + end + 1: begin + icap_state <= 2; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hAA995566; // sync word + end + 2: begin + icap_state <= 3; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + 3: begin + icap_state <= 4; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h30008001; // write 1 word to CMD + end + 4: begin + icap_state <= 5; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h0000000F; // IPROG + end + 5: begin + icap_state <= 0; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + endcase + + fpga_boot_sync_reg_0 <= fpga_boot; + fpga_boot_sync_reg_1 <= fpga_boot_sync_reg_0; + fpga_boot_sync_reg_2 <= fpga_boot_sync_reg_1; +end + +ICAPE3 +icape3_inst ( + .AVAIL(icap_avail), + .CLK(clk_125mhz_int), + .CSIB(icap_csib_reg), + .I(icap_di_rev), + .O(), + .PRDONE(), + .PRERROR(), + .RDWRB(icap_rdwrb_reg) +); + +// PCIe +wire pcie_sys_clk; +wire pcie_sys_clk_gt; + +IBUFDS_GTE4 #( + .REFCLK_HROW_CK_SEL(2'b00) +) +ibufds_gte4_pcie_mgt_refclk_inst ( + .I (pcie_refclk_0_p), + .IB (pcie_refclk_0_n), + .CEB (1'b0), + .O (pcie_sys_clk_gt), + .ODIV2 (pcie_sys_clk) +); + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rq_tkeep; +wire axis_rq_tlast; +wire axis_rq_tready; +wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] axis_rq_tuser; +wire axis_rq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rc_tkeep; +wire axis_rc_tlast; +wire axis_rc_tready; +wire [AXIS_PCIE_RC_USER_WIDTH-1:0] axis_rc_tuser; +wire axis_rc_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cq_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cq_tkeep; +wire axis_cq_tlast; +wire axis_cq_tready; +wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] axis_cq_tuser; +wire axis_cq_tvalid; + +wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cc_tdata; +wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cc_tkeep; +wire axis_cc_tlast; +wire axis_cc_tready; +wire [AXIS_PCIE_CC_USER_WIDTH-1:0] axis_cc_tuser; +wire axis_cc_tvalid; + +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num0; +wire pcie_rq_seq_num_vld0; +wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num1; +wire pcie_rq_seq_num_vld1; + +wire [3:0] pcie_tfc_nph_av; +wire [3:0] pcie_tfc_npd_av; + +wire [2:0] cfg_max_payload; +wire [2:0] cfg_max_read_req; + +wire [9:0] cfg_mgmt_addr; +wire [7:0] cfg_mgmt_function_number; +wire cfg_mgmt_write; +wire [31:0] cfg_mgmt_write_data; +wire [3:0] cfg_mgmt_byte_enable; +wire cfg_mgmt_read; +wire [31:0] cfg_mgmt_read_data; +wire cfg_mgmt_read_write_done; + +wire [7:0] cfg_fc_ph; +wire [11:0] cfg_fc_pd; +wire [7:0] cfg_fc_nph; +wire [11:0] cfg_fc_npd; +wire [7:0] cfg_fc_cplh; +wire [11:0] cfg_fc_cpld; +wire [2:0] cfg_fc_sel; + +wire [3:0] cfg_interrupt_msi_enable; +wire [11:0] cfg_interrupt_msi_mmenable; +wire cfg_interrupt_msi_mask_update; +wire [31:0] cfg_interrupt_msi_data; +wire [3:0] cfg_interrupt_msi_select; +wire [31:0] cfg_interrupt_msi_int; +wire [31:0] cfg_interrupt_msi_pending_status; +wire cfg_interrupt_msi_pending_status_data_enable; +wire [3:0] cfg_interrupt_msi_pending_status_function_num; +wire cfg_interrupt_msi_sent; +wire cfg_interrupt_msi_fail; +wire [2:0] cfg_interrupt_msi_attr; +wire cfg_interrupt_msi_tph_present; +wire [1:0] cfg_interrupt_msi_tph_type; +wire [8:0] cfg_interrupt_msi_tph_st_tag; +wire [3:0] cfg_interrupt_msi_function_number; + +wire status_error_cor; +wire status_error_uncor; + +// extra register for pcie_user_reset signal +wire pcie_user_reset_int; +(* shreg_extract = "no" *) +reg pcie_user_reset_reg_1 = 1'b1; +(* shreg_extract = "no" *) +reg pcie_user_reset_reg_2 = 1'b1; + +always @(posedge pcie_user_clk) begin + pcie_user_reset_reg_1 <= pcie_user_reset_int; + pcie_user_reset_reg_2 <= pcie_user_reset_reg_1; +end + +BUFG +pcie_user_reset_bufg_inst ( + .I(pcie_user_reset_reg_2), + .O(pcie_user_reset) +); + +pcie4_uscale_plus_0 +pcie4_uscale_plus_inst ( + .pci_exp_txn(pcie_tx_n), + .pci_exp_txp(pcie_tx_p), + .pci_exp_rxn(pcie_rx_n), + .pci_exp_rxp(pcie_rx_p), + .user_clk(pcie_user_clk), + .user_reset(pcie_user_reset_int), + .user_lnk_up(), + + .s_axis_rq_tdata(axis_rq_tdata), + .s_axis_rq_tkeep(axis_rq_tkeep), + .s_axis_rq_tlast(axis_rq_tlast), + .s_axis_rq_tready(axis_rq_tready), + .s_axis_rq_tuser(axis_rq_tuser), + .s_axis_rq_tvalid(axis_rq_tvalid), + + .m_axis_rc_tdata(axis_rc_tdata), + .m_axis_rc_tkeep(axis_rc_tkeep), + .m_axis_rc_tlast(axis_rc_tlast), + .m_axis_rc_tready(axis_rc_tready), + .m_axis_rc_tuser(axis_rc_tuser), + .m_axis_rc_tvalid(axis_rc_tvalid), + + .m_axis_cq_tdata(axis_cq_tdata), + .m_axis_cq_tkeep(axis_cq_tkeep), + .m_axis_cq_tlast(axis_cq_tlast), + .m_axis_cq_tready(axis_cq_tready), + .m_axis_cq_tuser(axis_cq_tuser), + .m_axis_cq_tvalid(axis_cq_tvalid), + + .s_axis_cc_tdata(axis_cc_tdata), + .s_axis_cc_tkeep(axis_cc_tkeep), + .s_axis_cc_tlast(axis_cc_tlast), + .s_axis_cc_tready(axis_cc_tready), + .s_axis_cc_tuser(axis_cc_tuser), + .s_axis_cc_tvalid(axis_cc_tvalid), + + .pcie_rq_seq_num0(pcie_rq_seq_num0), + .pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0), + .pcie_rq_seq_num1(pcie_rq_seq_num1), + .pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1), + .pcie_rq_tag0(), + .pcie_rq_tag1(), + .pcie_rq_tag_av(), + .pcie_rq_tag_vld0(), + .pcie_rq_tag_vld1(), + + .pcie_tfc_nph_av(pcie_tfc_nph_av), + .pcie_tfc_npd_av(pcie_tfc_npd_av), + + .pcie_cq_np_req(1'b1), + .pcie_cq_np_req_count(), + + .cfg_phy_link_down(), + .cfg_phy_link_status(), + .cfg_negotiated_width(), + .cfg_current_speed(), + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_function_status(), + .cfg_function_power_state(), + .cfg_vf_status(), + .cfg_vf_power_state(), + .cfg_link_power_state(), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + .cfg_mgmt_debug_access(1'b0), + + .cfg_err_cor_out(), + .cfg_err_nonfatal_out(), + .cfg_err_fatal_out(), + .cfg_local_error_valid(), + .cfg_local_error_out(), + .cfg_ltssm_state(), + .cfg_rx_pm_state(), + .cfg_tx_pm_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(), + + .cfg_msg_received(), + .cfg_msg_received_data(), + .cfg_msg_received_type(), + .cfg_msg_transmit(1'b0), + .cfg_msg_transmit_type(3'd0), + .cfg_msg_transmit_data(32'd0), + .cfg_msg_transmit_done(), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_dsn(64'd0), + + .cfg_power_state_change_ack(1'b1), + .cfg_power_state_change_interrupt(), + + .cfg_err_cor_in(status_error_cor), + .cfg_err_uncor_in(status_error_uncor), + .cfg_flr_in_process(), + .cfg_flr_done(4'd0), + .cfg_vf_flr_in_process(), + .cfg_vf_flr_func_num(8'd0), + .cfg_vf_flr_done(8'd0), + + .cfg_link_training_enable(1'b1), + + .cfg_interrupt_int(4'd0), + .cfg_interrupt_pending(4'd0), + .cfg_interrupt_sent(), + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_pm_aspm_l1_entry_reject(1'b0), + .cfg_pm_aspm_tx_l0s_entry_disable(1'b0), + + .cfg_hot_reset_out(), + + .cfg_config_space_enable(1'b1), + .cfg_req_pm_transition_l23_ready(1'b0), + .cfg_hot_reset_in(1'b0), + + .cfg_ds_port_number(8'd0), + .cfg_ds_bus_number(8'd0), + .cfg_ds_device_number(5'd0), + //.cfg_ds_function_number(3'd0), + + //.cfg_subsys_vend_id(16'h1234), + + .sys_clk(pcie_sys_clk), + .sys_clk_gt(pcie_sys_clk_gt), + .sys_reset(pcie_reset_n), + + .phy_rdy_out() +); + +// XGMII 10G PHY + +// QSFP0 +wire qsfp0_tx_clk_1_int; +wire qsfp0_tx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_1_int; +wire qsfp0_tx_prbs31_enable_1_int; +wire qsfp0_rx_clk_1_int; +wire qsfp0_rx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_1_int; +wire qsfp0_rx_prbs31_enable_1_int; +wire [6:0] qsfp0_rx_error_count_1_int; +wire qsfp0_tx_clk_2_int; +wire qsfp0_tx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_2_int; +wire qsfp0_tx_prbs31_enable_2_int; +wire qsfp0_rx_clk_2_int; +wire qsfp0_rx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_2_int; +wire qsfp0_rx_prbs31_enable_2_int; +wire [6:0] qsfp0_rx_error_count_2_int; +wire qsfp0_tx_clk_3_int; +wire qsfp0_tx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_3_int; +wire qsfp0_tx_prbs31_enable_3_int; +wire qsfp0_rx_clk_3_int; +wire qsfp0_rx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_3_int; +wire qsfp0_rx_prbs31_enable_3_int; +wire [6:0] qsfp0_rx_error_count_3_int; +wire qsfp0_tx_clk_4_int; +wire qsfp0_tx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_4_int; +wire qsfp0_tx_prbs31_enable_4_int; +wire qsfp0_rx_clk_4_int; +wire qsfp0_rx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_4_int; +wire qsfp0_rx_prbs31_enable_4_int; +wire [6:0] qsfp0_rx_error_count_4_int; + +wire qsfp0_drp_clk = clk_125mhz_int; +wire qsfp0_drp_rst = rst_125mhz_int; +wire [23:0] qsfp0_drp_addr; +wire [15:0] qsfp0_drp_di; +wire qsfp0_drp_en; +wire qsfp0_drp_we; +wire [15:0] qsfp0_drp_do; +wire qsfp0_drp_rdy; + +wire qsfp0_rx_block_lock_1; +wire qsfp0_rx_block_lock_2; +wire qsfp0_rx_block_lock_3; +wire qsfp0_rx_block_lock_4; + +wire qsfp0_gtpowergood; + +wire qsfp0_mgt_refclk_b0; +wire qsfp0_mgt_refclk_b0_int; +wire qsfp0_mgt_refclk_b0_bufg; + +IBUFDS_GTE4 ibufds_gte4_qsfp0_mgt_refclk_b0_inst ( + .I (qsfp0_mgt_refclk_b0_p), + .IB (qsfp0_mgt_refclk_b0_n), + .CEB (1'b0), + .O (qsfp0_mgt_refclk_b0), + .ODIV2 (qsfp0_mgt_refclk_b0_int) +); + +BUFG_GT bufg_gt_qsfp0_mgt_refclk_b0_inst ( + .CE (qsfp0_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp0_mgt_refclk_b0_int), + .O (qsfp0_mgt_refclk_b0_bufg) +); + +wire qsfp0_rst; + +sync_reset #( + .N(4) +) +qsfp0_sync_reset_inst ( + .clk(qsfp0_mgt_refclk_b0_bufg), + .rst(rst_125mhz_int), + .out(qsfp0_rst) +); + +eth_xcvr_phy_10g_gty_quad_wrapper #( + .PRBS31_ENABLE(1), + .TX_SERDES_PIPELINE(1), + .RX_SERDES_PIPELINE(1), + .COUNT_125US(125000/2.56) +) +qsfp0_phy_quad_inst ( + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(qsfp0_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(qsfp0_gtpowergood), + .xcvr_ref_clk(qsfp0_mgt_refclk_b0), + + /* + * DRP + */ + .drp_clk(qsfp0_drp_clk), + .drp_rst(qsfp0_drp_rst), + .drp_addr(qsfp0_drp_addr), + .drp_di(qsfp0_drp_di), + .drp_en(qsfp0_drp_en), + .drp_we(qsfp0_drp_we), + .drp_do(qsfp0_drp_do), + .drp_rdy(qsfp0_drp_rdy), + + /* + * Serial data + */ + .xcvr_txp({qsfp0_tx4_p, qsfp0_tx3_p, qsfp0_tx2_p, qsfp0_tx1_p}), + .xcvr_txn({qsfp0_tx4_n, qsfp0_tx3_n, qsfp0_tx2_n, qsfp0_tx1_n}), + .xcvr_rxp({qsfp0_rx4_p, qsfp0_rx3_p, qsfp0_rx2_p, qsfp0_rx1_p}), + .xcvr_rxn({qsfp0_rx4_n, qsfp0_rx3_n, qsfp0_rx2_n, qsfp0_rx1_n}), + + /* + * PHY connections + */ + .phy_1_tx_clk(qsfp0_tx_clk_1_int), + .phy_1_tx_rst(qsfp0_tx_rst_1_int), + .phy_1_xgmii_txd(qsfp0_txd_1_int), + .phy_1_xgmii_txc(qsfp0_txc_1_int), + .phy_1_rx_clk(qsfp0_rx_clk_1_int), + .phy_1_rx_rst(qsfp0_rx_rst_1_int), + .phy_1_xgmii_rxd(qsfp0_rxd_1_int), + .phy_1_xgmii_rxc(qsfp0_rxc_1_int), + .phy_1_tx_bad_block(), + .phy_1_rx_error_count(qsfp0_rx_error_count_1_int), + .phy_1_rx_bad_block(), + .phy_1_rx_sequence_error(), + .phy_1_rx_block_lock(qsfp0_rx_block_lock_1), + .phy_1_rx_high_ber(), + .phy_1_tx_prbs31_enable(qsfp0_tx_prbs31_enable_1_int), + .phy_1_rx_prbs31_enable(qsfp0_rx_prbs31_enable_1_int), + + .phy_2_tx_clk(qsfp0_tx_clk_2_int), + .phy_2_tx_rst(qsfp0_tx_rst_2_int), + .phy_2_xgmii_txd(qsfp0_txd_2_int), + .phy_2_xgmii_txc(qsfp0_txc_2_int), + .phy_2_rx_clk(qsfp0_rx_clk_2_int), + .phy_2_rx_rst(qsfp0_rx_rst_2_int), + .phy_2_xgmii_rxd(qsfp0_rxd_2_int), + .phy_2_xgmii_rxc(qsfp0_rxc_2_int), + .phy_2_tx_bad_block(), + .phy_2_rx_error_count(qsfp0_rx_error_count_2_int), + .phy_2_rx_bad_block(), + .phy_2_rx_sequence_error(), + .phy_2_rx_block_lock(qsfp0_rx_block_lock_2), + .phy_2_rx_high_ber(), + .phy_2_tx_prbs31_enable(qsfp0_tx_prbs31_enable_2_int), + .phy_2_rx_prbs31_enable(qsfp0_rx_prbs31_enable_2_int), + + .phy_3_tx_clk(qsfp0_tx_clk_3_int), + .phy_3_tx_rst(qsfp0_tx_rst_3_int), + .phy_3_xgmii_txd(qsfp0_txd_3_int), + .phy_3_xgmii_txc(qsfp0_txc_3_int), + .phy_3_rx_clk(qsfp0_rx_clk_3_int), + .phy_3_rx_rst(qsfp0_rx_rst_3_int), + .phy_3_xgmii_rxd(qsfp0_rxd_3_int), + .phy_3_xgmii_rxc(qsfp0_rxc_3_int), + .phy_3_tx_bad_block(), + .phy_3_rx_error_count(qsfp0_rx_error_count_3_int), + .phy_3_rx_bad_block(), + .phy_3_rx_sequence_error(), + .phy_3_rx_block_lock(qsfp0_rx_block_lock_3), + .phy_3_rx_high_ber(), + .phy_3_tx_prbs31_enable(qsfp0_tx_prbs31_enable_3_int), + .phy_3_rx_prbs31_enable(qsfp0_rx_prbs31_enable_3_int), + + .phy_4_tx_clk(qsfp0_tx_clk_4_int), + .phy_4_tx_rst(qsfp0_tx_rst_4_int), + .phy_4_xgmii_txd(qsfp0_txd_4_int), + .phy_4_xgmii_txc(qsfp0_txc_4_int), + .phy_4_rx_clk(qsfp0_rx_clk_4_int), + .phy_4_rx_rst(qsfp0_rx_rst_4_int), + .phy_4_xgmii_rxd(qsfp0_rxd_4_int), + .phy_4_xgmii_rxc(qsfp0_rxc_4_int), + .phy_4_tx_bad_block(), + .phy_4_rx_error_count(qsfp0_rx_error_count_4_int), + .phy_4_rx_bad_block(), + .phy_4_rx_sequence_error(), + .phy_4_rx_block_lock(qsfp0_rx_block_lock_4), + .phy_4_rx_high_ber(), + .phy_4_tx_prbs31_enable(qsfp0_tx_prbs31_enable_4_int), + .phy_4_rx_prbs31_enable(qsfp0_rx_prbs31_enable_4_int) +); + +// QSFP1 +wire qsfp1_tx_clk_1_int; +wire qsfp1_tx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_1_int; +wire qsfp1_tx_prbs31_enable_1_int; +wire qsfp1_rx_clk_1_int; +wire qsfp1_rx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_1_int; +wire qsfp1_rx_prbs31_enable_1_int; +wire [6:0] qsfp1_rx_error_count_1_int; +wire qsfp1_tx_clk_2_int; +wire qsfp1_tx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_2_int; +wire qsfp1_tx_prbs31_enable_2_int; +wire qsfp1_rx_clk_2_int; +wire qsfp1_rx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_2_int; +wire qsfp1_rx_prbs31_enable_2_int; +wire [6:0] qsfp1_rx_error_count_2_int; +wire qsfp1_tx_clk_3_int; +wire qsfp1_tx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_3_int; +wire qsfp1_tx_prbs31_enable_3_int; +wire qsfp1_rx_clk_3_int; +wire qsfp1_rx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_3_int; +wire qsfp1_rx_prbs31_enable_3_int; +wire [6:0] qsfp1_rx_error_count_3_int; +wire qsfp1_tx_clk_4_int; +wire qsfp1_tx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_4_int; +wire qsfp1_tx_prbs31_enable_4_int; +wire qsfp1_rx_clk_4_int; +wire qsfp1_rx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_4_int; +wire qsfp1_rx_prbs31_enable_4_int; +wire [6:0] qsfp1_rx_error_count_4_int; + +wire qsfp1_drp_clk = clk_125mhz_int; +wire qsfp1_drp_rst = rst_125mhz_int; +wire [23:0] qsfp1_drp_addr; +wire [15:0] qsfp1_drp_di; +wire qsfp1_drp_en; +wire qsfp1_drp_we; +wire [15:0] qsfp1_drp_do; +wire qsfp1_drp_rdy; + +wire qsfp1_rx_block_lock_1; +wire qsfp1_rx_block_lock_2; +wire qsfp1_rx_block_lock_3; +wire qsfp1_rx_block_lock_4; + +wire qsfp1_gtpowergood; + +wire qsfp1_mgt_refclk_b0; +wire qsfp1_mgt_refclk_b0_int; +wire qsfp1_mgt_refclk_b0_bufg; + +IBUFDS_GTE4 ibufds_gte4_qsfp1_mgt_refclk_b0_inst ( + .I (qsfp1_mgt_refclk_b0_p), + .IB (qsfp1_mgt_refclk_b0_n), + .CEB (1'b0), + .O (qsfp1_mgt_refclk_b0), + .ODIV2 (qsfp1_mgt_refclk_b0_int) +); + +BUFG_GT bufg_gt_qsfp1_mgt_refclk_b0_inst ( + .CE (qsfp1_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp1_mgt_refclk_b0_int), + .O (qsfp1_mgt_refclk_b0_bufg) +); + +wire qsfp1_rst; + +sync_reset #( + .N(4) +) +qsfp1_sync_reset_inst ( + .clk(qsfp1_mgt_refclk_b0_bufg), + .rst(rst_125mhz_int), + .out(qsfp1_rst) +); + +eth_xcvr_phy_10g_gty_quad_wrapper #( + .PRBS31_ENABLE(1), + .TX_SERDES_PIPELINE(1), + .RX_SERDES_PIPELINE(1), + .COUNT_125US(125000/2.56) +) +qsfp1_phy_quad_inst ( + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(qsfp1_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(qsfp1_gtpowergood), + .xcvr_ref_clk(qsfp1_mgt_refclk_b0), + + /* + * DRP + */ + .drp_clk(qsfp1_drp_clk), + .drp_rst(qsfp1_drp_rst), + .drp_addr(qsfp1_drp_addr), + .drp_di(qsfp1_drp_di), + .drp_en(qsfp1_drp_en), + .drp_we(qsfp1_drp_we), + .drp_do(qsfp1_drp_do), + .drp_rdy(qsfp1_drp_rdy), + + /* + * Serial data + */ + .xcvr_txp({qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), + .xcvr_txn({qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), + .xcvr_rxp({qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), + .xcvr_rxn({qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), + + /* + * PHY connections + */ + .phy_1_tx_clk(qsfp1_tx_clk_1_int), + .phy_1_tx_rst(qsfp1_tx_rst_1_int), + .phy_1_xgmii_txd(qsfp1_txd_1_int), + .phy_1_xgmii_txc(qsfp1_txc_1_int), + .phy_1_rx_clk(qsfp1_rx_clk_1_int), + .phy_1_rx_rst(qsfp1_rx_rst_1_int), + .phy_1_xgmii_rxd(qsfp1_rxd_1_int), + .phy_1_xgmii_rxc(qsfp1_rxc_1_int), + .phy_1_tx_bad_block(), + .phy_1_rx_error_count(qsfp1_rx_error_count_1_int), + .phy_1_rx_bad_block(), + .phy_1_rx_sequence_error(), + .phy_1_rx_block_lock(qsfp1_rx_block_lock_1), + .phy_1_rx_high_ber(), + .phy_1_tx_prbs31_enable(qsfp1_tx_prbs31_enable_1_int), + .phy_1_rx_prbs31_enable(qsfp1_rx_prbs31_enable_1_int), + + .phy_2_tx_clk(qsfp1_tx_clk_2_int), + .phy_2_tx_rst(qsfp1_tx_rst_2_int), + .phy_2_xgmii_txd(qsfp1_txd_2_int), + .phy_2_xgmii_txc(qsfp1_txc_2_int), + .phy_2_rx_clk(qsfp1_rx_clk_2_int), + .phy_2_rx_rst(qsfp1_rx_rst_2_int), + .phy_2_xgmii_rxd(qsfp1_rxd_2_int), + .phy_2_xgmii_rxc(qsfp1_rxc_2_int), + .phy_2_tx_bad_block(), + .phy_2_rx_error_count(qsfp1_rx_error_count_2_int), + .phy_2_rx_bad_block(), + .phy_2_rx_sequence_error(), + .phy_2_rx_block_lock(qsfp1_rx_block_lock_2), + .phy_2_rx_high_ber(), + .phy_2_tx_prbs31_enable(qsfp1_tx_prbs31_enable_2_int), + .phy_2_rx_prbs31_enable(qsfp1_rx_prbs31_enable_2_int), + + .phy_3_tx_clk(qsfp1_tx_clk_3_int), + .phy_3_tx_rst(qsfp1_tx_rst_3_int), + .phy_3_xgmii_txd(qsfp1_txd_3_int), + .phy_3_xgmii_txc(qsfp1_txc_3_int), + .phy_3_rx_clk(qsfp1_rx_clk_3_int), + .phy_3_rx_rst(qsfp1_rx_rst_3_int), + .phy_3_xgmii_rxd(qsfp1_rxd_3_int), + .phy_3_xgmii_rxc(qsfp1_rxc_3_int), + .phy_3_tx_bad_block(), + .phy_3_rx_error_count(qsfp1_rx_error_count_3_int), + .phy_3_rx_bad_block(), + .phy_3_rx_sequence_error(), + .phy_3_rx_block_lock(qsfp1_rx_block_lock_3), + .phy_3_rx_high_ber(), + .phy_3_tx_prbs31_enable(qsfp1_tx_prbs31_enable_3_int), + .phy_3_rx_prbs31_enable(qsfp1_rx_prbs31_enable_3_int), + + .phy_4_tx_clk(qsfp1_tx_clk_4_int), + .phy_4_tx_rst(qsfp1_tx_rst_4_int), + .phy_4_xgmii_txd(qsfp1_txd_4_int), + .phy_4_xgmii_txc(qsfp1_txc_4_int), + .phy_4_rx_clk(qsfp1_rx_clk_4_int), + .phy_4_rx_rst(qsfp1_rx_rst_4_int), + .phy_4_xgmii_rxd(qsfp1_rxd_4_int), + .phy_4_xgmii_rxc(qsfp1_rxc_4_int), + .phy_4_tx_bad_block(), + .phy_4_rx_error_count(qsfp1_rx_error_count_4_int), + .phy_4_rx_bad_block(), + .phy_4_rx_sequence_error(), + .phy_4_rx_block_lock(qsfp1_rx_block_lock_4), + .phy_4_rx_high_ber(), + .phy_4_tx_prbs31_enable(qsfp1_tx_prbs31_enable_4_int), + .phy_4_rx_prbs31_enable(qsfp1_rx_prbs31_enable_4_int) +); + +// QSFP2 +wire qsfp2_tx_clk_1_int; +wire qsfp2_tx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_1_int; +wire qsfp2_tx_prbs31_enable_1_int; +wire qsfp2_rx_clk_1_int; +wire qsfp2_rx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_1_int; +wire qsfp2_rx_prbs31_enable_1_int; +wire [6:0] qsfp2_rx_error_count_1_int; +wire qsfp2_tx_clk_2_int; +wire qsfp2_tx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_2_int; +wire qsfp2_tx_prbs31_enable_2_int; +wire qsfp2_rx_clk_2_int; +wire qsfp2_rx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_2_int; +wire qsfp2_rx_prbs31_enable_2_int; +wire [6:0] qsfp2_rx_error_count_2_int; +wire qsfp2_tx_clk_3_int; +wire qsfp2_tx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_3_int; +wire qsfp2_tx_prbs31_enable_3_int; +wire qsfp2_rx_clk_3_int; +wire qsfp2_rx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_3_int; +wire qsfp2_rx_prbs31_enable_3_int; +wire [6:0] qsfp2_rx_error_count_3_int; +wire qsfp2_tx_clk_4_int; +wire qsfp2_tx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_4_int; +wire qsfp2_tx_prbs31_enable_4_int; +wire qsfp2_rx_clk_4_int; +wire qsfp2_rx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_4_int; +wire qsfp2_rx_prbs31_enable_4_int; +wire [6:0] qsfp2_rx_error_count_4_int; + +wire qsfp2_drp_clk = clk_125mhz_int; +wire qsfp2_drp_rst = rst_125mhz_int; +wire [23:0] qsfp2_drp_addr; +wire [15:0] qsfp2_drp_di; +wire qsfp2_drp_en; +wire qsfp2_drp_we; +wire [15:0] qsfp2_drp_do; +wire qsfp2_drp_rdy; + +wire qsfp2_rx_block_lock_1; +wire qsfp2_rx_block_lock_2; +wire qsfp2_rx_block_lock_3; +wire qsfp2_rx_block_lock_4; + +wire qsfp2_gtpowergood; + +wire qsfp2_mgt_refclk_b0; +wire qsfp2_mgt_refclk_b0_int; +wire qsfp2_mgt_refclk_b0_bufg; + +IBUFDS_GTE4 ibufds_gte4_qsfp2_mgt_refclk_b0_inst ( + .I (qsfp2_mgt_refclk_b0_p), + .IB (qsfp2_mgt_refclk_b0_n), + .CEB (1'b0), + .O (qsfp2_mgt_refclk_b0), + .ODIV2 (qsfp2_mgt_refclk_b0_int) +); + +BUFG_GT bufg_gt_qsfp2_mgt_refclk_b0_inst ( + .CE (qsfp2_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp2_mgt_refclk_b0_int), + .O (qsfp2_mgt_refclk_b0_bufg) +); + +wire qsfp2_rst; + +sync_reset #( + .N(4) +) +qsfp2_sync_reset_inst ( + .clk(qsfp2_mgt_refclk_b0_bufg), + .rst(rst_125mhz_int), + .out(qsfp2_rst) +); + +eth_xcvr_phy_10g_gty_quad_wrapper #( + .PRBS31_ENABLE(1), + .TX_SERDES_PIPELINE(1), + .RX_SERDES_PIPELINE(1), + .COUNT_125US(125000/2.56) +) +qsfp2_phy_quad_inst ( + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(qsfp2_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(qsfp2_gtpowergood), + .xcvr_ref_clk(qsfp2_mgt_refclk_b0), + + /* + * DRP + */ + .drp_clk(qsfp2_drp_clk), + .drp_rst(qsfp2_drp_rst), + .drp_addr(qsfp2_drp_addr), + .drp_di(qsfp2_drp_di), + .drp_en(qsfp2_drp_en), + .drp_we(qsfp2_drp_we), + .drp_do(qsfp2_drp_do), + .drp_rdy(qsfp2_drp_rdy), + + /* + * Serial data + */ + .xcvr_txp({qsfp2_tx4_p, qsfp2_tx3_p, qsfp2_tx2_p, qsfp2_tx1_p}), + .xcvr_txn({qsfp2_tx4_n, qsfp2_tx3_n, qsfp2_tx2_n, qsfp2_tx1_n}), + .xcvr_rxp({qsfp2_rx4_p, qsfp2_rx3_p, qsfp2_rx2_p, qsfp2_rx1_p}), + .xcvr_rxn({qsfp2_rx4_n, qsfp2_rx3_n, qsfp2_rx2_n, qsfp2_rx1_n}), + + /* + * PHY connections + */ + .phy_1_tx_clk(qsfp2_tx_clk_1_int), + .phy_1_tx_rst(qsfp2_tx_rst_1_int), + .phy_1_xgmii_txd(qsfp2_txd_1_int), + .phy_1_xgmii_txc(qsfp2_txc_1_int), + .phy_1_rx_clk(qsfp2_rx_clk_1_int), + .phy_1_rx_rst(qsfp2_rx_rst_1_int), + .phy_1_xgmii_rxd(qsfp2_rxd_1_int), + .phy_1_xgmii_rxc(qsfp2_rxc_1_int), + .phy_1_tx_bad_block(), + .phy_1_rx_error_count(qsfp2_rx_error_count_1_int), + .phy_1_rx_bad_block(), + .phy_1_rx_sequence_error(), + .phy_1_rx_block_lock(qsfp2_rx_block_lock_1), + .phy_1_rx_high_ber(), + .phy_1_tx_prbs31_enable(qsfp2_tx_prbs31_enable_1_int), + .phy_1_rx_prbs31_enable(qsfp2_rx_prbs31_enable_1_int), + + .phy_2_tx_clk(qsfp2_tx_clk_2_int), + .phy_2_tx_rst(qsfp2_tx_rst_2_int), + .phy_2_xgmii_txd(qsfp2_txd_2_int), + .phy_2_xgmii_txc(qsfp2_txc_2_int), + .phy_2_rx_clk(qsfp2_rx_clk_2_int), + .phy_2_rx_rst(qsfp2_rx_rst_2_int), + .phy_2_xgmii_rxd(qsfp2_rxd_2_int), + .phy_2_xgmii_rxc(qsfp2_rxc_2_int), + .phy_2_tx_bad_block(), + .phy_2_rx_error_count(qsfp2_rx_error_count_2_int), + .phy_2_rx_bad_block(), + .phy_2_rx_sequence_error(), + .phy_2_rx_block_lock(qsfp2_rx_block_lock_2), + .phy_2_rx_high_ber(), + .phy_2_tx_prbs31_enable(qsfp2_tx_prbs31_enable_2_int), + .phy_2_rx_prbs31_enable(qsfp2_rx_prbs31_enable_2_int), + + .phy_3_tx_clk(qsfp2_tx_clk_3_int), + .phy_3_tx_rst(qsfp2_tx_rst_3_int), + .phy_3_xgmii_txd(qsfp2_txd_3_int), + .phy_3_xgmii_txc(qsfp2_txc_3_int), + .phy_3_rx_clk(qsfp2_rx_clk_3_int), + .phy_3_rx_rst(qsfp2_rx_rst_3_int), + .phy_3_xgmii_rxd(qsfp2_rxd_3_int), + .phy_3_xgmii_rxc(qsfp2_rxc_3_int), + .phy_3_tx_bad_block(), + .phy_3_rx_error_count(qsfp2_rx_error_count_3_int), + .phy_3_rx_bad_block(), + .phy_3_rx_sequence_error(), + .phy_3_rx_block_lock(qsfp2_rx_block_lock_3), + .phy_3_rx_high_ber(), + .phy_3_tx_prbs31_enable(qsfp2_tx_prbs31_enable_3_int), + .phy_3_rx_prbs31_enable(qsfp2_rx_prbs31_enable_3_int), + + .phy_4_tx_clk(qsfp2_tx_clk_4_int), + .phy_4_tx_rst(qsfp2_tx_rst_4_int), + .phy_4_xgmii_txd(qsfp2_txd_4_int), + .phy_4_xgmii_txc(qsfp2_txc_4_int), + .phy_4_rx_clk(qsfp2_rx_clk_4_int), + .phy_4_rx_rst(qsfp2_rx_rst_4_int), + .phy_4_xgmii_rxd(qsfp2_rxd_4_int), + .phy_4_xgmii_rxc(qsfp2_rxc_4_int), + .phy_4_tx_bad_block(), + .phy_4_rx_error_count(qsfp2_rx_error_count_4_int), + .phy_4_rx_bad_block(), + .phy_4_rx_sequence_error(), + .phy_4_rx_block_lock(qsfp2_rx_block_lock_4), + .phy_4_rx_high_ber(), + .phy_4_tx_prbs31_enable(qsfp2_tx_prbs31_enable_4_int), + .phy_4_rx_prbs31_enable(qsfp2_rx_prbs31_enable_4_int) +); + +// QSFP3 +wire qsfp3_tx_clk_1_int; +wire qsfp3_tx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_1_int; +wire qsfp3_tx_prbs31_enable_1_int; +wire qsfp3_rx_clk_1_int; +wire qsfp3_rx_rst_1_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_1_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_1_int; +wire qsfp3_rx_prbs31_enable_1_int; +wire [6:0] qsfp3_rx_error_count_1_int; +wire qsfp3_tx_clk_2_int; +wire qsfp3_tx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_2_int; +wire qsfp3_tx_prbs31_enable_2_int; +wire qsfp3_rx_clk_2_int; +wire qsfp3_rx_rst_2_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_2_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_2_int; +wire qsfp3_rx_prbs31_enable_2_int; +wire [6:0] qsfp3_rx_error_count_2_int; +wire qsfp3_tx_clk_3_int; +wire qsfp3_tx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_3_int; +wire qsfp3_tx_prbs31_enable_3_int; +wire qsfp3_rx_clk_3_int; +wire qsfp3_rx_rst_3_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_3_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_3_int; +wire qsfp3_rx_prbs31_enable_3_int; +wire [6:0] qsfp3_rx_error_count_3_int; +wire qsfp3_tx_clk_4_int; +wire qsfp3_tx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_4_int; +wire qsfp3_tx_prbs31_enable_4_int; +wire qsfp3_rx_clk_4_int; +wire qsfp3_rx_rst_4_int; +wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_4_int; +wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_4_int; +wire qsfp3_rx_prbs31_enable_4_int; +wire [6:0] qsfp3_rx_error_count_4_int; + +wire qsfp3_drp_clk = clk_125mhz_int; +wire qsfp3_drp_rst = rst_125mhz_int; +wire [23:0] qsfp3_drp_addr; +wire [15:0] qsfp3_drp_di; +wire qsfp3_drp_en; +wire qsfp3_drp_we; +wire [15:0] qsfp3_drp_do; +wire qsfp3_drp_rdy; + +wire qsfp3_rx_block_lock_1; +wire qsfp3_rx_block_lock_2; +wire qsfp3_rx_block_lock_3; +wire qsfp3_rx_block_lock_4; + +wire qsfp3_gtpowergood; + +wire qsfp3_mgt_refclk_b0; +wire qsfp3_mgt_refclk_b0_int; +wire qsfp3_mgt_refclk_b0_bufg; + +IBUFDS_GTE4 ibufds_gte4_qsfp3_mgt_refclk_b0_inst ( + .I (qsfp3_mgt_refclk_b0_p), + .IB (qsfp3_mgt_refclk_b0_n), + .CEB (1'b0), + .O (qsfp3_mgt_refclk_b0), + .ODIV2 (qsfp3_mgt_refclk_b0_int) +); + +BUFG_GT bufg_gt_qsfp3_mgt_refclk_b0_inst ( + .CE (qsfp3_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp3_mgt_refclk_b0_int), + .O (qsfp3_mgt_refclk_b0_bufg) +); + +wire qsfp3_rst; + +sync_reset #( + .N(4) +) +qsfp3_sync_reset_inst ( + .clk(qsfp3_mgt_refclk_b0_bufg), + .rst(rst_125mhz_int), + .out(qsfp3_rst) +); + +eth_xcvr_phy_10g_gty_quad_wrapper #( + .PRBS31_ENABLE(1), + .TX_SERDES_PIPELINE(1), + .RX_SERDES_PIPELINE(1), + .COUNT_125US(125000/2.56) +) +qsfp3_phy_quad_inst ( + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(qsfp3_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(qsfp3_gtpowergood), + .xcvr_ref_clk(qsfp3_mgt_refclk_b0), + + /* + * DRP + */ + .drp_clk(qsfp3_drp_clk), + .drp_rst(qsfp3_drp_rst), + .drp_addr(qsfp3_drp_addr), + .drp_di(qsfp3_drp_di), + .drp_en(qsfp3_drp_en), + .drp_we(qsfp3_drp_we), + .drp_do(qsfp3_drp_do), + .drp_rdy(qsfp3_drp_rdy), + + /* + * Serial data + */ + .xcvr_txp({qsfp3_tx4_p, qsfp3_tx3_p, qsfp3_tx2_p, qsfp3_tx1_p}), + .xcvr_txn({qsfp3_tx4_n, qsfp3_tx3_n, qsfp3_tx2_n, qsfp3_tx1_n}), + .xcvr_rxp({qsfp3_rx4_p, qsfp3_rx3_p, qsfp3_rx2_p, qsfp3_rx1_p}), + .xcvr_rxn({qsfp3_rx4_n, qsfp3_rx3_n, qsfp3_rx2_n, qsfp3_rx1_n}), + + /* + * PHY connections + */ + .phy_1_tx_clk(qsfp3_tx_clk_1_int), + .phy_1_tx_rst(qsfp3_tx_rst_1_int), + .phy_1_xgmii_txd(qsfp3_txd_1_int), + .phy_1_xgmii_txc(qsfp3_txc_1_int), + .phy_1_rx_clk(qsfp3_rx_clk_1_int), + .phy_1_rx_rst(qsfp3_rx_rst_1_int), + .phy_1_xgmii_rxd(qsfp3_rxd_1_int), + .phy_1_xgmii_rxc(qsfp3_rxc_1_int), + .phy_1_tx_bad_block(), + .phy_1_rx_error_count(qsfp3_rx_error_count_1_int), + .phy_1_rx_bad_block(), + .phy_1_rx_sequence_error(), + .phy_1_rx_block_lock(qsfp3_rx_block_lock_1), + .phy_1_rx_high_ber(), + .phy_1_tx_prbs31_enable(qsfp3_tx_prbs31_enable_1_int), + .phy_1_rx_prbs31_enable(qsfp3_rx_prbs31_enable_1_int), + + .phy_2_tx_clk(qsfp3_tx_clk_2_int), + .phy_2_tx_rst(qsfp3_tx_rst_2_int), + .phy_2_xgmii_txd(qsfp3_txd_2_int), + .phy_2_xgmii_txc(qsfp3_txc_2_int), + .phy_2_rx_clk(qsfp3_rx_clk_2_int), + .phy_2_rx_rst(qsfp3_rx_rst_2_int), + .phy_2_xgmii_rxd(qsfp3_rxd_2_int), + .phy_2_xgmii_rxc(qsfp3_rxc_2_int), + .phy_2_tx_bad_block(), + .phy_2_rx_error_count(qsfp3_rx_error_count_2_int), + .phy_2_rx_bad_block(), + .phy_2_rx_sequence_error(), + .phy_2_rx_block_lock(qsfp3_rx_block_lock_2), + .phy_2_rx_high_ber(), + .phy_2_tx_prbs31_enable(qsfp3_tx_prbs31_enable_2_int), + .phy_2_rx_prbs31_enable(qsfp3_rx_prbs31_enable_2_int), + + .phy_3_tx_clk(qsfp3_tx_clk_3_int), + .phy_3_tx_rst(qsfp3_tx_rst_3_int), + .phy_3_xgmii_txd(qsfp3_txd_3_int), + .phy_3_xgmii_txc(qsfp3_txc_3_int), + .phy_3_rx_clk(qsfp3_rx_clk_3_int), + .phy_3_rx_rst(qsfp3_rx_rst_3_int), + .phy_3_xgmii_rxd(qsfp3_rxd_3_int), + .phy_3_xgmii_rxc(qsfp3_rxc_3_int), + .phy_3_tx_bad_block(), + .phy_3_rx_error_count(qsfp3_rx_error_count_3_int), + .phy_3_rx_bad_block(), + .phy_3_rx_sequence_error(), + .phy_3_rx_block_lock(qsfp3_rx_block_lock_3), + .phy_3_rx_high_ber(), + .phy_3_tx_prbs31_enable(qsfp3_tx_prbs31_enable_3_int), + .phy_3_rx_prbs31_enable(qsfp3_rx_prbs31_enable_3_int), + + .phy_4_tx_clk(qsfp3_tx_clk_4_int), + .phy_4_tx_rst(qsfp3_tx_rst_4_int), + .phy_4_xgmii_txd(qsfp3_txd_4_int), + .phy_4_xgmii_txc(qsfp3_txc_4_int), + .phy_4_rx_clk(qsfp3_rx_clk_4_int), + .phy_4_rx_rst(qsfp3_rx_rst_4_int), + .phy_4_xgmii_rxd(qsfp3_rxd_4_int), + .phy_4_xgmii_rxc(qsfp3_rxc_4_int), + .phy_4_tx_bad_block(), + .phy_4_rx_error_count(qsfp3_rx_error_count_4_int), + .phy_4_rx_bad_block(), + .phy_4_rx_sequence_error(), + .phy_4_rx_block_lock(qsfp3_rx_block_lock_4), + .phy_4_rx_high_ber(), + .phy_4_tx_prbs31_enable(qsfp3_tx_prbs31_enable_4_int), + .phy_4_rx_prbs31_enable(qsfp3_rx_prbs31_enable_4_int) +); + +fpga_core #( + // FW and board IDs + .FPGA_ID(FPGA_ID), + .FW_ID(FW_ID), + .FW_VER(FW_VER), + .BOARD_ID(BOARD_ID), + .BOARD_VER(BOARD_VER), + .BUILD_DATE(BUILD_DATE), + .GIT_HASH(GIT_HASH), + .RELEASE_INFO(RELEASE_INFO), + + // Structural configuration + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + .SCHED_PER_IF(SCHED_PER_IF), + .PORT_MASK(PORT_MASK), + + // PTP configuration + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .PTP_PERIOD_NS_WIDTH(PTP_PERIOD_NS_WIDTH), + .PTP_OFFSET_NS_WIDTH(PTP_OFFSET_NS_WIDTH), + .PTP_FNS_WIDTH(PTP_FNS_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_CLOCK_PIPELINE(PTP_CLOCK_PIPELINE), + .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_PORT_CDC_PIPELINE(PTP_PORT_CDC_PIPELINE), + .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), + .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), + + // Queue manager configuration (interface) + .EVENT_QUEUE_OP_TABLE_SIZE(EVENT_QUEUE_OP_TABLE_SIZE), + .TX_QUEUE_OP_TABLE_SIZE(TX_QUEUE_OP_TABLE_SIZE), + .RX_QUEUE_OP_TABLE_SIZE(RX_QUEUE_OP_TABLE_SIZE), + .TX_CPL_QUEUE_OP_TABLE_SIZE(TX_CPL_QUEUE_OP_TABLE_SIZE), + .RX_CPL_QUEUE_OP_TABLE_SIZE(RX_CPL_QUEUE_OP_TABLE_SIZE), + .EVENT_QUEUE_INDEX_WIDTH(EVENT_QUEUE_INDEX_WIDTH), + .TX_QUEUE_INDEX_WIDTH(TX_QUEUE_INDEX_WIDTH), + .RX_QUEUE_INDEX_WIDTH(RX_QUEUE_INDEX_WIDTH), + .TX_CPL_QUEUE_INDEX_WIDTH(TX_CPL_QUEUE_INDEX_WIDTH), + .RX_CPL_QUEUE_INDEX_WIDTH(RX_CPL_QUEUE_INDEX_WIDTH), + .EVENT_QUEUE_PIPELINE(EVENT_QUEUE_PIPELINE), + .TX_QUEUE_PIPELINE(TX_QUEUE_PIPELINE), + .RX_QUEUE_PIPELINE(RX_QUEUE_PIPELINE), + .TX_CPL_QUEUE_PIPELINE(TX_CPL_QUEUE_PIPELINE), + .RX_CPL_QUEUE_PIPELINE(RX_CPL_QUEUE_PIPELINE), + + // TX and RX engine configuration (port) + .TX_DESC_TABLE_SIZE(TX_DESC_TABLE_SIZE), + .RX_DESC_TABLE_SIZE(RX_DESC_TABLE_SIZE), + + // Scheduler configuration (port) + .TX_SCHEDULER_OP_TABLE_SIZE(TX_SCHEDULER_OP_TABLE_SIZE), + .TX_SCHEDULER_PIPELINE(TX_SCHEDULER_PIPELINE), + .TDMA_INDEX_WIDTH(TDMA_INDEX_WIDTH), + + // Timestamping configuration (port) + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TS_FIFO_DEPTH(TX_PTP_TS_FIFO_DEPTH), + .RX_PTP_TS_FIFO_DEPTH(RX_PTP_TS_FIFO_DEPTH), + + // Interface configuration (port) + .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), + .RX_RSS_ENABLE(RX_RSS_ENABLE), + .RX_HASH_ENABLE(RX_HASH_ENABLE), + .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .TX_FIFO_DEPTH(TX_FIFO_DEPTH), + .RX_FIFO_DEPTH(RX_FIFO_DEPTH), + .MAX_TX_SIZE(MAX_TX_SIZE), + .MAX_RX_SIZE(MAX_RX_SIZE), + .TX_RAM_SIZE(TX_RAM_SIZE), + .RX_RAM_SIZE(RX_RAM_SIZE), + + // Application block configuration + .APP_ENABLE(APP_ENABLE), + .APP_CTRL_ENABLE(APP_CTRL_ENABLE), + .APP_DMA_ENABLE(APP_DMA_ENABLE), + .APP_AXIS_DIRECT_ENABLE(APP_AXIS_DIRECT_ENABLE), + .APP_AXIS_SYNC_ENABLE(APP_AXIS_SYNC_ENABLE), + .APP_AXIS_IF_ENABLE(APP_AXIS_IF_ENABLE), + .APP_STAT_ENABLE(APP_STAT_ENABLE), + + // DMA interface configuration + .DMA_LEN_WIDTH(DMA_LEN_WIDTH), + .DMA_TAG_WIDTH(DMA_TAG_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), + .RAM_PIPELINE(RAM_PIPELINE), + + // PCIe interface configuration + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .PF_COUNT(PF_COUNT), + .VF_COUNT(VF_COUNT), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .PCIE_DMA_READ_OP_TABLE_SIZE(PCIE_DMA_READ_OP_TABLE_SIZE), + .PCIE_DMA_READ_TX_LIMIT(PCIE_DMA_READ_TX_LIMIT), + .PCIE_DMA_READ_TX_FC_ENABLE(PCIE_DMA_READ_TX_FC_ENABLE), + .PCIE_DMA_WRITE_OP_TABLE_SIZE(PCIE_DMA_WRITE_OP_TABLE_SIZE), + .PCIE_DMA_WRITE_TX_LIMIT(PCIE_DMA_WRITE_TX_LIMIT), + .PCIE_DMA_WRITE_TX_FC_ENABLE(PCIE_DMA_WRITE_TX_FC_ENABLE), + .MSI_COUNT(MSI_COUNT), + + // AXI lite interface configuration (control) + .AXIL_CTRL_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .AXIL_CTRL_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH), + + // AXI lite interface configuration (application control) + .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), + .AXIL_APP_CTRL_ADDR_WIDTH(AXIL_APP_CTRL_ADDR_WIDTH), + + // Ethernet interface configuration + .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .AXIS_ETH_SYNC_DATA_WIDTH(AXIS_ETH_SYNC_DATA_WIDTH), + .AXIS_ETH_TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .AXIS_ETH_RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .AXIS_ETH_TX_PIPELINE(AXIS_ETH_TX_PIPELINE), + .AXIS_ETH_TX_FIFO_PIPELINE(AXIS_ETH_TX_FIFO_PIPELINE), + .AXIS_ETH_TX_TS_PIPELINE(AXIS_ETH_TX_TS_PIPELINE), + .AXIS_ETH_RX_PIPELINE(AXIS_ETH_RX_PIPELINE), + .AXIS_ETH_RX_FIFO_PIPELINE(AXIS_ETH_RX_FIFO_PIPELINE), + + // Statistics counter subsystem + .STAT_ENABLE(STAT_ENABLE), + .STAT_DMA_ENABLE(STAT_DMA_ENABLE), + .STAT_PCIE_ENABLE(STAT_PCIE_ENABLE), + .STAT_INC_WIDTH(STAT_INC_WIDTH), + .STAT_ID_WIDTH(STAT_ID_WIDTH) +) +core_inst ( + /* + * Clock: 250 MHz + * Synchronous reset + */ + .clk_250mhz(pcie_user_clk), + .rst_250mhz(pcie_user_reset), + + /* + * GPIO + */ + .led(led), + + /* + * I2C + */ + .eeprom_i2c_scl_i(eeprom_i2c_scl_i), + .eeprom_i2c_scl_o(eeprom_i2c_scl_o), + .eeprom_i2c_scl_t(eeprom_i2c_scl_t), + .eeprom_i2c_sda_i(eeprom_i2c_sda_i), + .eeprom_i2c_sda_o(eeprom_i2c_sda_o), + .eeprom_i2c_sda_t(eeprom_i2c_sda_t), + + /* + * PCIe + */ + .m_axis_rq_tdata(axis_rq_tdata), + .m_axis_rq_tkeep(axis_rq_tkeep), + .m_axis_rq_tlast(axis_rq_tlast), + .m_axis_rq_tready(axis_rq_tready), + .m_axis_rq_tuser(axis_rq_tuser), + .m_axis_rq_tvalid(axis_rq_tvalid), + + .s_axis_rc_tdata(axis_rc_tdata), + .s_axis_rc_tkeep(axis_rc_tkeep), + .s_axis_rc_tlast(axis_rc_tlast), + .s_axis_rc_tready(axis_rc_tready), + .s_axis_rc_tuser(axis_rc_tuser), + .s_axis_rc_tvalid(axis_rc_tvalid), + + .s_axis_cq_tdata(axis_cq_tdata), + .s_axis_cq_tkeep(axis_cq_tkeep), + .s_axis_cq_tlast(axis_cq_tlast), + .s_axis_cq_tready(axis_cq_tready), + .s_axis_cq_tuser(axis_cq_tuser), + .s_axis_cq_tvalid(axis_cq_tvalid), + + .m_axis_cc_tdata(axis_cc_tdata), + .m_axis_cc_tkeep(axis_cc_tkeep), + .m_axis_cc_tlast(axis_cc_tlast), + .m_axis_cc_tready(axis_cc_tready), + .m_axis_cc_tuser(axis_cc_tuser), + .m_axis_cc_tvalid(axis_cc_tvalid), + + .s_axis_rq_seq_num_0(pcie_rq_seq_num0), + .s_axis_rq_seq_num_valid_0(pcie_rq_seq_num_vld0), + .s_axis_rq_seq_num_1(pcie_rq_seq_num1), + .s_axis_rq_seq_num_valid_1(pcie_rq_seq_num_vld1), + + .pcie_tfc_nph_av(pcie_tfc_nph_av), + .pcie_tfc_npd_av(pcie_tfc_npd_av), + + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor), + + /* + * Ethernet: QSFP28 + */ + .qsfp0_tx_clk_1(qsfp0_tx_clk_1_int), + .qsfp0_tx_rst_1(qsfp0_tx_rst_1_int), + .qsfp0_txd_1(qsfp0_txd_1_int), + .qsfp0_txc_1(qsfp0_txc_1_int), + .qsfp0_tx_prbs31_enable_1(qsfp0_tx_prbs31_enable_1_int), + .qsfp0_rx_clk_1(qsfp0_rx_clk_1_int), + .qsfp0_rx_rst_1(qsfp0_rx_rst_1_int), + .qsfp0_rxd_1(qsfp0_rxd_1_int), + .qsfp0_rxc_1(qsfp0_rxc_1_int), + .qsfp0_rx_prbs31_enable_1(qsfp0_rx_prbs31_enable_1_int), + .qsfp0_rx_error_count_1(qsfp0_rx_error_count_1_int), + .qsfp0_tx_clk_2(qsfp0_tx_clk_2_int), + .qsfp0_tx_rst_2(qsfp0_tx_rst_2_int), + .qsfp0_txd_2(qsfp0_txd_2_int), + .qsfp0_txc_2(qsfp0_txc_2_int), + .qsfp0_tx_prbs31_enable_2(qsfp0_tx_prbs31_enable_2_int), + .qsfp0_rx_clk_2(qsfp0_rx_clk_2_int), + .qsfp0_rx_rst_2(qsfp0_rx_rst_2_int), + .qsfp0_rxd_2(qsfp0_rxd_2_int), + .qsfp0_rxc_2(qsfp0_rxc_2_int), + .qsfp0_rx_prbs31_enable_2(qsfp0_rx_prbs31_enable_2_int), + .qsfp0_rx_error_count_2(qsfp0_rx_error_count_2_int), + .qsfp0_tx_clk_3(qsfp0_tx_clk_3_int), + .qsfp0_tx_rst_3(qsfp0_tx_rst_3_int), + .qsfp0_txd_3(qsfp0_txd_3_int), + .qsfp0_txc_3(qsfp0_txc_3_int), + .qsfp0_tx_prbs31_enable_3(qsfp0_tx_prbs31_enable_3_int), + .qsfp0_rx_clk_3(qsfp0_rx_clk_3_int), + .qsfp0_rx_rst_3(qsfp0_rx_rst_3_int), + .qsfp0_rxd_3(qsfp0_rxd_3_int), + .qsfp0_rxc_3(qsfp0_rxc_3_int), + .qsfp0_rx_prbs31_enable_3(qsfp0_rx_prbs31_enable_3_int), + .qsfp0_rx_error_count_3(qsfp0_rx_error_count_3_int), + .qsfp0_tx_clk_4(qsfp0_tx_clk_4_int), + .qsfp0_tx_rst_4(qsfp0_tx_rst_4_int), + .qsfp0_txd_4(qsfp0_txd_4_int), + .qsfp0_txc_4(qsfp0_txc_4_int), + .qsfp0_tx_prbs31_enable_4(qsfp0_tx_prbs31_enable_4_int), + .qsfp0_rx_clk_4(qsfp0_rx_clk_4_int), + .qsfp0_rx_rst_4(qsfp0_rx_rst_4_int), + .qsfp0_rxd_4(qsfp0_rxd_4_int), + .qsfp0_rxc_4(qsfp0_rxc_4_int), + .qsfp0_rx_prbs31_enable_4(qsfp0_rx_prbs31_enable_4_int), + .qsfp0_rx_error_count_4(qsfp0_rx_error_count_4_int), + + .qsfp0_drp_clk(qsfp0_drp_clk), + .qsfp0_drp_rst(qsfp0_drp_rst), + .qsfp0_drp_addr(qsfp0_drp_addr), + .qsfp0_drp_di(qsfp0_drp_di), + .qsfp0_drp_en(qsfp0_drp_en), + .qsfp0_drp_we(qsfp0_drp_we), + .qsfp0_drp_do(qsfp0_drp_do), + .qsfp0_drp_rdy(qsfp0_drp_rdy), + + .qsfp0_modprsl(qsfp0_modprsl_int), + .qsfp0_resetl(qsfp0_resetl), + .qsfp0_intl(qsfp0_intl_int), + .qsfp0_lpmode(qsfp0_lpmode), + + .qsfp0_i2c_scl_i(qsfp0_i2c_scl_i), + .qsfp0_i2c_scl_o(qsfp0_i2c_scl_o), + .qsfp0_i2c_scl_t(qsfp0_i2c_scl_t), + .qsfp0_i2c_sda_i(qsfp0_i2c_sda_i), + .qsfp0_i2c_sda_o(qsfp0_i2c_sda_o), + .qsfp0_i2c_sda_t(qsfp0_i2c_sda_t), + + .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), + .qsfp1_txd_1(qsfp1_txd_1_int), + .qsfp1_txc_1(qsfp1_txc_1_int), + .qsfp1_tx_prbs31_enable_1(qsfp1_tx_prbs31_enable_1_int), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), + .qsfp1_rxd_1(qsfp1_rxd_1_int), + .qsfp1_rxc_1(qsfp1_rxc_1_int), + .qsfp1_rx_prbs31_enable_1(qsfp1_rx_prbs31_enable_1_int), + .qsfp1_rx_error_count_1(qsfp1_rx_error_count_1_int), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), + .qsfp1_txd_2(qsfp1_txd_2_int), + .qsfp1_txc_2(qsfp1_txc_2_int), + .qsfp1_tx_prbs31_enable_2(qsfp1_tx_prbs31_enable_2_int), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), + .qsfp1_rxd_2(qsfp1_rxd_2_int), + .qsfp1_rxc_2(qsfp1_rxc_2_int), + .qsfp1_rx_prbs31_enable_2(qsfp1_rx_prbs31_enable_2_int), + .qsfp1_rx_error_count_2(qsfp1_rx_error_count_2_int), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), + .qsfp1_txd_3(qsfp1_txd_3_int), + .qsfp1_txc_3(qsfp1_txc_3_int), + .qsfp1_tx_prbs31_enable_3(qsfp1_tx_prbs31_enable_3_int), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), + .qsfp1_rxd_3(qsfp1_rxd_3_int), + .qsfp1_rxc_3(qsfp1_rxc_3_int), + .qsfp1_rx_prbs31_enable_3(qsfp1_rx_prbs31_enable_3_int), + .qsfp1_rx_error_count_3(qsfp1_rx_error_count_3_int), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), + .qsfp1_txd_4(qsfp1_txd_4_int), + .qsfp1_txc_4(qsfp1_txc_4_int), + .qsfp1_tx_prbs31_enable_4(qsfp1_tx_prbs31_enable_4_int), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), + .qsfp1_rxd_4(qsfp1_rxd_4_int), + .qsfp1_rxc_4(qsfp1_rxc_4_int), + .qsfp1_rx_prbs31_enable_4(qsfp1_rx_prbs31_enable_4_int), + .qsfp1_rx_error_count_4(qsfp1_rx_error_count_4_int), + + .qsfp1_drp_clk(qsfp1_drp_clk), + .qsfp1_drp_rst(qsfp1_drp_rst), + .qsfp1_drp_addr(qsfp1_drp_addr), + .qsfp1_drp_di(qsfp1_drp_di), + .qsfp1_drp_en(qsfp1_drp_en), + .qsfp1_drp_we(qsfp1_drp_we), + .qsfp1_drp_do(qsfp1_drp_do), + .qsfp1_drp_rdy(qsfp1_drp_rdy), + + .qsfp1_modprsl(qsfp1_modprsl_int), + .qsfp1_resetl(qsfp1_resetl), + .qsfp1_intl(qsfp1_intl_int), + .qsfp1_lpmode(qsfp1_lpmode), + + .qsfp1_i2c_scl_i(qsfp1_i2c_scl_i), + .qsfp1_i2c_scl_o(qsfp1_i2c_scl_o), + .qsfp1_i2c_scl_t(qsfp1_i2c_scl_t), + .qsfp1_i2c_sda_i(qsfp1_i2c_sda_i), + .qsfp1_i2c_sda_o(qsfp1_i2c_sda_o), + .qsfp1_i2c_sda_t(qsfp1_i2c_sda_t), + + .qsfp2_tx_clk_1(qsfp2_tx_clk_1_int), + .qsfp2_tx_rst_1(qsfp2_tx_rst_1_int), + .qsfp2_txd_1(qsfp2_txd_1_int), + .qsfp2_txc_1(qsfp2_txc_1_int), + .qsfp2_tx_prbs31_enable_1(qsfp2_tx_prbs31_enable_1_int), + .qsfp2_rx_clk_1(qsfp2_rx_clk_1_int), + .qsfp2_rx_rst_1(qsfp2_rx_rst_1_int), + .qsfp2_rxd_1(qsfp2_rxd_1_int), + .qsfp2_rxc_1(qsfp2_rxc_1_int), + .qsfp2_rx_prbs31_enable_1(qsfp2_rx_prbs31_enable_1_int), + .qsfp2_rx_error_count_1(qsfp2_rx_error_count_1_int), + .qsfp2_tx_clk_2(qsfp2_tx_clk_2_int), + .qsfp2_tx_rst_2(qsfp2_tx_rst_2_int), + .qsfp2_txd_2(qsfp2_txd_2_int), + .qsfp2_txc_2(qsfp2_txc_2_int), + .qsfp2_tx_prbs31_enable_2(qsfp2_tx_prbs31_enable_2_int), + .qsfp2_rx_clk_2(qsfp2_rx_clk_2_int), + .qsfp2_rx_rst_2(qsfp2_rx_rst_2_int), + .qsfp2_rxd_2(qsfp2_rxd_2_int), + .qsfp2_rxc_2(qsfp2_rxc_2_int), + .qsfp2_rx_prbs31_enable_2(qsfp2_rx_prbs31_enable_2_int), + .qsfp2_rx_error_count_2(qsfp2_rx_error_count_2_int), + .qsfp2_tx_clk_3(qsfp2_tx_clk_3_int), + .qsfp2_tx_rst_3(qsfp2_tx_rst_3_int), + .qsfp2_txd_3(qsfp2_txd_3_int), + .qsfp2_txc_3(qsfp2_txc_3_int), + .qsfp2_tx_prbs31_enable_3(qsfp2_tx_prbs31_enable_3_int), + .qsfp2_rx_clk_3(qsfp2_rx_clk_3_int), + .qsfp2_rx_rst_3(qsfp2_rx_rst_3_int), + .qsfp2_rxd_3(qsfp2_rxd_3_int), + .qsfp2_rxc_3(qsfp2_rxc_3_int), + .qsfp2_rx_prbs31_enable_3(qsfp2_rx_prbs31_enable_3_int), + .qsfp2_rx_error_count_3(qsfp2_rx_error_count_3_int), + .qsfp2_tx_clk_4(qsfp2_tx_clk_4_int), + .qsfp2_tx_rst_4(qsfp2_tx_rst_4_int), + .qsfp2_txd_4(qsfp2_txd_4_int), + .qsfp2_txc_4(qsfp2_txc_4_int), + .qsfp2_tx_prbs31_enable_4(qsfp2_tx_prbs31_enable_4_int), + .qsfp2_rx_clk_4(qsfp2_rx_clk_4_int), + .qsfp2_rx_rst_4(qsfp2_rx_rst_4_int), + .qsfp2_rxd_4(qsfp2_rxd_4_int), + .qsfp2_rxc_4(qsfp2_rxc_4_int), + .qsfp2_rx_prbs31_enable_4(qsfp2_rx_prbs31_enable_4_int), + .qsfp2_rx_error_count_4(qsfp2_rx_error_count_4_int), + + .qsfp2_drp_clk(qsfp2_drp_clk), + .qsfp2_drp_rst(qsfp2_drp_rst), + .qsfp2_drp_addr(qsfp2_drp_addr), + .qsfp2_drp_di(qsfp2_drp_di), + .qsfp2_drp_en(qsfp2_drp_en), + .qsfp2_drp_we(qsfp2_drp_we), + .qsfp2_drp_do(qsfp2_drp_do), + .qsfp2_drp_rdy(qsfp2_drp_rdy), + + .qsfp2_modprsl(qsfp2_modprsl_int), + .qsfp2_resetl(qsfp2_resetl), + .qsfp2_intl(qsfp2_intl_int), + .qsfp2_lpmode(qsfp2_lpmode), + + .qsfp2_i2c_scl_i(qsfp2_i2c_scl_i), + .qsfp2_i2c_scl_o(qsfp2_i2c_scl_o), + .qsfp2_i2c_scl_t(qsfp2_i2c_scl_t), + .qsfp2_i2c_sda_i(qsfp2_i2c_sda_i), + .qsfp2_i2c_sda_o(qsfp2_i2c_sda_o), + .qsfp2_i2c_sda_t(qsfp2_i2c_sda_t), + + .qsfp3_tx_clk_1(qsfp3_tx_clk_1_int), + .qsfp3_tx_rst_1(qsfp3_tx_rst_1_int), + .qsfp3_txd_1(qsfp3_txd_1_int), + .qsfp3_txc_1(qsfp3_txc_1_int), + .qsfp3_tx_prbs31_enable_1(qsfp3_tx_prbs31_enable_1_int), + .qsfp3_rx_clk_1(qsfp3_rx_clk_1_int), + .qsfp3_rx_rst_1(qsfp3_rx_rst_1_int), + .qsfp3_rxd_1(qsfp3_rxd_1_int), + .qsfp3_rxc_1(qsfp3_rxc_1_int), + .qsfp3_rx_prbs31_enable_1(qsfp3_rx_prbs31_enable_1_int), + .qsfp3_rx_error_count_1(qsfp3_rx_error_count_1_int), + .qsfp3_tx_clk_2(qsfp3_tx_clk_2_int), + .qsfp3_tx_rst_2(qsfp3_tx_rst_2_int), + .qsfp3_txd_2(qsfp3_txd_2_int), + .qsfp3_txc_2(qsfp3_txc_2_int), + .qsfp3_tx_prbs31_enable_2(qsfp3_tx_prbs31_enable_2_int), + .qsfp3_rx_clk_2(qsfp3_rx_clk_2_int), + .qsfp3_rx_rst_2(qsfp3_rx_rst_2_int), + .qsfp3_rxd_2(qsfp3_rxd_2_int), + .qsfp3_rxc_2(qsfp3_rxc_2_int), + .qsfp3_rx_prbs31_enable_2(qsfp3_rx_prbs31_enable_2_int), + .qsfp3_rx_error_count_2(qsfp3_rx_error_count_2_int), + .qsfp3_tx_clk_3(qsfp3_tx_clk_3_int), + .qsfp3_tx_rst_3(qsfp3_tx_rst_3_int), + .qsfp3_txd_3(qsfp3_txd_3_int), + .qsfp3_txc_3(qsfp3_txc_3_int), + .qsfp3_tx_prbs31_enable_3(qsfp3_tx_prbs31_enable_3_int), + .qsfp3_rx_clk_3(qsfp3_rx_clk_3_int), + .qsfp3_rx_rst_3(qsfp3_rx_rst_3_int), + .qsfp3_rxd_3(qsfp3_rxd_3_int), + .qsfp3_rxc_3(qsfp3_rxc_3_int), + .qsfp3_rx_prbs31_enable_3(qsfp3_rx_prbs31_enable_3_int), + .qsfp3_rx_error_count_3(qsfp3_rx_error_count_3_int), + .qsfp3_tx_clk_4(qsfp3_tx_clk_4_int), + .qsfp3_tx_rst_4(qsfp3_tx_rst_4_int), + .qsfp3_txd_4(qsfp3_txd_4_int), + .qsfp3_txc_4(qsfp3_txc_4_int), + .qsfp3_tx_prbs31_enable_4(qsfp3_tx_prbs31_enable_4_int), + .qsfp3_rx_clk_4(qsfp3_rx_clk_4_int), + .qsfp3_rx_rst_4(qsfp3_rx_rst_4_int), + .qsfp3_rxd_4(qsfp3_rxd_4_int), + .qsfp3_rxc_4(qsfp3_rxc_4_int), + .qsfp3_rx_prbs31_enable_4(qsfp3_rx_prbs31_enable_4_int), + .qsfp3_rx_error_count_4(qsfp3_rx_error_count_4_int), + + .qsfp3_drp_clk(qsfp3_drp_clk), + .qsfp3_drp_rst(qsfp3_drp_rst), + .qsfp3_drp_addr(qsfp3_drp_addr), + .qsfp3_drp_di(qsfp3_drp_di), + .qsfp3_drp_en(qsfp3_drp_en), + .qsfp3_drp_we(qsfp3_drp_we), + .qsfp3_drp_do(qsfp3_drp_do), + .qsfp3_drp_rdy(qsfp3_drp_rdy), + + .qsfp3_modprsl(qsfp3_modprsl_int), + .qsfp3_resetl(qsfp3_resetl), + .qsfp3_intl(qsfp3_intl_int), + .qsfp3_lpmode(qsfp3_lpmode), + + .qsfp3_i2c_scl_i(qsfp3_i2c_scl_i), + .qsfp3_i2c_scl_o(qsfp3_i2c_scl_o), + .qsfp3_i2c_scl_t(qsfp3_i2c_scl_t), + .qsfp3_i2c_sda_i(qsfp3_i2c_sda_i), + .qsfp3_i2c_sda_o(qsfp3_i2c_sda_o), + .qsfp3_i2c_sda_t(qsfp3_i2c_sda_t), + + /* + * QSPI flash + */ + .fpga_boot(fpga_boot), + .qspi_clk(qspi_clk_int), + .qspi_dq_i(qspi_dq_i_int), + .qspi_dq_o(qspi_dq_o_int), + .qspi_dq_oe(qspi_dq_oe_int), + .qspi_cs(qspi_cs_int) +); + +endmodule + +`resetall diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v new file mode 100644 index 000000000..04f847603 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v @@ -0,0 +1,1732 @@ +/* + +Copyright 2019-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. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + // FW and board IDs + parameter FPGA_ID = 32'h4B31093, + parameter FW_ID = 32'h00000000, + parameter FW_VER = 32'h00_00_01_00, + parameter BOARD_ID = 32'h12ba_9823, + parameter BOARD_VER = 32'h01_00_00_00, + parameter BUILD_DATE = 32'd602976000, + parameter GIT_HASH = 32'hdce357bf, + parameter RELEASE_INFO = 32'h00000000, + + // Structural configuration + parameter IF_COUNT = 2, + parameter PORTS_PER_IF = 1, + parameter SCHED_PER_IF = PORTS_PER_IF, + parameter PORT_MASK = 0, + + // PTP configuration + parameter PTP_TS_WIDTH = 96, + parameter PTP_TAG_WIDTH = 16, + parameter PTP_PERIOD_NS_WIDTH = 4, + parameter PTP_OFFSET_NS_WIDTH = 32, + parameter PTP_FNS_WIDTH = 32, + parameter PTP_PERIOD_NS = 4'd4, + parameter PTP_PERIOD_FNS = 32'd0, + parameter PTP_CLOCK_PIPELINE = 0, + parameter PTP_USE_SAMPLE_CLOCK = 0, + parameter PTP_PORT_CDC_PIPELINE = 0, + parameter PTP_PEROUT_ENABLE = 0, + parameter PTP_PEROUT_COUNT = 1, + parameter IF_PTP_PERIOD_NS = 6'h6, + parameter IF_PTP_PERIOD_FNS = 16'h6666, + + // Queue manager configuration (interface) + parameter EVENT_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_QUEUE_OP_TABLE_SIZE = 32, + parameter RX_QUEUE_OP_TABLE_SIZE = 32, + parameter TX_CPL_QUEUE_OP_TABLE_SIZE = TX_QUEUE_OP_TABLE_SIZE, + parameter RX_CPL_QUEUE_OP_TABLE_SIZE = RX_QUEUE_OP_TABLE_SIZE, + parameter EVENT_QUEUE_INDEX_WIDTH = 5, + parameter TX_QUEUE_INDEX_WIDTH = 13, + parameter RX_QUEUE_INDEX_WIDTH = 8, + parameter TX_CPL_QUEUE_INDEX_WIDTH = TX_QUEUE_INDEX_WIDTH, + parameter RX_CPL_QUEUE_INDEX_WIDTH = RX_QUEUE_INDEX_WIDTH, + parameter EVENT_QUEUE_PIPELINE = 3, + parameter TX_QUEUE_PIPELINE = 3+(TX_QUEUE_INDEX_WIDTH > 12 ? TX_QUEUE_INDEX_WIDTH-12 : 0), + parameter RX_QUEUE_PIPELINE = 3+(RX_QUEUE_INDEX_WIDTH > 12 ? RX_QUEUE_INDEX_WIDTH-12 : 0), + parameter TX_CPL_QUEUE_PIPELINE = TX_QUEUE_PIPELINE, + parameter RX_CPL_QUEUE_PIPELINE = RX_QUEUE_PIPELINE, + + // TX and RX engine configuration (port) + parameter TX_DESC_TABLE_SIZE = 32, + parameter RX_DESC_TABLE_SIZE = 32, + + // Scheduler configuration (port) + parameter TX_SCHEDULER_OP_TABLE_SIZE = TX_DESC_TABLE_SIZE, + parameter TX_SCHEDULER_PIPELINE = TX_QUEUE_PIPELINE, + parameter TDMA_INDEX_WIDTH = 6, + + // Timestamping configuration (port) + parameter PTP_TS_ENABLE = 1, + parameter TX_PTP_TS_FIFO_DEPTH = 32, + parameter RX_PTP_TS_FIFO_DEPTH = 32, + + // Interface configuration (port) + parameter TX_CHECKSUM_ENABLE = 1, + parameter RX_RSS_ENABLE = 1, + parameter RX_HASH_ENABLE = 1, + parameter RX_CHECKSUM_ENABLE = 1, + parameter ENABLE_PADDING = 1, + parameter ENABLE_DIC = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_DEPTH = 32768, + parameter RX_FIFO_DEPTH = 32768, + parameter MAX_TX_SIZE = 9214, + parameter MAX_RX_SIZE = 9214, + parameter TX_RAM_SIZE = 32768, + parameter RX_RAM_SIZE = 32768, + + // Application block configuration + parameter APP_ENABLE = 0, + parameter APP_CTRL_ENABLE = 1, + parameter APP_DMA_ENABLE = 1, + parameter APP_AXIS_DIRECT_ENABLE = 1, + parameter APP_AXIS_SYNC_ENABLE = 1, + parameter APP_AXIS_IF_ENABLE = 1, + parameter APP_STAT_ENABLE = 1, + + // DMA interface configuration + parameter DMA_LEN_WIDTH = 16, + parameter DMA_TAG_WIDTH = 16, + parameter RAM_ADDR_WIDTH = $clog2(TX_RAM_SIZE > RX_RAM_SIZE ? TX_RAM_SIZE : RX_RAM_SIZE), + parameter RAM_PIPELINE = 2, + + // PCIe interface configuration + parameter AXIS_PCIE_DATA_WIDTH = 512, + parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32), + parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161, + parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 62 : 137, + parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183, + parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81, + parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6, + parameter PF_COUNT = 1, + parameter VF_COUNT = 0, + parameter PCIE_TAG_COUNT = 64, + parameter PCIE_DMA_READ_OP_TABLE_SIZE = PCIE_TAG_COUNT, + parameter PCIE_DMA_READ_TX_LIMIT = 16, + parameter PCIE_DMA_READ_TX_FC_ENABLE = 1, + parameter PCIE_DMA_WRITE_OP_TABLE_SIZE = 16, + parameter PCIE_DMA_WRITE_TX_LIMIT = 3, + parameter PCIE_DMA_WRITE_TX_FC_ENABLE = 1, + parameter MSI_COUNT = 32, + + // AXI lite interface configuration (control) + parameter AXIL_CTRL_DATA_WIDTH = 32, + parameter AXIL_CTRL_ADDR_WIDTH = 24, + + // AXI lite interface configuration (application control) + parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH, + parameter AXIL_APP_CTRL_ADDR_WIDTH = 24, + + // Ethernet interface configuration + parameter XGMII_DATA_WIDTH = 64, + parameter XGMII_CTRL_WIDTH = XGMII_DATA_WIDTH/8, + parameter AXIS_ETH_DATA_WIDTH = XGMII_DATA_WIDTH, + parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8, + parameter AXIS_ETH_SYNC_DATA_WIDTH = AXIS_ETH_DATA_WIDTH, + parameter AXIS_ETH_TX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TAG_WIDTH : 0) + 1, + parameter AXIS_ETH_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, + parameter AXIS_ETH_TX_PIPELINE = 4, + parameter AXIS_ETH_TX_FIFO_PIPELINE = 4, + parameter AXIS_ETH_TX_TS_PIPELINE = 4, + parameter AXIS_ETH_RX_PIPELINE = 4, + parameter AXIS_ETH_RX_FIFO_PIPELINE = 4, + + // Statistics counter subsystem + parameter STAT_ENABLE = 1, + parameter STAT_DMA_ENABLE = 1, + parameter STAT_PCIE_ENABLE = 1, + parameter STAT_INC_WIDTH = 24, + parameter STAT_ID_WIDTH = 12 +) +( + /* + * Clock: 250 MHz + * Synchronous reset + */ + input wire clk_250mhz, + input wire rst_250mhz, + + /* + * GPIO + */ + input wire [3:0] sw, + output wire [3:0] led, + + /* + * I2C + */ + input wire eeprom_i2c_scl_i, + output wire eeprom_i2c_scl_o, + output wire eeprom_i2c_scl_t, + input wire eeprom_i2c_sda_i, + output wire eeprom_i2c_sda_o, + output wire eeprom_i2c_sda_t, + + /* + * PCIe + */ + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep, + output wire m_axis_rq_tlast, + input wire m_axis_rq_tready, + output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser, + output wire m_axis_rq_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep, + input wire s_axis_rc_tlast, + output wire s_axis_rc_tready, + input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser, + input wire s_axis_rc_tvalid, + + input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata, + input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep, + input wire s_axis_cq_tlast, + output wire s_axis_cq_tready, + input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser, + input wire s_axis_cq_tvalid, + + output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata, + output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep, + output wire m_axis_cc_tlast, + input wire m_axis_cc_tready, + output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser, + output wire m_axis_cc_tvalid, + + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0, + input wire s_axis_rq_seq_num_valid_0, + input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1, + input wire s_axis_rq_seq_num_valid_1, + + input wire [1:0] pcie_tfc_nph_av, + input wire [1:0] pcie_tfc_npd_av, + + input wire [2:0] cfg_max_payload, + input wire [2:0] cfg_max_read_req, + + output wire [9:0] cfg_mgmt_addr, + output wire [7:0] cfg_mgmt_function_number, + output wire cfg_mgmt_write, + output wire [31:0] cfg_mgmt_write_data, + output wire [3:0] cfg_mgmt_byte_enable, + output wire cfg_mgmt_read, + input wire [31:0] cfg_mgmt_read_data, + input wire cfg_mgmt_read_write_done, + + input wire [7:0] cfg_fc_ph, + input wire [11:0] cfg_fc_pd, + input wire [7:0] cfg_fc_nph, + input wire [11:0] cfg_fc_npd, + input wire [7:0] cfg_fc_cplh, + input wire [11:0] cfg_fc_cpld, + output wire [2:0] cfg_fc_sel, + + input wire [3:0] cfg_interrupt_msi_enable, + input wire [11:0] cfg_interrupt_msi_mmenable, + input wire cfg_interrupt_msi_mask_update, + input wire [31:0] cfg_interrupt_msi_data, + output wire [3:0] cfg_interrupt_msi_select, + output wire [31:0] cfg_interrupt_msi_int, + output wire [31:0] cfg_interrupt_msi_pending_status, + output wire cfg_interrupt_msi_pending_status_data_enable, + output wire [3:0] cfg_interrupt_msi_pending_status_function_num, + input wire cfg_interrupt_msi_sent, + input wire cfg_interrupt_msi_fail, + output wire [2:0] cfg_interrupt_msi_attr, + output wire cfg_interrupt_msi_tph_present, + output wire [1:0] cfg_interrupt_msi_tph_type, + output wire [8:0] cfg_interrupt_msi_tph_st_tag, + output wire [3:0] cfg_interrupt_msi_function_number, + + output wire status_error_cor, + output wire status_error_uncor, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp0_tx_clk_1, + input wire qsfp0_tx_rst_1, + output wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_1, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_1, + output wire qsfp0_tx_prbs31_enable_1, + input wire qsfp0_rx_clk_1, + input wire qsfp0_rx_rst_1, + input wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_1, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_1, + output wire qsfp0_rx_prbs31_enable_1, + input wire [6:0] qsfp0_rx_error_count_1, + input wire qsfp0_tx_clk_2, + input wire qsfp0_tx_rst_2, + output wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_2, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_2, + output wire qsfp0_tx_prbs31_enable_2, + input wire qsfp0_rx_clk_2, + input wire qsfp0_rx_rst_2, + input wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_2, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_2, + output wire qsfp0_rx_prbs31_enable_2, + input wire [6:0] qsfp0_rx_error_count_2, + input wire qsfp0_tx_clk_3, + input wire qsfp0_tx_rst_3, + output wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_3, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_3, + output wire qsfp0_tx_prbs31_enable_3, + input wire qsfp0_rx_clk_3, + input wire qsfp0_rx_rst_3, + input wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_3, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_3, + output wire qsfp0_rx_prbs31_enable_3, + input wire [6:0] qsfp0_rx_error_count_3, + input wire qsfp0_tx_clk_4, + input wire qsfp0_tx_rst_4, + output wire [XGMII_DATA_WIDTH-1:0] qsfp0_txd_4, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp0_txc_4, + output wire qsfp0_tx_prbs31_enable_4, + input wire qsfp0_rx_clk_4, + input wire qsfp0_rx_rst_4, + input wire [XGMII_DATA_WIDTH-1:0] qsfp0_rxd_4, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp0_rxc_4, + output wire qsfp0_rx_prbs31_enable_4, + input wire [6:0] qsfp0_rx_error_count_4, + + input wire qsfp0_drp_clk, + input wire qsfp0_drp_rst, + output wire [23:0] qsfp0_drp_addr, + output wire [15:0] qsfp0_drp_di, + output wire qsfp0_drp_en, + output wire qsfp0_drp_we, + input wire [15:0] qsfp0_drp_do, + input wire qsfp0_drp_rdy, + + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + + input wire qsfp0_i2c_scl_i, + output wire qsfp0_i2c_scl_o, + output wire qsfp0_i2c_scl_t, + input wire qsfp0_i2c_sda_i, + output wire qsfp0_i2c_sda_o, + output wire qsfp0_i2c_sda_t, + + input wire qsfp1_tx_clk_1, + input wire qsfp1_tx_rst_1, + output wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_1, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_1, + output wire qsfp1_tx_prbs31_enable_1, + input wire qsfp1_rx_clk_1, + input wire qsfp1_rx_rst_1, + input wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_1, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_1, + output wire qsfp1_rx_prbs31_enable_1, + input wire [6:0] qsfp1_rx_error_count_1, + input wire qsfp1_tx_clk_2, + input wire qsfp1_tx_rst_2, + output wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_2, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_2, + output wire qsfp1_tx_prbs31_enable_2, + input wire qsfp1_rx_clk_2, + input wire qsfp1_rx_rst_2, + input wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_2, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_2, + output wire qsfp1_rx_prbs31_enable_2, + input wire [6:0] qsfp1_rx_error_count_2, + input wire qsfp1_tx_clk_3, + input wire qsfp1_tx_rst_3, + output wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_3, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_3, + output wire qsfp1_tx_prbs31_enable_3, + input wire qsfp1_rx_clk_3, + input wire qsfp1_rx_rst_3, + input wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_3, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_3, + output wire qsfp1_rx_prbs31_enable_3, + input wire [6:0] qsfp1_rx_error_count_3, + input wire qsfp1_tx_clk_4, + input wire qsfp1_tx_rst_4, + output wire [XGMII_DATA_WIDTH-1:0] qsfp1_txd_4, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp1_txc_4, + output wire qsfp1_tx_prbs31_enable_4, + input wire qsfp1_rx_clk_4, + input wire qsfp1_rx_rst_4, + input wire [XGMII_DATA_WIDTH-1:0] qsfp1_rxd_4, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp1_rxc_4, + output wire qsfp1_rx_prbs31_enable_4, + input wire [6:0] qsfp1_rx_error_count_4, + + input wire qsfp1_drp_clk, + input wire qsfp1_drp_rst, + output wire [23:0] qsfp1_drp_addr, + output wire [15:0] qsfp1_drp_di, + output wire qsfp1_drp_en, + output wire qsfp1_drp_we, + input wire [15:0] qsfp1_drp_do, + input wire qsfp1_drp_rdy, + + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + + input wire qsfp1_i2c_scl_i, + output wire qsfp1_i2c_scl_o, + output wire qsfp1_i2c_scl_t, + input wire qsfp1_i2c_sda_i, + output wire qsfp1_i2c_sda_o, + output wire qsfp1_i2c_sda_t, + + input wire qsfp2_tx_clk_1, + input wire qsfp2_tx_rst_1, + output wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_1, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_1, + output wire qsfp2_tx_prbs31_enable_1, + input wire qsfp2_rx_clk_1, + input wire qsfp2_rx_rst_1, + input wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_1, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_1, + output wire qsfp2_rx_prbs31_enable_1, + input wire [6:0] qsfp2_rx_error_count_1, + input wire qsfp2_tx_clk_2, + input wire qsfp2_tx_rst_2, + output wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_2, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_2, + output wire qsfp2_tx_prbs31_enable_2, + input wire qsfp2_rx_clk_2, + input wire qsfp2_rx_rst_2, + input wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_2, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_2, + output wire qsfp2_rx_prbs31_enable_2, + input wire [6:0] qsfp2_rx_error_count_2, + input wire qsfp2_tx_clk_3, + input wire qsfp2_tx_rst_3, + output wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_3, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_3, + output wire qsfp2_tx_prbs31_enable_3, + input wire qsfp2_rx_clk_3, + input wire qsfp2_rx_rst_3, + input wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_3, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_3, + output wire qsfp2_rx_prbs31_enable_3, + input wire [6:0] qsfp2_rx_error_count_3, + input wire qsfp2_tx_clk_4, + input wire qsfp2_tx_rst_4, + output wire [XGMII_DATA_WIDTH-1:0] qsfp2_txd_4, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp2_txc_4, + output wire qsfp2_tx_prbs31_enable_4, + input wire qsfp2_rx_clk_4, + input wire qsfp2_rx_rst_4, + input wire [XGMII_DATA_WIDTH-1:0] qsfp2_rxd_4, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp2_rxc_4, + output wire qsfp2_rx_prbs31_enable_4, + input wire [6:0] qsfp2_rx_error_count_4, + + input wire qsfp2_drp_clk, + input wire qsfp2_drp_rst, + output wire [23:0] qsfp2_drp_addr, + output wire [15:0] qsfp2_drp_di, + output wire qsfp2_drp_en, + output wire qsfp2_drp_we, + input wire [15:0] qsfp2_drp_do, + input wire qsfp2_drp_rdy, + + output wire qsfp2_resetl, + input wire qsfp2_modprsl, + input wire qsfp2_intl, + output wire qsfp2_lpmode, + + input wire qsfp2_i2c_scl_i, + output wire qsfp2_i2c_scl_o, + output wire qsfp2_i2c_scl_t, + input wire qsfp2_i2c_sda_i, + output wire qsfp2_i2c_sda_o, + output wire qsfp2_i2c_sda_t, + + input wire qsfp3_tx_clk_1, + input wire qsfp3_tx_rst_1, + output wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_1, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_1, + output wire qsfp3_tx_prbs31_enable_1, + input wire qsfp3_rx_clk_1, + input wire qsfp3_rx_rst_1, + input wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_1, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_1, + output wire qsfp3_rx_prbs31_enable_1, + input wire [6:0] qsfp3_rx_error_count_1, + input wire qsfp3_tx_clk_2, + input wire qsfp3_tx_rst_2, + output wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_2, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_2, + output wire qsfp3_tx_prbs31_enable_2, + input wire qsfp3_rx_clk_2, + input wire qsfp3_rx_rst_2, + input wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_2, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_2, + output wire qsfp3_rx_prbs31_enable_2, + input wire [6:0] qsfp3_rx_error_count_2, + input wire qsfp3_tx_clk_3, + input wire qsfp3_tx_rst_3, + output wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_3, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_3, + output wire qsfp3_tx_prbs31_enable_3, + input wire qsfp3_rx_clk_3, + input wire qsfp3_rx_rst_3, + input wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_3, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_3, + output wire qsfp3_rx_prbs31_enable_3, + input wire [6:0] qsfp3_rx_error_count_3, + input wire qsfp3_tx_clk_4, + input wire qsfp3_tx_rst_4, + output wire [XGMII_DATA_WIDTH-1:0] qsfp3_txd_4, + output wire [XGMII_CTRL_WIDTH-1:0] qsfp3_txc_4, + output wire qsfp3_tx_prbs31_enable_4, + input wire qsfp3_rx_clk_4, + input wire qsfp3_rx_rst_4, + input wire [XGMII_DATA_WIDTH-1:0] qsfp3_rxd_4, + input wire [XGMII_CTRL_WIDTH-1:0] qsfp3_rxc_4, + output wire qsfp3_rx_prbs31_enable_4, + input wire [6:0] qsfp3_rx_error_count_4, + + input wire qsfp3_drp_clk, + input wire qsfp3_drp_rst, + output wire [23:0] qsfp3_drp_addr, + output wire [15:0] qsfp3_drp_di, + output wire qsfp3_drp_en, + output wire qsfp3_drp_we, + input wire [15:0] qsfp3_drp_do, + input wire qsfp3_drp_rdy, + + output wire qsfp3_resetl, + input wire qsfp3_modprsl, + input wire qsfp3_intl, + output wire qsfp3_lpmode, + + input wire qsfp3_i2c_scl_i, + output wire qsfp3_i2c_scl_o, + output wire qsfp3_i2c_scl_t, + input wire qsfp3_i2c_sda_i, + output wire qsfp3_i2c_sda_o, + output wire qsfp3_i2c_sda_t, + + /* + * QSPI flash + */ + output wire fpga_boot, + output wire qspi_clk, + input wire [3:0] qspi_dq_i, + output wire [3:0] qspi_dq_o, + output wire [3:0] qspi_dq_oe, + output wire qspi_cs +); + +parameter PORT_COUNT = IF_COUNT*PORTS_PER_IF; + +parameter F_COUNT = PF_COUNT+VF_COUNT; + +parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8); +parameter AXIL_IF_CTRL_ADDR_WIDTH = AXIL_CTRL_ADDR_WIDTH-$clog2(IF_COUNT); +parameter AXIL_CSR_ADDR_WIDTH = AXIL_IF_CTRL_ADDR_WIDTH-5-$clog2((PORTS_PER_IF+3)/8); + +localparam RB_BASE_ADDR = 16'h1000; +localparam RBB = RB_BASE_ADDR & {AXIL_CTRL_ADDR_WIDTH{1'b1}}; + +localparam RB_DRP_QSFP0_BASE = RB_BASE_ADDR + 16'h80; +localparam RB_DRP_QSFP1_BASE = RB_DRP_QSFP0_BASE + 16'h20; +localparam RB_DRP_QSFP2_BASE = RB_DRP_QSFP1_BASE + 16'h20; +localparam RB_DRP_QSFP3_BASE = RB_DRP_QSFP2_BASE + 16'h20; + +initial begin + if (PORT_COUNT > 16) begin + $error("Error: Max port count exceeded (instance %m)"); + $finish; + end +end + +// AXI lite connections +wire [AXIL_CSR_ADDR_WIDTH-1:0] axil_csr_awaddr; +wire [2:0] axil_csr_awprot; +wire axil_csr_awvalid; +wire axil_csr_awready; +wire [AXIL_CTRL_DATA_WIDTH-1:0] axil_csr_wdata; +wire [AXIL_CTRL_STRB_WIDTH-1:0] axil_csr_wstrb; +wire axil_csr_wvalid; +wire axil_csr_wready; +wire [1:0] axil_csr_bresp; +wire axil_csr_bvalid; +wire axil_csr_bready; +wire [AXIL_CSR_ADDR_WIDTH-1:0] axil_csr_araddr; +wire [2:0] axil_csr_arprot; +wire axil_csr_arvalid; +wire axil_csr_arready; +wire [AXIL_CTRL_DATA_WIDTH-1:0] axil_csr_rdata; +wire [1:0] axil_csr_rresp; +wire axil_csr_rvalid; +wire axil_csr_rready; + +// PTP +wire [PTP_TS_WIDTH-1:0] ptp_ts_96; +wire ptp_ts_step; +wire ptp_pps; + +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_locked; +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_error; +wire [PTP_PEROUT_COUNT-1:0] ptp_perout_pulse; + +// control registers +wire [AXIL_CSR_ADDR_WIDTH-1:0] ctrl_reg_wr_addr; +wire [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_wr_data; +wire [AXIL_CTRL_STRB_WIDTH-1:0] ctrl_reg_wr_strb; +wire ctrl_reg_wr_en; +wire ctrl_reg_wr_wait; +wire ctrl_reg_wr_ack; +wire [AXIL_CSR_ADDR_WIDTH-1:0] ctrl_reg_rd_addr; +wire ctrl_reg_rd_en; +wire [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_rd_data; +wire ctrl_reg_rd_wait; +wire ctrl_reg_rd_ack; + +wire qsfp0_drp_reg_wr_wait; +wire qsfp0_drp_reg_wr_ack; +wire [AXIL_CTRL_DATA_WIDTH-1:0] qsfp0_drp_reg_rd_data; +wire qsfp0_drp_reg_rd_wait; +wire qsfp0_drp_reg_rd_ack; + +wire qsfp1_drp_reg_wr_wait; +wire qsfp1_drp_reg_wr_ack; +wire [AXIL_CTRL_DATA_WIDTH-1:0] qsfp1_drp_reg_rd_data; +wire qsfp1_drp_reg_rd_wait; +wire qsfp1_drp_reg_rd_ack; + +wire qsfp2_drp_reg_wr_wait; +wire qsfp2_drp_reg_wr_ack; +wire [AXIL_CTRL_DATA_WIDTH-1:0] qsfp2_drp_reg_rd_data; +wire qsfp2_drp_reg_rd_wait; +wire qsfp2_drp_reg_rd_ack; + +wire qsfp3_drp_reg_wr_wait; +wire qsfp3_drp_reg_wr_ack; +wire [AXIL_CTRL_DATA_WIDTH-1:0] qsfp3_drp_reg_rd_data; +wire qsfp3_drp_reg_rd_wait; +wire qsfp3_drp_reg_rd_ack; + +reg ctrl_reg_wr_ack_reg = 1'b0; +reg [AXIL_CTRL_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = {AXIL_CTRL_DATA_WIDTH{1'b0}}; +reg ctrl_reg_rd_ack_reg = 1'b0; + +reg qsfp0_reset_reg = 1'b0; +reg qsfp1_reset_reg = 1'b0; +reg qsfp2_reset_reg = 1'b0; +reg qsfp3_reset_reg = 1'b0; + +reg qsfp0_lpmode_reg = 1'b0; +reg qsfp1_lpmode_reg = 1'b0; +reg qsfp2_lpmode_reg = 1'b0; +reg qsfp3_lpmode_reg = 1'b0; + +reg eeprom_i2c_scl_o_reg = 1'b1; +reg eeprom_i2c_sda_o_reg = 1'b1; + +reg qsfp0_i2c_scl_o_reg = 1'b1; +reg qsfp0_i2c_sda_o_reg = 1'b1; + +reg qsfp1_i2c_scl_o_reg = 1'b1; +reg qsfp1_i2c_sda_o_reg = 1'b1; + +reg qsfp2_i2c_scl_o_reg = 1'b1; +reg qsfp2_i2c_sda_o_reg = 1'b1; + +reg qsfp3_i2c_scl_o_reg = 1'b1; +reg qsfp3_i2c_sda_o_reg = 1'b1; + +reg fpga_boot_reg = 1'b0; + +reg qspi_clk_reg = 1'b0; +reg qspi_cs_reg = 1'b1; +reg [3:0] qspi_dq_o_reg = 4'd0; +reg [3:0] qspi_dq_oe_reg = 4'd0; + +assign ctrl_reg_wr_wait = qsfp0_drp_reg_wr_wait | qsfp1_drp_reg_wr_wait | qsfp2_drp_reg_wr_wait | qsfp3_drp_reg_wr_wait; +assign ctrl_reg_wr_ack = ctrl_reg_wr_ack_reg | qsfp0_drp_reg_wr_ack | qsfp1_drp_reg_wr_ack | qsfp2_drp_reg_wr_ack | qsfp3_drp_reg_wr_ack; +assign ctrl_reg_rd_data = ctrl_reg_rd_data_reg | qsfp0_drp_reg_rd_data | qsfp1_drp_reg_rd_data | qsfp2_drp_reg_rd_data | qsfp3_drp_reg_rd_data; +assign ctrl_reg_rd_wait = qsfp0_drp_reg_rd_wait | qsfp1_drp_reg_rd_wait | qsfp2_drp_reg_rd_wait | qsfp3_drp_reg_rd_wait; +assign ctrl_reg_rd_ack = ctrl_reg_rd_ack_reg | qsfp0_drp_reg_rd_ack | qsfp1_drp_reg_rd_ack | qsfp2_drp_reg_rd_ack | qsfp3_drp_reg_rd_ack; + +assign qsfp0_resetl = !qsfp0_reset_reg; +assign qsfp1_resetl = !qsfp1_reset_reg; +assign qsfp2_resetl = !qsfp2_reset_reg; +assign qsfp3_resetl = !qsfp3_reset_reg; + +assign qsfp0_lpmode = qsfp0_lpmode_reg; +assign qsfp1_lpmode = qsfp1_lpmode_reg; +assign qsfp2_lpmode = qsfp2_lpmode_reg; +assign qsfp3_lpmode = qsfp3_lpmode_reg; + +assign eeprom_i2c_scl_o = eeprom_i2c_scl_o_reg; +assign eeprom_i2c_scl_t = eeprom_i2c_scl_o_reg; +assign eeprom_i2c_sda_o = eeprom_i2c_sda_o_reg; +assign eeprom_i2c_sda_t = eeprom_i2c_sda_o_reg; + +assign qsfp0_i2c_scl_o = qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_scl_t = qsfp0_i2c_scl_o_reg; +assign qsfp0_i2c_sda_o = qsfp0_i2c_sda_o_reg; +assign qsfp0_i2c_sda_t = qsfp0_i2c_sda_o_reg; + +assign qsfp1_i2c_scl_o = qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_scl_t = qsfp1_i2c_scl_o_reg; +assign qsfp1_i2c_sda_o = qsfp1_i2c_sda_o_reg; +assign qsfp1_i2c_sda_t = qsfp1_i2c_sda_o_reg; + +assign qsfp2_i2c_scl_o = qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_scl_t = qsfp2_i2c_scl_o_reg; +assign qsfp2_i2c_sda_o = qsfp2_i2c_sda_o_reg; +assign qsfp2_i2c_sda_t = qsfp2_i2c_sda_o_reg; + +assign qsfp3_i2c_scl_o = qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_scl_t = qsfp3_i2c_scl_o_reg; +assign qsfp3_i2c_sda_o = qsfp3_i2c_sda_o_reg; +assign qsfp3_i2c_sda_t = qsfp3_i2c_sda_o_reg; + +assign fpga_boot = fpga_boot_reg; + +assign qspi_clk = qspi_clk_reg; +assign qspi_cs = qspi_cs_reg; +assign qspi_dq_o = qspi_dq_o_reg; +assign qspi_dq_oe = qspi_dq_oe_reg; + +always @(posedge clk_250mhz) begin + ctrl_reg_wr_ack_reg <= 1'b0; + ctrl_reg_rd_data_reg <= {AXIL_CTRL_DATA_WIDTH{1'b0}}; + ctrl_reg_rd_ack_reg <= 1'b0; + + if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin + // write operation + ctrl_reg_wr_ack_reg <= 1'b0; + case ({ctrl_reg_wr_addr >> 2, 2'b00}) + // FW ID + 8'h0C: begin + // FW ID: FPGA JTAG ID + fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; + end + // I2C 0 + RBB+8'h0C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp0_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp0_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 1 + RBB+8'h1C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp1_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp1_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 2 + RBB+8'h2C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp2_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp2_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 3 + RBB+8'h3C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + qsfp3_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp3_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // I2C 4 + RBB+8'h4C: begin + // I2C ctrl: control + if (ctrl_reg_wr_strb[0]) begin + eeprom_i2c_scl_o_reg <= ctrl_reg_wr_data[1]; + end + if (ctrl_reg_wr_strb[1]) begin + eeprom_i2c_sda_o_reg <= ctrl_reg_wr_data[9]; + end + end + // XCVR GPIO + RBB+8'h5C: begin + // XCVR GPIO: control 0123 + if (ctrl_reg_wr_strb[0]) begin + qsfp0_reset_reg <= ctrl_reg_wr_data[4]; + qsfp0_lpmode_reg <= ctrl_reg_wr_data[5]; + end + if (ctrl_reg_wr_strb[1]) begin + qsfp1_reset_reg <= ctrl_reg_wr_data[12]; + qsfp1_lpmode_reg <= ctrl_reg_wr_data[13]; + end + if (ctrl_reg_wr_strb[2]) begin + qsfp2_reset_reg <= ctrl_reg_wr_data[20]; + qsfp2_lpmode_reg <= ctrl_reg_wr_data[21]; + end + if (ctrl_reg_wr_strb[3]) begin + qsfp3_reset_reg <= ctrl_reg_wr_data[28]; + qsfp3_lpmode_reg <= ctrl_reg_wr_data[29]; + end + end + // QSPI flash + RBB+8'h6C: begin + // SPI flash ctrl: format + fpga_boot_reg <= ctrl_reg_wr_data == 32'hFEE1DEAD; + end + RBB+8'h70: begin + // SPI flash ctrl: control 0 + if (ctrl_reg_wr_strb[0]) begin + qspi_dq_o_reg <= ctrl_reg_wr_data[3:0]; + end + if (ctrl_reg_wr_strb[1]) begin + qspi_dq_oe_reg <= ctrl_reg_wr_data[11:8]; + end + if (ctrl_reg_wr_strb[2]) begin + qspi_clk_reg <= ctrl_reg_wr_data[16]; + qspi_cs_reg <= ctrl_reg_wr_data[17]; + end + end + default: ctrl_reg_wr_ack_reg <= 1'b0; + endcase + end + + if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin + // read operation + ctrl_reg_rd_ack_reg <= 1'b1; + case ({ctrl_reg_rd_addr >> 2, 2'b00}) + // I2C 0 + RBB+8'h00: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h04: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h08: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // I2C ctrl: Next header + RBB+8'h0C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp0_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp0_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp0_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp0_i2c_sda_o_reg; + end + // I2C 1 + RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h18: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h20; // I2C ctrl: Next header + RBB+8'h1C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp1_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp1_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp1_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp1_i2c_sda_o_reg; + end + // I2C 2 + RBB+8'h20: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h24: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h28: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h30; // I2C ctrl: Next header + RBB+8'h2C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp2_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp2_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp2_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp2_i2c_sda_o_reg; + end + // I2C 3 + RBB+8'h30: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h34: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h38: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h40; // I2C ctrl: Next header + RBB+8'h3C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= qsfp3_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= qsfp3_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= qsfp3_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= qsfp3_i2c_sda_o_reg; + end + // I2C 4 + RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C110; // I2C ctrl: Type + RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000100; // I2C ctrl: Version + RBB+8'h48: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h50; // I2C ctrl: Next header + RBB+8'h4C: begin + // I2C ctrl: control + ctrl_reg_rd_data_reg[0] <= eeprom_i2c_scl_i; + ctrl_reg_rd_data_reg[1] <= eeprom_i2c_scl_o_reg; + ctrl_reg_rd_data_reg[8] <= eeprom_i2c_sda_i; + ctrl_reg_rd_data_reg[9] <= eeprom_i2c_sda_o_reg; + end + // XCVR GPIO + RBB+8'h50: ctrl_reg_rd_data_reg <= 32'h0000C101; // XCVR GPIO: Type + RBB+8'h54: ctrl_reg_rd_data_reg <= 32'h00000100; // XCVR GPIO: Version + RBB+8'h58: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h60; // XCVR GPIO: Next header + RBB+8'h5C: begin + // XCVR GPIO: control 0123 + ctrl_reg_rd_data_reg[0] <= !qsfp0_modprsl; + ctrl_reg_rd_data_reg[1] <= !qsfp0_intl; + ctrl_reg_rd_data_reg[4] <= qsfp0_reset_reg; + ctrl_reg_rd_data_reg[5] <= qsfp0_lpmode_reg; + ctrl_reg_rd_data_reg[8] <= !qsfp1_modprsl; + ctrl_reg_rd_data_reg[9] <= !qsfp1_intl; + ctrl_reg_rd_data_reg[12] <= qsfp1_reset_reg; + ctrl_reg_rd_data_reg[13] <= qsfp1_lpmode_reg; + ctrl_reg_rd_data_reg[16] <= !qsfp2_modprsl; + ctrl_reg_rd_data_reg[17] <= !qsfp2_intl; + ctrl_reg_rd_data_reg[20] <= qsfp2_reset_reg; + ctrl_reg_rd_data_reg[21] <= qsfp2_lpmode_reg; + ctrl_reg_rd_data_reg[24] <= !qsfp3_modprsl; + ctrl_reg_rd_data_reg[25] <= !qsfp3_intl; + ctrl_reg_rd_data_reg[28] <= qsfp3_reset_reg; + ctrl_reg_rd_data_reg[29] <= qsfp3_lpmode_reg; + end + // QSPI flash + RBB+8'h60: ctrl_reg_rd_data_reg <= 32'h0000C120; // SPI flash ctrl: Type + RBB+8'h64: ctrl_reg_rd_data_reg <= 32'h00000200; // SPI flash ctrl: Version + RBB+8'h68: ctrl_reg_rd_data_reg <= RB_DRP_QSFP0_BASE; // SPI flash ctrl: Next header + RBB+8'h6C: begin + // SPI flash ctrl: format + ctrl_reg_rd_data_reg[3:0] <= 2; // configuration (two segments) + ctrl_reg_rd_data_reg[7:4] <= 0; // default segment + ctrl_reg_rd_data_reg[11:8] <= 1; // fallback segment + ctrl_reg_rd_data_reg[31:12] <= 32'h0C000000 >> 12; // first segment size (192 M) + end + RBB+8'h70: begin + // SPI flash ctrl: control 0 + ctrl_reg_rd_data_reg[3:0] <= qspi_dq_i; + ctrl_reg_rd_data_reg[11:8] <= qspi_dq_oe; + ctrl_reg_rd_data_reg[16] <= qspi_clk; + ctrl_reg_rd_data_reg[17] <= qspi_cs; + end + default: ctrl_reg_rd_ack_reg <= 1'b0; + endcase + end + + if (rst_250mhz) begin + ctrl_reg_wr_ack_reg <= 1'b0; + ctrl_reg_rd_ack_reg <= 1'b0; + + qsfp0_reset_reg <= 1'b0; + qsfp1_reset_reg <= 1'b0; + qsfp2_reset_reg <= 1'b0; + qsfp3_reset_reg <= 1'b0; + + qsfp0_lpmode_reg <= 1'b0; + qsfp1_lpmode_reg <= 1'b0; + qsfp2_lpmode_reg <= 1'b0; + qsfp3_lpmode_reg <= 1'b0; + + eeprom_i2c_scl_o_reg <= 1'b1; + eeprom_i2c_sda_o_reg <= 1'b1; + + qsfp0_i2c_scl_o_reg <= 1'b1; + qsfp0_i2c_sda_o_reg <= 1'b1; + + qsfp1_i2c_scl_o_reg <= 1'b1; + qsfp1_i2c_sda_o_reg <= 1'b1; + + qsfp2_i2c_scl_o_reg <= 1'b1; + qsfp2_i2c_sda_o_reg <= 1'b1; + + qsfp3_i2c_scl_o_reg <= 1'b1; + qsfp3_i2c_sda_o_reg <= 1'b1; + + fpga_boot_reg <= 1'b0; + + qspi_clk_reg <= 1'b0; + qspi_cs_reg <= 1'b1; + qspi_dq_o_reg <= 4'd0; + qspi_dq_oe_reg <= 4'd0; + end +end + +rb_drp #( + .DRP_ADDR_WIDTH(24), + .DRP_DATA_WIDTH(16), + .DRP_INFO({8'h09, 8'h03, 8'd0, 8'd4}), + .REG_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .RB_BASE_ADDR(RB_DRP_QSFP0_BASE), + .RB_NEXT_PTR(RB_DRP_QSFP1_BASE) +) +qsfp0_rb_drp_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * Register interface + */ + .reg_wr_addr(ctrl_reg_wr_addr), + .reg_wr_data(ctrl_reg_wr_data), + .reg_wr_strb(ctrl_reg_wr_strb), + .reg_wr_en(ctrl_reg_wr_en), + .reg_wr_wait(qsfp0_drp_reg_wr_wait), + .reg_wr_ack(qsfp0_drp_reg_wr_ack), + .reg_rd_addr(ctrl_reg_rd_addr), + .reg_rd_en(ctrl_reg_rd_en), + .reg_rd_data(qsfp0_drp_reg_rd_data), + .reg_rd_wait(qsfp0_drp_reg_rd_wait), + .reg_rd_ack(qsfp0_drp_reg_rd_ack), + + /* + * DRP + */ + .drp_clk(qsfp0_drp_clk), + .drp_rst(qsfp0_drp_rst), + .drp_addr(qsfp0_drp_addr), + .drp_di(qsfp0_drp_di), + .drp_en(qsfp0_drp_en), + .drp_we(qsfp0_drp_we), + .drp_do(qsfp0_drp_do), + .drp_rdy(qsfp0_drp_rdy) +); + +rb_drp #( + .DRP_ADDR_WIDTH(24), + .DRP_DATA_WIDTH(16), + .DRP_INFO({8'h09, 8'h03, 8'd0, 8'd4}), + .REG_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .RB_BASE_ADDR(RB_DRP_QSFP1_BASE), + .RB_NEXT_PTR(RB_DRP_QSFP2_BASE) +) +qsfp1_rb_drp_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * Register interface + */ + .reg_wr_addr(ctrl_reg_wr_addr), + .reg_wr_data(ctrl_reg_wr_data), + .reg_wr_strb(ctrl_reg_wr_strb), + .reg_wr_en(ctrl_reg_wr_en), + .reg_wr_wait(qsfp1_drp_reg_wr_wait), + .reg_wr_ack(qsfp1_drp_reg_wr_ack), + .reg_rd_addr(ctrl_reg_rd_addr), + .reg_rd_en(ctrl_reg_rd_en), + .reg_rd_data(qsfp1_drp_reg_rd_data), + .reg_rd_wait(qsfp1_drp_reg_rd_wait), + .reg_rd_ack(qsfp1_drp_reg_rd_ack), + + /* + * DRP + */ + .drp_clk(qsfp1_drp_clk), + .drp_rst(qsfp1_drp_rst), + .drp_addr(qsfp1_drp_addr), + .drp_di(qsfp1_drp_di), + .drp_en(qsfp1_drp_en), + .drp_we(qsfp1_drp_we), + .drp_do(qsfp1_drp_do), + .drp_rdy(qsfp1_drp_rdy) +); + +rb_drp #( + .DRP_ADDR_WIDTH(24), + .DRP_DATA_WIDTH(16), + .DRP_INFO({8'h09, 8'h03, 8'd0, 8'd4}), + .REG_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .RB_BASE_ADDR(RB_DRP_QSFP2_BASE), + .RB_NEXT_PTR(RB_DRP_QSFP3_BASE) +) +qsfp2_rb_drp_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * Register interface + */ + .reg_wr_addr(ctrl_reg_wr_addr), + .reg_wr_data(ctrl_reg_wr_data), + .reg_wr_strb(ctrl_reg_wr_strb), + .reg_wr_en(ctrl_reg_wr_en), + .reg_wr_wait(qsfp2_drp_reg_wr_wait), + .reg_wr_ack(qsfp2_drp_reg_wr_ack), + .reg_rd_addr(ctrl_reg_rd_addr), + .reg_rd_en(ctrl_reg_rd_en), + .reg_rd_data(qsfp2_drp_reg_rd_data), + .reg_rd_wait(qsfp2_drp_reg_rd_wait), + .reg_rd_ack(qsfp2_drp_reg_rd_ack), + + /* + * DRP + */ + .drp_clk(qsfp2_drp_clk), + .drp_rst(qsfp2_drp_rst), + .drp_addr(qsfp2_drp_addr), + .drp_di(qsfp2_drp_di), + .drp_en(qsfp2_drp_en), + .drp_we(qsfp2_drp_we), + .drp_do(qsfp2_drp_do), + .drp_rdy(qsfp2_drp_rdy) +); + +rb_drp #( + .DRP_ADDR_WIDTH(24), + .DRP_DATA_WIDTH(16), + .DRP_INFO({8'h09, 8'h03, 8'd0, 8'd4}), + .REG_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .REG_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .REG_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .RB_BASE_ADDR(RB_DRP_QSFP3_BASE), + .RB_NEXT_PTR(0) +) +qsfp3_rb_drp_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * Register interface + */ + .reg_wr_addr(ctrl_reg_wr_addr), + .reg_wr_data(ctrl_reg_wr_data), + .reg_wr_strb(ctrl_reg_wr_strb), + .reg_wr_en(ctrl_reg_wr_en), + .reg_wr_wait(qsfp3_drp_reg_wr_wait), + .reg_wr_ack(qsfp3_drp_reg_wr_ack), + .reg_rd_addr(ctrl_reg_rd_addr), + .reg_rd_en(ctrl_reg_rd_en), + .reg_rd_data(qsfp3_drp_reg_rd_data), + .reg_rd_wait(qsfp3_drp_reg_rd_wait), + .reg_rd_ack(qsfp3_drp_reg_rd_ack), + + /* + * DRP + */ + .drp_clk(qsfp3_drp_clk), + .drp_rst(qsfp3_drp_rst), + .drp_addr(qsfp3_drp_addr), + .drp_di(qsfp3_drp_di), + .drp_en(qsfp3_drp_en), + .drp_we(qsfp3_drp_we), + .drp_do(qsfp3_drp_do), + .drp_rdy(qsfp3_drp_rdy) +); + +reg [26:0] pps_led_counter_reg = 0; +reg pps_led_reg = 0; + +always @(posedge clk_250mhz) begin + if (ptp_pps) begin + pps_led_counter_reg <= 125000000; + end else if (pps_led_counter_reg > 0) begin + pps_led_counter_reg <= pps_led_counter_reg - 1; + end + + pps_led_reg <= pps_led_counter_reg > 0; +end + +// BER tester +tdma_ber #( + .COUNT(16), + .INDEX_WIDTH(6), + .SLICE_WIDTH(5), + .AXIL_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .AXIL_ADDR_WIDTH(8+6+$clog2(16)), + .AXIL_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .SCHEDULE_START_S(0), + .SCHEDULE_START_NS(0), + .SCHEDULE_PERIOD_S(0), + .SCHEDULE_PERIOD_NS(1000000), + .TIMESLOT_PERIOD_S(0), + .TIMESLOT_PERIOD_NS(100000), + .ACTIVE_PERIOD_S(0), + .ACTIVE_PERIOD_NS(90000), + .PHY_PIPELINE(2) +) +tdma_ber_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + .phy_tx_clk({qsfp3_tx_clk_4, qsfp3_tx_clk_3, qsfp3_tx_clk_2, qsfp3_tx_clk_1, qsfp2_tx_clk_4, qsfp2_tx_clk_3, qsfp2_tx_clk_2, qsfp2_tx_clk_1, qsfp1_tx_clk_4, qsfp1_tx_clk_3, qsfp1_tx_clk_2, qsfp1_tx_clk_1, qsfp0_tx_clk_4, qsfp0_tx_clk_3, qsfp0_tx_clk_2, qsfp0_tx_clk_1}), + .phy_rx_clk({qsfp3_rx_clk_4, qsfp3_rx_clk_3, qsfp3_rx_clk_2, qsfp3_rx_clk_1, qsfp2_rx_clk_4, qsfp2_rx_clk_3, qsfp2_rx_clk_2, qsfp2_rx_clk_1, qsfp1_rx_clk_4, qsfp1_rx_clk_3, qsfp1_rx_clk_2, qsfp1_rx_clk_1, qsfp0_rx_clk_4, qsfp0_rx_clk_3, qsfp0_rx_clk_2, qsfp0_rx_clk_1}), + .phy_rx_error_count({qsfp3_rx_error_count_4, qsfp3_rx_error_count_3, qsfp3_rx_error_count_2, qsfp3_rx_error_count_1, qsfp2_rx_error_count_4, qsfp2_rx_error_count_3, qsfp2_rx_error_count_2, qsfp2_rx_error_count_1, qsfp1_rx_error_count_4, qsfp1_rx_error_count_3, qsfp1_rx_error_count_2, qsfp1_rx_error_count_1, qsfp0_rx_error_count_4, qsfp0_rx_error_count_3, qsfp0_rx_error_count_2, qsfp0_rx_error_count_1}), + .phy_tx_prbs31_enable({qsfp3_tx_prbs31_enable_4, qsfp3_tx_prbs31_enable_3, qsfp3_tx_prbs31_enable_2, qsfp3_tx_prbs31_enable_1, qsfp2_tx_prbs31_enable_4, qsfp2_tx_prbs31_enable_3, qsfp2_tx_prbs31_enable_2, qsfp2_tx_prbs31_enable_1, qsfp1_tx_prbs31_enable_4, qsfp1_tx_prbs31_enable_3, qsfp1_tx_prbs31_enable_2, qsfp1_tx_prbs31_enable_1, qsfp0_tx_prbs31_enable_4, qsfp0_tx_prbs31_enable_3, qsfp0_tx_prbs31_enable_2, qsfp0_tx_prbs31_enable_1}), + .phy_rx_prbs31_enable({qsfp3_rx_prbs31_enable_4, qsfp3_rx_prbs31_enable_3, qsfp3_rx_prbs31_enable_2, qsfp3_rx_prbs31_enable_1, qsfp2_rx_prbs31_enable_4, qsfp2_rx_prbs31_enable_3, qsfp2_rx_prbs31_enable_2, qsfp2_rx_prbs31_enable_1, qsfp1_rx_prbs31_enable_4, qsfp1_rx_prbs31_enable_3, qsfp1_rx_prbs31_enable_2, qsfp1_rx_prbs31_enable_1, qsfp0_rx_prbs31_enable_4, qsfp0_rx_prbs31_enable_3, qsfp0_rx_prbs31_enable_2, qsfp0_rx_prbs31_enable_1}), + .s_axil_awaddr(axil_csr_awaddr), + .s_axil_awprot(axil_csr_awprot), + .s_axil_awvalid(axil_csr_awvalid), + .s_axil_awready(axil_csr_awready), + .s_axil_wdata(axil_csr_wdata), + .s_axil_wstrb(axil_csr_wstrb), + .s_axil_wvalid(axil_csr_wvalid), + .s_axil_wready(axil_csr_wready), + .s_axil_bresp(axil_csr_bresp), + .s_axil_bvalid(axil_csr_bvalid), + .s_axil_bready(axil_csr_bready), + .s_axil_araddr(axil_csr_araddr), + .s_axil_arprot(axil_csr_arprot), + .s_axil_arvalid(axil_csr_arvalid), + .s_axil_arready(axil_csr_arready), + .s_axil_rdata(axil_csr_rdata), + .s_axil_rresp(axil_csr_rresp), + .s_axil_rvalid(axil_csr_rvalid), + .s_axil_rready(axil_csr_rready), + .ptp_ts_96(ptp_ts_96), + .ptp_ts_step(ptp_ts_step) +); + +assign led[2:0] = 3'b111; +assign led[3] = !pps_led_reg; + +wire [PORT_COUNT-1:0] eth_tx_clk; +wire [PORT_COUNT-1:0] eth_tx_rst; + +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_tx_ptp_ts_96; +wire [PORT_COUNT-1:0] eth_tx_ptp_ts_step; + +wire [PORT_COUNT*AXIS_ETH_DATA_WIDTH-1:0] axis_eth_tx_tdata; +wire [PORT_COUNT*AXIS_ETH_KEEP_WIDTH-1:0] axis_eth_tx_tkeep; +wire [PORT_COUNT-1:0] axis_eth_tx_tvalid; +wire [PORT_COUNT-1:0] axis_eth_tx_tready; +wire [PORT_COUNT-1:0] axis_eth_tx_tlast; +wire [PORT_COUNT*AXIS_ETH_TX_USER_WIDTH-1:0] axis_eth_tx_tuser; + +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] axis_eth_tx_ptp_ts; +wire [PORT_COUNT*PTP_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; +wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; +wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; + +wire [PORT_COUNT-1:0] eth_rx_clk; +wire [PORT_COUNT-1:0] eth_rx_rst; + +wire [PORT_COUNT*PTP_TS_WIDTH-1:0] eth_rx_ptp_ts_96; +wire [PORT_COUNT-1:0] eth_rx_ptp_ts_step; + +wire [PORT_COUNT*AXIS_ETH_DATA_WIDTH-1:0] axis_eth_rx_tdata; +wire [PORT_COUNT*AXIS_ETH_KEEP_WIDTH-1:0] axis_eth_rx_tkeep; +wire [PORT_COUNT-1:0] axis_eth_rx_tvalid; +wire [PORT_COUNT-1:0] axis_eth_rx_tready; +wire [PORT_COUNT-1:0] axis_eth_rx_tlast; +wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; + +wire [PORT_COUNT-1:0] port_xgmii_tx_clk; +wire [PORT_COUNT-1:0] port_xgmii_tx_rst; +wire [PORT_COUNT*XGMII_DATA_WIDTH-1:0] port_xgmii_txd; +wire [PORT_COUNT*XGMII_CTRL_WIDTH-1:0] port_xgmii_txc; + +wire [PORT_COUNT-1:0] port_xgmii_rx_clk; +wire [PORT_COUNT-1:0] port_xgmii_rx_rst; +wire [PORT_COUNT*XGMII_DATA_WIDTH-1:0] port_xgmii_rxd; +wire [PORT_COUNT*XGMII_CTRL_WIDTH-1:0] port_xgmii_rxc; + +mqnic_port_map_phy_xgmii #( + .PHY_COUNT(16), + .PORT_MASK(PORT_MASK), + .PORT_GROUP_SIZE(4), + + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + + .PORT_COUNT(PORT_COUNT), + + .XGMII_DATA_WIDTH(XGMII_DATA_WIDTH), + .XGMII_CTRL_WIDTH(XGMII_CTRL_WIDTH) +) +mqnic_port_map_phy_xgmii_inst ( + // towards PHY + .phy_xgmii_tx_clk({qsfp3_tx_clk_4, qsfp3_tx_clk_3, qsfp3_tx_clk_2, qsfp3_tx_clk_1, qsfp2_tx_clk_4, qsfp2_tx_clk_3, qsfp2_tx_clk_2, qsfp2_tx_clk_1, qsfp1_tx_clk_4, qsfp1_tx_clk_3, qsfp1_tx_clk_2, qsfp1_tx_clk_1, qsfp0_tx_clk_4, qsfp0_tx_clk_3, qsfp0_tx_clk_2, qsfp0_tx_clk_1}), + .phy_xgmii_tx_rst({qsfp3_tx_rst_4, qsfp3_tx_rst_3, qsfp3_tx_rst_2, qsfp3_tx_rst_1, qsfp2_tx_rst_4, qsfp2_tx_rst_3, qsfp2_tx_rst_2, qsfp2_tx_rst_1, qsfp1_tx_rst_4, qsfp1_tx_rst_3, qsfp1_tx_rst_2, qsfp1_tx_rst_1, qsfp0_tx_rst_4, qsfp0_tx_rst_3, qsfp0_tx_rst_2, qsfp0_tx_rst_1}), + .phy_xgmii_txd({qsfp3_txd_4, qsfp3_txd_3, qsfp3_txd_2, qsfp3_txd_1, qsfp2_txd_4, qsfp2_txd_3, qsfp2_txd_2, qsfp2_txd_1, qsfp1_txd_4, qsfp1_txd_3, qsfp1_txd_2, qsfp1_txd_1, qsfp0_txd_4, qsfp0_txd_3, qsfp0_txd_2, qsfp0_txd_1}), + .phy_xgmii_txc({qsfp3_txc_4, qsfp3_txc_3, qsfp3_txc_2, qsfp3_txc_1, qsfp2_txc_4, qsfp2_txc_3, qsfp2_txc_2, qsfp2_txc_1, qsfp1_txc_4, qsfp1_txc_3, qsfp1_txc_2, qsfp1_txc_1, qsfp0_txc_4, qsfp0_txc_3, qsfp0_txc_2, qsfp0_txc_1}), + + .phy_xgmii_rx_clk({qsfp3_rx_clk_4, qsfp3_rx_clk_3, qsfp3_rx_clk_2, qsfp3_rx_clk_1, qsfp2_rx_clk_4, qsfp2_rx_clk_3, qsfp2_rx_clk_2, qsfp2_rx_clk_1, qsfp1_rx_clk_4, qsfp1_rx_clk_3, qsfp1_rx_clk_2, qsfp1_rx_clk_1, qsfp0_rx_clk_4, qsfp0_rx_clk_3, qsfp0_rx_clk_2, qsfp0_rx_clk_1}), + .phy_xgmii_rx_rst({qsfp3_rx_rst_4, qsfp3_rx_rst_3, qsfp3_rx_rst_2, qsfp3_rx_rst_1, qsfp2_rx_rst_4, qsfp2_rx_rst_3, qsfp2_rx_rst_2, qsfp2_rx_rst_1, qsfp1_rx_rst_4, qsfp1_rx_rst_3, qsfp1_rx_rst_2, qsfp1_rx_rst_1, qsfp0_rx_rst_4, qsfp0_rx_rst_3, qsfp0_rx_rst_2, qsfp0_rx_rst_1}), + .phy_xgmii_rxd({qsfp3_rxd_4, qsfp3_rxd_3, qsfp3_rxd_2, qsfp3_rxd_1, qsfp2_rxd_4, qsfp2_rxd_3, qsfp2_rxd_2, qsfp2_rxd_1, qsfp1_rxd_4, qsfp1_rxd_3, qsfp1_rxd_2, qsfp1_rxd_1, qsfp0_rxd_4, qsfp0_rxd_3, qsfp0_rxd_2, qsfp0_rxd_1}), + .phy_xgmii_rxc({qsfp3_rxc_4, qsfp3_rxc_3, qsfp3_rxc_2, qsfp3_rxc_1, qsfp2_rxc_4, qsfp2_rxc_3, qsfp2_rxc_2, qsfp2_rxc_1, qsfp1_rxc_4, qsfp1_rxc_3, qsfp1_rxc_2, qsfp1_rxc_1, qsfp0_rxc_4, qsfp0_rxc_3, qsfp0_rxc_2, qsfp0_rxc_1}), + + // towards MAC + .port_xgmii_tx_clk(port_xgmii_tx_clk), + .port_xgmii_tx_rst(port_xgmii_tx_rst), + .port_xgmii_txd(port_xgmii_txd), + .port_xgmii_txc(port_xgmii_txc), + + .port_xgmii_rx_clk(port_xgmii_rx_clk), + .port_xgmii_rx_rst(port_xgmii_rx_rst), + .port_xgmii_rxd(port_xgmii_rxd), + .port_xgmii_rxc(port_xgmii_rxc) +); + +generate + genvar n; + + for (n = 0; n < PORT_COUNT; n = n + 1) begin : mac + + assign eth_tx_clk[n] = port_xgmii_tx_clk[n]; + assign eth_tx_rst[n] = port_xgmii_tx_rst[n]; + assign eth_rx_clk[n] = port_xgmii_rx_clk[n]; + assign eth_rx_rst[n] = port_xgmii_rx_rst[n]; + + eth_mac_10g #( + .DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .ENABLE_DIC(ENABLE_DIC), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_PERIOD_NS(IF_PTP_PERIOD_NS), + .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), + .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), + .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + ) + eth_mac_inst ( + .tx_clk(port_xgmii_tx_clk[n]), + .tx_rst(port_xgmii_tx_rst[n]), + .rx_clk(port_xgmii_rx_clk[n]), + .rx_rst(port_xgmii_rx_rst[n]), + + .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), + .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), + .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), + .tx_axis_tready(axis_eth_tx_tready[n +: 1]), + .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), + .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + + .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), + .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), + .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), + .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), + .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + + .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), + .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), + .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + + .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), + .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), + .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), + .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*PTP_TAG_WIDTH +: PTP_TAG_WIDTH]), + .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + + .tx_error_underflow(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + + .ifg_delay(8'd12) + ); + + end + +endgenerate + +mqnic_core_pcie_us #( + // FW and board IDs + .FPGA_ID(FPGA_ID), + .FW_ID(FW_ID), + .FW_VER(FW_VER), + .BOARD_ID(BOARD_ID), + .BOARD_VER(BOARD_VER), + .BUILD_DATE(BUILD_DATE), + .GIT_HASH(GIT_HASH), + .RELEASE_INFO(RELEASE_INFO), + + // Structural configuration + .IF_COUNT(IF_COUNT), + .PORTS_PER_IF(PORTS_PER_IF), + .SCHED_PER_IF(SCHED_PER_IF), + + .PORT_COUNT(PORT_COUNT), + + // PTP configuration + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TAG_WIDTH(PTP_TAG_WIDTH), + .PTP_PERIOD_NS_WIDTH(PTP_PERIOD_NS_WIDTH), + .PTP_OFFSET_NS_WIDTH(PTP_OFFSET_NS_WIDTH), + .PTP_FNS_WIDTH(PTP_FNS_WIDTH), + .PTP_PERIOD_NS(PTP_PERIOD_NS), + .PTP_PERIOD_FNS(PTP_PERIOD_FNS), + .PTP_CLOCK_PIPELINE(PTP_CLOCK_PIPELINE), + .PTP_USE_SAMPLE_CLOCK(PTP_USE_SAMPLE_CLOCK), + .PTP_SEPARATE_RX_CLOCK(0), + .PTP_PORT_CDC_PIPELINE(PTP_PORT_CDC_PIPELINE), + .PTP_PEROUT_ENABLE(PTP_PEROUT_ENABLE), + .PTP_PEROUT_COUNT(PTP_PEROUT_COUNT), + + // Queue manager configuration (interface) + .EVENT_QUEUE_OP_TABLE_SIZE(EVENT_QUEUE_OP_TABLE_SIZE), + .TX_QUEUE_OP_TABLE_SIZE(TX_QUEUE_OP_TABLE_SIZE), + .RX_QUEUE_OP_TABLE_SIZE(RX_QUEUE_OP_TABLE_SIZE), + .TX_CPL_QUEUE_OP_TABLE_SIZE(TX_CPL_QUEUE_OP_TABLE_SIZE), + .RX_CPL_QUEUE_OP_TABLE_SIZE(RX_CPL_QUEUE_OP_TABLE_SIZE), + .EVENT_QUEUE_INDEX_WIDTH(EVENT_QUEUE_INDEX_WIDTH), + .TX_QUEUE_INDEX_WIDTH(TX_QUEUE_INDEX_WIDTH), + .RX_QUEUE_INDEX_WIDTH(RX_QUEUE_INDEX_WIDTH), + .TX_CPL_QUEUE_INDEX_WIDTH(TX_CPL_QUEUE_INDEX_WIDTH), + .RX_CPL_QUEUE_INDEX_WIDTH(RX_CPL_QUEUE_INDEX_WIDTH), + .EVENT_QUEUE_PIPELINE(EVENT_QUEUE_PIPELINE), + .TX_QUEUE_PIPELINE(TX_QUEUE_PIPELINE), + .RX_QUEUE_PIPELINE(RX_QUEUE_PIPELINE), + .TX_CPL_QUEUE_PIPELINE(TX_CPL_QUEUE_PIPELINE), + .RX_CPL_QUEUE_PIPELINE(RX_CPL_QUEUE_PIPELINE), + + // TX and RX engine configuration (port) + .TX_DESC_TABLE_SIZE(TX_DESC_TABLE_SIZE), + .RX_DESC_TABLE_SIZE(RX_DESC_TABLE_SIZE), + + // Scheduler configuration (port) + .TX_SCHEDULER_OP_TABLE_SIZE(TX_SCHEDULER_OP_TABLE_SIZE), + .TX_SCHEDULER_PIPELINE(TX_SCHEDULER_PIPELINE), + .TDMA_INDEX_WIDTH(TDMA_INDEX_WIDTH), + + // Timestamping configuration (port) + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .TX_PTP_TS_FIFO_DEPTH(TX_PTP_TS_FIFO_DEPTH), + .RX_PTP_TS_FIFO_DEPTH(RX_PTP_TS_FIFO_DEPTH), + + // Interface configuration (port) + .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), + .RX_RSS_ENABLE(RX_RSS_ENABLE), + .RX_HASH_ENABLE(RX_HASH_ENABLE), + .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .TX_FIFO_DEPTH(TX_FIFO_DEPTH), + .RX_FIFO_DEPTH(RX_FIFO_DEPTH), + .MAX_TX_SIZE(MAX_TX_SIZE), + .MAX_RX_SIZE(MAX_RX_SIZE), + .TX_RAM_SIZE(TX_RAM_SIZE), + .RX_RAM_SIZE(RX_RAM_SIZE), + + // Application block configuration + .APP_ENABLE(APP_ENABLE), + .APP_CTRL_ENABLE(APP_CTRL_ENABLE), + .APP_DMA_ENABLE(APP_DMA_ENABLE), + .APP_AXIS_DIRECT_ENABLE(APP_AXIS_DIRECT_ENABLE), + .APP_AXIS_SYNC_ENABLE(APP_AXIS_SYNC_ENABLE), + .APP_AXIS_IF_ENABLE(APP_AXIS_IF_ENABLE), + .APP_STAT_ENABLE(APP_STAT_ENABLE), + .APP_GPIO_IN_WIDTH(32), + .APP_GPIO_OUT_WIDTH(32), + + // DMA interface configuration + .DMA_LEN_WIDTH(DMA_LEN_WIDTH), + .DMA_TAG_WIDTH(DMA_TAG_WIDTH), + .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), + .RAM_PIPELINE(RAM_PIPELINE), + + // PCIe interface configuration + .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), + .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), + .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), + .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), + .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), + .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), + .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), + .PF_COUNT(PF_COUNT), + .VF_COUNT(VF_COUNT), + .F_COUNT(F_COUNT), + .PCIE_TAG_COUNT(PCIE_TAG_COUNT), + .PCIE_DMA_READ_OP_TABLE_SIZE(PCIE_DMA_READ_OP_TABLE_SIZE), + .PCIE_DMA_READ_TX_LIMIT(PCIE_DMA_READ_TX_LIMIT), + .PCIE_DMA_READ_TX_FC_ENABLE(PCIE_DMA_READ_TX_FC_ENABLE), + .PCIE_DMA_WRITE_OP_TABLE_SIZE(PCIE_DMA_WRITE_OP_TABLE_SIZE), + .PCIE_DMA_WRITE_TX_LIMIT(PCIE_DMA_WRITE_TX_LIMIT), + .PCIE_DMA_WRITE_TX_FC_ENABLE(PCIE_DMA_WRITE_TX_FC_ENABLE), + .MSI_COUNT(MSI_COUNT), + + // AXI lite interface configuration (control) + .AXIL_CTRL_DATA_WIDTH(AXIL_CTRL_DATA_WIDTH), + .AXIL_CTRL_ADDR_WIDTH(AXIL_CTRL_ADDR_WIDTH), + .AXIL_CTRL_STRB_WIDTH(AXIL_CTRL_STRB_WIDTH), + .AXIL_IF_CTRL_ADDR_WIDTH(AXIL_IF_CTRL_ADDR_WIDTH), + .AXIL_CSR_ADDR_WIDTH(AXIL_CSR_ADDR_WIDTH), + .AXIL_CSR_PASSTHROUGH_ENABLE(1), + .RB_NEXT_PTR(RB_BASE_ADDR), + + // AXI lite interface configuration (application control) + .AXIL_APP_CTRL_DATA_WIDTH(AXIL_APP_CTRL_DATA_WIDTH), + .AXIL_APP_CTRL_ADDR_WIDTH(AXIL_APP_CTRL_ADDR_WIDTH), + + // Ethernet interface configuration + .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), + .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH), + .AXIS_ETH_SYNC_DATA_WIDTH(AXIS_ETH_SYNC_DATA_WIDTH), + .AXIS_ETH_TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), + .AXIS_ETH_RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .AXIS_ETH_RX_USE_READY(0), + .AXIS_ETH_TX_PIPELINE(AXIS_ETH_TX_PIPELINE), + .AXIS_ETH_TX_FIFO_PIPELINE(AXIS_ETH_TX_FIFO_PIPELINE), + .AXIS_ETH_TX_TS_PIPELINE(AXIS_ETH_TX_TS_PIPELINE), + .AXIS_ETH_RX_PIPELINE(AXIS_ETH_RX_PIPELINE), + .AXIS_ETH_RX_FIFO_PIPELINE(AXIS_ETH_RX_FIFO_PIPELINE), + + // Statistics counter subsystem + .STAT_ENABLE(STAT_ENABLE), + .STAT_DMA_ENABLE(STAT_DMA_ENABLE), + .STAT_PCIE_ENABLE(STAT_PCIE_ENABLE), + .STAT_INC_WIDTH(STAT_INC_WIDTH), + .STAT_ID_WIDTH(STAT_ID_WIDTH) +) +core_inst ( + .clk(clk_250mhz), + .rst(rst_250mhz), + + /* + * AXI input (RC) + */ + .s_axis_rc_tdata(s_axis_rc_tdata), + .s_axis_rc_tkeep(s_axis_rc_tkeep), + .s_axis_rc_tvalid(s_axis_rc_tvalid), + .s_axis_rc_tready(s_axis_rc_tready), + .s_axis_rc_tlast(s_axis_rc_tlast), + .s_axis_rc_tuser(s_axis_rc_tuser), + + /* + * AXI output (RQ) + */ + .m_axis_rq_tdata(m_axis_rq_tdata), + .m_axis_rq_tkeep(m_axis_rq_tkeep), + .m_axis_rq_tvalid(m_axis_rq_tvalid), + .m_axis_rq_tready(m_axis_rq_tready), + .m_axis_rq_tlast(m_axis_rq_tlast), + .m_axis_rq_tuser(m_axis_rq_tuser), + + /* + * AXI input (CQ) + */ + .s_axis_cq_tdata(s_axis_cq_tdata), + .s_axis_cq_tkeep(s_axis_cq_tkeep), + .s_axis_cq_tvalid(s_axis_cq_tvalid), + .s_axis_cq_tready(s_axis_cq_tready), + .s_axis_cq_tlast(s_axis_cq_tlast), + .s_axis_cq_tuser(s_axis_cq_tuser), + + /* + * AXI output (CC) + */ + .m_axis_cc_tdata(m_axis_cc_tdata), + .m_axis_cc_tkeep(m_axis_cc_tkeep), + .m_axis_cc_tvalid(m_axis_cc_tvalid), + .m_axis_cc_tready(m_axis_cc_tready), + .m_axis_cc_tlast(m_axis_cc_tlast), + .m_axis_cc_tuser(m_axis_cc_tuser), + + /* + * Transmit sequence number input + */ + .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), + .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), + .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), + .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), + + /* + * Flow control + */ + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + /* + * Configuration inputs + */ + .cfg_max_read_req(cfg_max_read_req), + .cfg_max_payload(cfg_max_payload), + + /* + * Configuration interface + */ + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + /* + * Interrupt interface + */ + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_vf_enable(8'd0), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * PCIe error outputs + */ + .status_error_cor(status_error_cor), + .status_error_uncor(status_error_uncor), + + /* + * AXI-Lite master interface (passthrough for NIC control and status) + */ + .m_axil_csr_awaddr(axil_csr_awaddr), + .m_axil_csr_awprot(axil_csr_awprot), + .m_axil_csr_awvalid(axil_csr_awvalid), + .m_axil_csr_awready(axil_csr_awready), + .m_axil_csr_wdata(axil_csr_wdata), + .m_axil_csr_wstrb(axil_csr_wstrb), + .m_axil_csr_wvalid(axil_csr_wvalid), + .m_axil_csr_wready(axil_csr_wready), + .m_axil_csr_bresp(axil_csr_bresp), + .m_axil_csr_bvalid(axil_csr_bvalid), + .m_axil_csr_bready(axil_csr_bready), + .m_axil_csr_araddr(axil_csr_araddr), + .m_axil_csr_arprot(axil_csr_arprot), + .m_axil_csr_arvalid(axil_csr_arvalid), + .m_axil_csr_arready(axil_csr_arready), + .m_axil_csr_rdata(axil_csr_rdata), + .m_axil_csr_rresp(axil_csr_rresp), + .m_axil_csr_rvalid(axil_csr_rvalid), + .m_axil_csr_rready(axil_csr_rready), + + /* + * Control register interface + */ + .ctrl_reg_wr_addr(ctrl_reg_wr_addr), + .ctrl_reg_wr_data(ctrl_reg_wr_data), + .ctrl_reg_wr_strb(ctrl_reg_wr_strb), + .ctrl_reg_wr_en(ctrl_reg_wr_en), + .ctrl_reg_wr_wait(ctrl_reg_wr_wait), + .ctrl_reg_wr_ack(ctrl_reg_wr_ack), + .ctrl_reg_rd_addr(ctrl_reg_rd_addr), + .ctrl_reg_rd_en(ctrl_reg_rd_en), + .ctrl_reg_rd_data(ctrl_reg_rd_data), + .ctrl_reg_rd_wait(ctrl_reg_rd_wait), + .ctrl_reg_rd_ack(ctrl_reg_rd_ack), + + /* + * PTP clock + */ + .ptp_sample_clk(clk_250mhz), + .ptp_pps(ptp_pps), + .ptp_ts_96(ptp_ts_96), + .ptp_ts_step(ptp_ts_step), + .ptp_perout_locked(ptp_perout_locked), + .ptp_perout_error(ptp_perout_error), + .ptp_perout_pulse(ptp_perout_pulse), + + /* + * Ethernet + */ + .eth_tx_clk(eth_tx_clk), + .eth_tx_rst(eth_tx_rst), + + .eth_tx_ptp_ts_96(eth_tx_ptp_ts_96), + .eth_tx_ptp_ts_step(eth_tx_ptp_ts_step), + + .m_axis_eth_tx_tdata(axis_eth_tx_tdata), + .m_axis_eth_tx_tkeep(axis_eth_tx_tkeep), + .m_axis_eth_tx_tvalid(axis_eth_tx_tvalid), + .m_axis_eth_tx_tready(axis_eth_tx_tready), + .m_axis_eth_tx_tlast(axis_eth_tx_tlast), + .m_axis_eth_tx_tuser(axis_eth_tx_tuser), + + .s_axis_eth_tx_ptp_ts(axis_eth_tx_ptp_ts), + .s_axis_eth_tx_ptp_ts_tag(axis_eth_tx_ptp_ts_tag), + .s_axis_eth_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), + .s_axis_eth_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + + .eth_rx_clk(eth_rx_clk), + .eth_rx_rst(eth_rx_rst), + + .eth_rx_ptp_clk(0), + .eth_rx_ptp_rst(0), + .eth_rx_ptp_ts_96(eth_rx_ptp_ts_96), + .eth_rx_ptp_ts_step(eth_rx_ptp_ts_step), + + .s_axis_eth_rx_tdata(axis_eth_rx_tdata), + .s_axis_eth_rx_tkeep(axis_eth_rx_tkeep), + .s_axis_eth_rx_tvalid(axis_eth_rx_tvalid), + .s_axis_eth_rx_tready(axis_eth_rx_tready), + .s_axis_eth_rx_tlast(axis_eth_rx_tlast), + .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + + /* + * Statistics input + */ + .s_axis_stat_tdata(0), + .s_axis_stat_tid(0), + .s_axis_stat_tvalid(1'b0), + .s_axis_stat_tready(), + + /* + * GPIO + */ + .app_gpio_in(0), + .app_gpio_out(), + + /* + * JTAG + */ + .app_jtag_tdi(1'b0), + .app_jtag_tdo(), + .app_jtag_tms(1'b0), + .app_jtag_tck(1'b0) +); + +endmodule + +`resetall diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/sync_signal.v b/fpga/mqnic/XUPP3R/fpga_25g/rtl/sync_signal.v new file mode 100644 index 000000000..74b855fa1 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/sync_signal.v @@ -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 diff --git a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile new file mode 100644 index 000000000..7266cf492 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile @@ -0,0 +1,426 @@ +# 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_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_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 ?= 4 +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_CLOCK_PIPELINE ?= 0 +export PARAM_PTP_USE_SAMPLE_CLOCK ?= 0 +export PARAM_PTP_PORT_CDC_PIPELINE ?= 0 +export PARAM_PTP_PEROUT_ENABLE ?= 0 +export PARAM_PTP_PEROUT_COUNT ?= 1 + +# Queue manager configuration (interface) +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 (port) +export PARAM_TX_DESC_TABLE_SIZE ?= 32 +export PARAM_RX_DESC_TABLE_SIZE ?= 32 + +# Scheduler configuration (port) +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 + +# Timestamping configuration (port) +export PARAM_PTP_TS_ENABLE ?= 1 +export PARAM_TX_PTP_TS_FIFO_DEPTH ?= 32 +export PARAM_RX_PTP_TS_FIFO_DEPTH ?= 32 + +# Interface configuration (port) +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_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_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 ?= 512 +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 ?= 25 + +# 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 ?= 25 + +# Ethernet interface configuration +export PARAM_AXIS_ETH_TX_PIPELINE ?= 4 +export PARAM_AXIS_ETH_TX_FIFO_PIPELINE ?= 4 +export PARAM_AXIS_ETH_TX_TS_PIPELINE ?= 4 +export PARAM_AXIS_ETH_RX_PIPELINE ?= 4 +export PARAM_AXIS_ETH_RX_FIFO_PIPELINE ?= 4 + +# 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_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_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_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) + COMPILE_ARGS += -P $(TOPLEVEL).RX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_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_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_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_CLOCK_PIPELINE=$(PARAM_PTP_CLOCK_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_PTP_TS_FIFO_DEPTH=$(PARAM_TX_PTP_TS_FIFO_DEPTH) + COMPILE_ARGS += -GRX_PTP_TS_FIFO_DEPTH=$(PARAM_RX_PTP_TS_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_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_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 diff --git a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/mqnic.py b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..cfb943e57 --- /dev/null +++ b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,927 @@ +""" + +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=16, + 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) + + # Ethernet + cocotb.start_soon(Clock(dut.qsfp0_rx_clk_1, 2.56, units="ns").start()) + self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) + cocotb.start_soon(Clock(dut.qsfp0_tx_clk_1, 2.56, units="ns").start()) + self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) + + cocotb.start_soon(Clock(dut.qsfp0_rx_clk_2, 2.56, units="ns").start()) + self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) + cocotb.start_soon(Clock(dut.qsfp0_tx_clk_2, 2.56, units="ns").start()) + self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) + + cocotb.start_soon(Clock(dut.qsfp0_rx_clk_3, 2.56, units="ns").start()) + self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) + cocotb.start_soon(Clock(dut.qsfp0_tx_clk_3, 2.56, units="ns").start()) + self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) + + cocotb.start_soon(Clock(dut.qsfp0_rx_clk_4, 2.56, units="ns").start()) + self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) + cocotb.start_soon(Clock(dut.qsfp0_tx_clk_4, 2.56, units="ns").start()) + self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) + + cocotb.start_soon(Clock(dut.qsfp1_rx_clk_1, 2.56, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.start_soon(Clock(dut.qsfp1_tx_clk_1, 2.56, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.start_soon(Clock(dut.qsfp1_rx_clk_2, 2.56, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.start_soon(Clock(dut.qsfp1_tx_clk_2, 2.56, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.start_soon(Clock(dut.qsfp1_rx_clk_3, 2.56, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.start_soon(Clock(dut.qsfp1_tx_clk_3, 2.56, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.start_soon(Clock(dut.qsfp1_rx_clk_4, 2.56, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.start_soon(Clock(dut.qsfp1_tx_clk_4, 2.56, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + cocotb.start_soon(Clock(dut.qsfp2_rx_clk_1, 2.56, units="ns").start()) + self.qsfp2_1_source = XgmiiSource(dut.qsfp2_rxd_1, dut.qsfp2_rxc_1, dut.qsfp2_rx_clk_1, dut.qsfp2_rx_rst_1) + cocotb.start_soon(Clock(dut.qsfp2_tx_clk_1, 2.56, units="ns").start()) + self.qsfp2_1_sink = XgmiiSink(dut.qsfp2_txd_1, dut.qsfp2_txc_1, dut.qsfp2_tx_clk_1, dut.qsfp2_tx_rst_1) + + cocotb.start_soon(Clock(dut.qsfp2_rx_clk_2, 2.56, units="ns").start()) + self.qsfp2_2_source = XgmiiSource(dut.qsfp2_rxd_2, dut.qsfp2_rxc_2, dut.qsfp2_rx_clk_2, dut.qsfp2_rx_rst_2) + cocotb.start_soon(Clock(dut.qsfp2_tx_clk_2, 2.56, units="ns").start()) + self.qsfp2_2_sink = XgmiiSink(dut.qsfp2_txd_2, dut.qsfp2_txc_2, dut.qsfp2_tx_clk_2, dut.qsfp2_tx_rst_2) + + cocotb.start_soon(Clock(dut.qsfp2_rx_clk_3, 2.56, units="ns").start()) + self.qsfp2_3_source = XgmiiSource(dut.qsfp2_rxd_3, dut.qsfp2_rxc_3, dut.qsfp2_rx_clk_3, dut.qsfp2_rx_rst_3) + cocotb.start_soon(Clock(dut.qsfp2_tx_clk_3, 2.56, units="ns").start()) + self.qsfp2_3_sink = XgmiiSink(dut.qsfp2_txd_3, dut.qsfp2_txc_3, dut.qsfp2_tx_clk_3, dut.qsfp2_tx_rst_3) + + cocotb.start_soon(Clock(dut.qsfp2_rx_clk_4, 2.56, units="ns").start()) + self.qsfp2_4_source = XgmiiSource(dut.qsfp2_rxd_4, dut.qsfp2_rxc_4, dut.qsfp2_rx_clk_4, dut.qsfp2_rx_rst_4) + cocotb.start_soon(Clock(dut.qsfp2_tx_clk_4, 2.56, units="ns").start()) + self.qsfp2_4_sink = XgmiiSink(dut.qsfp2_txd_4, dut.qsfp2_txc_4, dut.qsfp2_tx_clk_4, dut.qsfp2_tx_rst_4) + + cocotb.start_soon(Clock(dut.qsfp3_rx_clk_1, 2.56, units="ns").start()) + self.qsfp3_1_source = XgmiiSource(dut.qsfp3_rxd_1, dut.qsfp3_rxc_1, dut.qsfp3_rx_clk_1, dut.qsfp3_rx_rst_1) + cocotb.start_soon(Clock(dut.qsfp3_tx_clk_1, 2.56, units="ns").start()) + self.qsfp3_1_sink = XgmiiSink(dut.qsfp3_txd_1, dut.qsfp3_txc_1, dut.qsfp3_tx_clk_1, dut.qsfp3_tx_rst_1) + + cocotb.start_soon(Clock(dut.qsfp3_rx_clk_2, 2.56, units="ns").start()) + self.qsfp3_2_source = XgmiiSource(dut.qsfp3_rxd_2, dut.qsfp3_rxc_2, dut.qsfp3_rx_clk_2, dut.qsfp3_rx_rst_2) + cocotb.start_soon(Clock(dut.qsfp3_tx_clk_2, 2.56, units="ns").start()) + self.qsfp3_2_sink = XgmiiSink(dut.qsfp3_txd_2, dut.qsfp3_txc_2, dut.qsfp3_tx_clk_2, dut.qsfp3_tx_rst_2) + + cocotb.start_soon(Clock(dut.qsfp3_rx_clk_3, 2.56, units="ns").start()) + self.qsfp3_3_source = XgmiiSource(dut.qsfp3_rxd_3, dut.qsfp3_rxc_3, dut.qsfp3_rx_clk_3, dut.qsfp3_rx_rst_3) + cocotb.start_soon(Clock(dut.qsfp3_tx_clk_3, 2.56, units="ns").start()) + self.qsfp3_3_sink = XgmiiSink(dut.qsfp3_txd_3, dut.qsfp3_txc_3, dut.qsfp3_tx_clk_3, dut.qsfp3_tx_rst_3) + + cocotb.start_soon(Clock(dut.qsfp3_rx_clk_4, 2.56, units="ns").start()) + self.qsfp3_4_source = XgmiiSource(dut.qsfp3_rxd_4, dut.qsfp3_rxc_4, dut.qsfp3_rx_clk_4, dut.qsfp3_rx_rst_4) + cocotb.start_soon(Clock(dut.qsfp3_tx_clk_4, 2.56, units="ns").start()) + self.qsfp3_4_sink = XgmiiSink(dut.qsfp3_txd_4, dut.qsfp3_txc_4, dut.qsfp3_tx_clk_4, dut.qsfp3_tx_rst_4) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + cocotb.start_soon(Clock(dut.qsfp0_drp_clk, 8, units="ns").start()) + dut.qsfp0_drp_rst.setimmediatevalue(0) + dut.qsfp0_drp_do.setimmediatevalue(0) + dut.qsfp0_drp_rdy.setimmediatevalue(0) + + dut.qsfp0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp0_rx_error_count_3.setimmediatevalue(0) + dut.qsfp0_rx_error_count_4.setimmediatevalue(0) + + cocotb.start_soon(Clock(dut.qsfp1_drp_clk, 8, units="ns").start()) + dut.qsfp1_drp_rst.setimmediatevalue(0) + dut.qsfp1_drp_do.setimmediatevalue(0) + dut.qsfp1_drp_rdy.setimmediatevalue(0) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + cocotb.start_soon(Clock(dut.qsfp2_drp_clk, 8, units="ns").start()) + dut.qsfp2_drp_rst.setimmediatevalue(0) + dut.qsfp2_drp_do.setimmediatevalue(0) + dut.qsfp2_drp_rdy.setimmediatevalue(0) + + dut.qsfp2_rx_error_count_1.setimmediatevalue(0) + dut.qsfp2_rx_error_count_2.setimmediatevalue(0) + dut.qsfp2_rx_error_count_3.setimmediatevalue(0) + dut.qsfp2_rx_error_count_4.setimmediatevalue(0) + + cocotb.start_soon(Clock(dut.qsfp3_drp_clk, 8, units="ns").start()) + dut.qsfp3_drp_rst.setimmediatevalue(0) + dut.qsfp3_drp_do.setimmediatevalue(0) + dut.qsfp3_drp_rdy.setimmediatevalue(0) + + dut.qsfp3_rx_error_count_1.setimmediatevalue(0) + dut.qsfp3_rx_error_count_2.setimmediatevalue(0) + dut.qsfp3_rx_error_count_3.setimmediatevalue(0) + dut.qsfp3_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp0_i2c_scl_i.setimmediatevalue(1) + dut.qsfp0_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qsfp1_i2c_scl_i.setimmediatevalue(1) + dut.qsfp1_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp2_modprsl.setimmediatevalue(0) + dut.qsfp2_intl.setimmediatevalue(1) + + dut.qsfp2_i2c_scl_i.setimmediatevalue(1) + dut.qsfp2_i2c_sda_i.setimmediatevalue(1) + + dut.qsfp3_modprsl.setimmediatevalue(0) + dut.qsfp3_intl.setimmediatevalue(1) + + dut.qsfp3_i2c_scl_i.setimmediatevalue(1) + dut.qsfp3_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.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp3_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp3_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp3_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp3_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp3_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp3_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp3_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp3_tx_rst_4.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.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp3_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp3_tx_rst_4.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.qsfp0_1_sink.empty(): + await self.qsfp0_1_source.send(await self.qsfp0_1_sink.recv()) + if not self.qsfp0_2_sink.empty(): + await self.qsfp0_2_source.send(await self.qsfp0_2_sink.recv()) + if not self.qsfp0_3_sink.empty(): + await self.qsfp0_3_source.send(await self.qsfp0_3_sink.recv()) + if not self.qsfp0_4_sink.empty(): + await self.qsfp0_4_source.send(await self.qsfp0_4_sink.recv()) + if not self.qsfp1_1_sink.empty(): + await self.qsfp1_1_source.send(await self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + await self.qsfp1_2_source.send(await self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + await self.qsfp1_3_source.send(await self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + await self.qsfp1_4_source.send(await self.qsfp1_4_sink.recv()) + if not self.qsfp2_1_sink.empty(): + await self.qsfp2_1_source.send(await self.qsfp2_1_sink.recv()) + if not self.qsfp2_2_sink.empty(): + await self.qsfp2_2_source.send(await self.qsfp2_2_sink.recv()) + if not self.qsfp2_3_sink.empty(): + await self.qsfp2_3_source.send(await self.qsfp2_3_sink.recv()) + if not self.qsfp2_4_sink.empty(): + await self.qsfp2_4_source.send(await self.qsfp2_4_sink.recv()) + if not self.qsfp3_1_sink.empty(): + await self.qsfp3_1_source.send(await self.qsfp3_1_sink.recv()) + if not self.qsfp3_2_sink.empty(): + await self.qsfp3_2_source.send(await self.qsfp3_2_sink.recv()) + if not self.qsfp3_3_sink.empty(): + await self.qsfp3_3_source.send(await self.qsfp3_3_sink.recv()) + if not self.qsfp3_4_sink.empty(): + await self.qsfp3_4_source.send(await self.qsfp3_4_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.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + await tb.qsfp0_1_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.qsfp1_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # await tb.qsfp1_1_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.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + await tb.qsfp0_1_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("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_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_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'] = 4 + parameters['PORTS_PER_IF'] = 1 + parameters['SCHED_PER_IF'] = parameters['PORTS_PER_IF'] + parameters['PORT_MASK'] = 0 + + # PTP configuration + parameters['PTP_CLOCK_PIPELINE'] = 0 + parameters['PTP_USE_SAMPLE_CLOCK'] = 0 + parameters['PTP_PORT_CDC_PIPELINE'] = 0 + parameters['PTP_PEROUT_ENABLE'] = 0 + parameters['PTP_PEROUT_COUNT'] = 1 + + # Queue manager configuration (interface) + 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 (port) + parameters['TX_DESC_TABLE_SIZE'] = 32 + parameters['RX_DESC_TABLE_SIZE'] = 32 + + # Scheduler configuration (port) + parameters['TX_SCHEDULER_OP_TABLE_SIZE'] = parameters['TX_DESC_TABLE_SIZE'] + parameters['TX_SCHEDULER_PIPELINE'] = parameters['TX_QUEUE_PIPELINE'] + parameters['TDMA_INDEX_WIDTH'] = 6 + + # Timestamping configuration (port) + parameters['PTP_TS_ENABLE'] = 1 + parameters['TX_PTP_TS_FIFO_DEPTH'] = 32 + parameters['RX_PTP_TS_FIFO_DEPTH'] = 32 + + # Interface configuration (port) + 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_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_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'] = 512 + 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'] = 25 + + # AXI lite interface configuration (application control) + parameters['AXIL_APP_CTRL_DATA_WIDTH'] = parameters['AXIL_CTRL_DATA_WIDTH'] + parameters['AXIL_APP_CTRL_ADDR_WIDTH'] = 25 + + # Ethernet interface configuration + parameters['AXIS_ETH_TX_PIPELINE'] = 4 + parameters['AXIS_ETH_TX_FIFO_PIPELINE'] = 4 + parameters['AXIS_ETH_TX_TS_PIPELINE'] = 4 + parameters['AXIS_ETH_RX_PIPELINE'] = 4 + parameters['AXIS_ETH_RX_FIFO_PIPELINE'] = 4 + + # 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, + )