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

fpga/mqnic/KR260: Add 10G mqnic design for Kria KR260

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2023-06-02 02:05:30 -07:00
parent 2f134d1968
commit a8c60e89ac
22 changed files with 6252 additions and 0 deletions

View File

@ -39,6 +39,7 @@ Corundum currently supports devices from both Xilinx and Intel, on boards from s
* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
* Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
* Xilinx Kria KR260 (Xilinx Zynq UltraScale+ XCK26)
* Xilinx VCU108 (Xilinx Virtex UltraScale XCVU095)
* Xilinx VCU118 (Xilinx Virtex UltraScale+ XCVU9P)
* Xilinx VCU1525 (Xilinx Virtex UltraScale+ XCVU9P)

View File

@ -184,6 +184,7 @@ This section details SoC targets, which interface with CPU cores on the same dev
============ ================= ==================== ==========
Manufacturer Board FPGA Board ID
============ ================= ==================== ==========
Xilinx KR260 XCK26-2SFVC784C 0x10ee9104
Xilinx ZCU102 XCZU9EG-2FFVB1156E 0x10ee9066
Xilinx ZCU106 XCZU7EV-2FFVC1156E 0x10ee906a
============ ================= ==================== ==========
@ -193,6 +194,7 @@ This section details SoC targets, which interface with CPU cores on the same dev
================= ========= ========== =============================== =====
Board PCIe IF Network IF DDR HBM
================= ========= ========== =============================== =====
KR260 \- 1x SFP+ \- \-
ZCU102 \- 4x SFP+ 512 MB DDR4 2400 (256M x16) \-
ZCU106 Gen 3 x4 2x SFP+ 2 GB DDR4 2400 (256M x64) \-
================= ========= ========== =============================== =====
@ -202,6 +204,7 @@ This section details SoC targets, which interface with CPU cores on the same dev
================= ============ ============ ==========
Board I2C :sup:`1` MAC :sup:`2` FW update
================= ============ ============ ==========
KR260 N N N
ZCU102 Y Y :sup:`3` N
ZCU106 Y Y :sup:`3` N
================= ============ ============ ==========
@ -215,6 +218,7 @@ This section details SoC targets, which interface with CPU cores on the same dev
================= ========================= ==== ======= ==== =====
Board Design IFxP RXQ/TXQ MAC Sched
================= ========================= ==== ======= ==== =====
KR260 mqnic/fpga/fpga 1x1 32/32 10G RR
ZCU102 mqnic/fpga/fpga 2x1 32/32 10G RR
ZCU106 mqnic/fpga_zynqmp/fpga 2x1 32/32 10G RR
================= ========================= ==== ======= ==== =====

View File

@ -31,6 +31,7 @@ Corundum currently supports devices from both Xilinx and Intel, on boards from s
* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
* Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
* Xilinx Kria KR260 (Xilinx Zynq UltraScale+ XCK26)
* Xilinx VCU108 (Xilinx Virtex UltraScale XCVU095)
* Xilinx VCU118 (Xilinx Virtex UltraScale+ XCVU9P)
* Xilinx VCU1525 (Xilinx Virtex UltraScale+ XCVU9P)

View File

@ -0,0 +1,30 @@
# Corundum mqnic for KR260
## Introduction
This design targets the Xilinx KR260 FPGA board.
* FPGA: K26 SoM (xck26-sfvc784-2LV-c)
* PHY: 10G BASE-R PHY IP core and internal GTH transceiver
## Quick start for Ubuntu
### Build FPGA bitstream
Run `make app` in the `fpga` subdirectory to build the bitstream, `.xsa` file, and device tree overlay. Ensure that the Xilinx Vivado toolchain components are in PATH (source `settings64.sh` in Vivado installation directory).
### Installation
Download an Ubuntu image for the KR260 here: https://ubuntu.com/download/amd-xilinx. Write the image to an SD card with `dd`, for example:
xzcat ubuntu.img.xz | dd of=/dev/sdX
Copy files in `fpga/app` to `/lib/firmware/xilinx/mqnic` on the KR260. Also make a copy of the source repo on the KR260 from which the kernel module and userspace tools can be built.
### Build driver and userspace tools
On the KR260, run `make` in `modules/mqnic` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled. Then run `make` in `utils` to build the userspace tools.
### Testing
On the KR260, run `sudo xmutil unloadapp` to unload the FPGA, then `sudo xmutil loadapp mqnic` to load the configuration. Then, build the kernel module and userspace tools by running `make` in `modules/mqnic` and `utils`. Finally, load the kernel module with `insmod mqnic.ko`. Check `dmesg` for output from driver initialization. Run `mqnic-dump -d /dev/mqnic0` to dump the internal state.

1
fpga/mqnic/KR260/fpga/app Symbolic link
View File

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

View File

@ -0,0 +1,141 @@
###################################################################
#
# 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 %.bin %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include ../$(CONFIG)
FPGA_TOP ?= fpga
PROJECT ?= $(FPGA_TOP)
SYN_FILES_REL = $(foreach p,$(SYN_FILES),$(if $(filter /% ./%,$p),$p,../$p))
INC_FILES_REL = $(foreach p,$(INC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
XCI_FILES_REL = $(foreach p,$(XCI_FILES),$(if $(filter /% ./%,$p),$p,../$p))
IP_TCL_FILES_REL = $(foreach p,$(IP_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
CONFIG_TCL_FILES_REL = $(foreach p,$(CONFIG_TCL_FILES),$(if $(filter /% ./%,$p),$p,../$p))
ifdef XDC_FILES
XDC_FILES_REL = $(foreach p,$(XDC_FILES),$(if $(filter /% ./%,$p),$p,../$p))
else
XDC_FILES_REL = $(PROJECT).xdc
endif
###################################################################
# Main Targets
#
# all: build everything
# clean: remove output files and project files
###################################################################
all: fpga
fpga: $(PROJECT).bit
vivado: $(PROJECT).xpr
vivado $(PROJECT).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 *.bin *.ltx *.xsa program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
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) $(PROJECT)" > $@
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
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)
echo "open_project -quiet $(PROJECT).xpr" > $@
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
$(PROJECT).xpr: create_project.tcl update_config.tcl
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
# synthesis run
$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) $(CONFIG_TCL_FILES_REL)
echo "open_project $(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
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
echo "open_project $(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
echo "open_run impl_1" >> run_impl.tcl
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
vivado -nojournal -nolog -mode batch -source run_impl.tcl
# bit file
$(PROJECT).bit $(PROJECT).bin $(PROJECT).ltx $(PROJECT).xsa: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force -bin_file $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
echo "write_hw_platform -fixed -force -include_bit $(PROJECT).xsa" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bin .
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
mkdir -p rev
COUNT=100; \
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bin rev/$(PROJECT)_rev$$COUNT.bin; \
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi; \
cp -pv $(PROJECT).xsa rev/$(PROJECT)_rev$$COUNT.xsa;

View File

@ -0,0 +1,42 @@
# XDC constraints for the Xilinx KR260 board
# part: xck26-sfvc784-2LV-c
# General configuration
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
# LEDs
set_property -dict {LOC F8 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[0]}] ;# HPA14P som240_1_d13
set_property -dict {LOC E8 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[1]}] ;# HPA14N som240_1_d14
set_property -dict {LOC G8 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {sfp_led[0]}] ;# HPA13P som240_1_a12
set_property -dict {LOC F7 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {sfp_led[1]}] ;# HPA13N som240_1_a13
set_false_path -to [get_ports {led[*] sfp_led[*]}]
set_output_delay 0 [get_ports {led[*] sfp_led[*]}]
# SFP+ Interface
set_property -dict {LOC T2 } [get_ports sfp_rx_p] ;# MGTHRXP2_224 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3
set_property -dict {LOC T1 } [get_ports sfp_rx_n] ;# MGTHRXN2_224 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3
set_property -dict {LOC R4 } [get_ports sfp_tx_p] ;# MGTHTXP2_224 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3
set_property -dict {LOC R3 } [get_ports sfp_tx_n] ;# MGTHTXN2_224 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3
set_property -dict {LOC Y6 } [get_ports sfp_mgt_refclk_p] ;# MGTREFCLK0P_224 from U90
set_property -dict {LOC Y5 } [get_ports sfp_mgt_refclk_n] ;# MGTREFCLK0N_224 from U90
set_property -dict {LOC Y10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_tx_disable] ;# HDB19 som240_2_a47
set_property -dict {LOC A10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_tx_fault] ;# HDA19 som240_1_c23
set_property -dict {LOC J12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_rx_los] ;# HDA10 som240_1_a16
set_property -dict {LOC W10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_mod_abs] ;# HDB18 som240_2_a46
set_property -dict {LOC AB11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_i2c_scl] ;# HDB16 som240_2_b49
set_property -dict {LOC AC11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp_i2c_sda] ;# HDB17 som240_2_b50
# 156.25 MHz MGT reference clock
create_clock -period 6.400 -name sfp_mgt_refclk [get_ports sfp_mgt_refclk_p]
set_false_path -to [get_ports {sfp_tx_disable}]
set_output_delay 0 [get_ports {sfp_tx_disable}]
set_false_path -from [get_ports {sfp_tx_fault sfp_rx_los sfp_mod_abs}]
set_input_delay 0 [get_ports {sfp_tx_fault sfp_rx_los sfp_mod_abs}]
set_false_path -to [get_ports {sfp_i2c_sda sfp_i2c_scl}]
set_output_delay 0 [get_ports {sfp_i2c_sda sfp_i2c_scl}]
set_false_path -from [get_ports {sfp_i2c_sda sfp_i2c_scl}]
set_input_delay 0 [get_ports {sfp_i2c_sda sfp_i2c_scl}]

View File

@ -0,0 +1,160 @@
# FPGA settings
FPGA_PART = xck26-sfvc784-2LV-c
FPGA_TOP = fpga
FPGA_ARCH = zynquplus
# 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_axi.v
SYN_FILES += rtl/common/mqnic_core.v
SYN_FILES += rtl/common/mqnic_dram_if.v
SYN_FILES += rtl/common/mqnic_interface.v
SYN_FILES += rtl/common/mqnic_interface_tx.v
SYN_FILES += rtl/common/mqnic_interface_rx.v
SYN_FILES += rtl/common/mqnic_port.v
SYN_FILES += rtl/common/mqnic_port_tx.v
SYN_FILES += rtl/common/mqnic_port_rx.v
SYN_FILES += rtl/common/mqnic_egress.v
SYN_FILES += rtl/common/mqnic_ingress.v
SYN_FILES += rtl/common/mqnic_l2_egress.v
SYN_FILES += rtl/common/mqnic_l2_ingress.v
SYN_FILES += rtl/common/mqnic_rx_queue_map.v
SYN_FILES += rtl/common/mqnic_ptp.v
SYN_FILES += rtl/common/mqnic_ptp_clock.v
SYN_FILES += rtl/common/mqnic_ptp_perout.v
SYN_FILES += rtl/common/mqnic_rb_clk_info.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_dma_if_axi.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/irq_rate_limit.v
SYN_FILES += lib/pcie/rtl/dma_if_axi.v
SYN_FILES += lib/pcie/rtl/dma_if_axi_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_axi_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
# XDC files
XDC_FILES = fpga.xdc
XDC_FILES += lib/axis/syn/vivado/axis_async_fifo.tcl
XDC_FILES += lib/axis/syn/vivado/sync_reset.tcl
XDC_FILES += lib/eth/syn/vivado/ptp_clock_cdc.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_port.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_ptp_clock.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_rb_clk_info.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/zynq_ps.tcl
IP_TCL_FILES += ip/eth_xcvr_gth.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
echo "open_hw" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
APP_DIR = app
$(APP_DIR)/shell.json:
@mkdir -p $(@D)
echo '{"shell_type": "XRT_FLAT", "num_slots": "1"}' > $@
$(APP_DIR)/$(FPGA_TOP).bin: $(FPGA_TOP).bin
@mkdir -p $(@D)
cp $< $@
$(APP_DIR)/overlay.dtbo: ../ps/overlay.dtsi
@mkdir -p $(@D)
dtc -@ -O dtb -o $@ $^
.PHONY: app
app: $(APP_DIR)/$(FPGA_TOP).bin $(APP_DIR)/shell.json $(APP_DIR)/overlay.dtbo
clean::
-rm -rf $(APP_DIR)

View File

@ -0,0 +1,203 @@
# 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 0x4A49093]
set fw_id [expr 0x00000000]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9104]
set board_ver 1.0
set release_info [expr 0x00000000]
# 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]
# Board configuration
dict set params TDMA_BER_ENABLE "0"
# Structural configuration
dict set params IF_COUNT "1"
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"
# Clock configuration
dict set params CLK_PERIOD_NS_NUM "4"
dict set params CLK_PERIOD_NS_DENOM "1"
# PTP configuration
dict set params PTP_CLOCK_PIPELINE "0"
dict set params PTP_CLOCK_CDC_PIPELINE "0"
dict set params PTP_PORT_CDC_PIPELINE "0"
dict set params PTP_PEROUT_ENABLE "1"
dict set params PTP_PEROUT_COUNT "1"
# Queue manager configuration
dict set params EVENT_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_QUEUE_OP_TABLE_SIZE "32"
dict set params RX_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params TX_QUEUE_OP_TABLE_SIZE]
dict set params RX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params RX_QUEUE_OP_TABLE_SIZE]
dict set params EVENT_QUEUE_INDEX_WIDTH "2"
dict set params TX_QUEUE_INDEX_WIDTH "5"
dict set params RX_QUEUE_INDEX_WIDTH "5"
dict set params TX_CPL_QUEUE_INDEX_WIDTH [dict get $params TX_QUEUE_INDEX_WIDTH]
dict set params RX_CPL_QUEUE_INDEX_WIDTH [dict get $params RX_QUEUE_INDEX_WIDTH]
dict set params EVENT_QUEUE_PIPELINE "3"
dict set params TX_QUEUE_PIPELINE [expr 3+([dict get $params TX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params TX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params RX_QUEUE_PIPELINE [expr 3+([dict get $params RX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params RX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params TX_CPL_QUEUE_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params RX_CPL_QUEUE_PIPELINE [dict get $params RX_QUEUE_PIPELINE]
# TX and RX engine configuration
dict set params TX_DESC_TABLE_SIZE "32"
dict set params RX_DESC_TABLE_SIZE "32"
dict set params RX_INDIR_TBL_ADDR_WIDTH [expr min([dict get $params RX_QUEUE_INDEX_WIDTH], 8)]
# Scheduler configuration
dict set params TX_SCHEDULER_OP_TABLE_SIZE [dict get $params TX_DESC_TABLE_SIZE]
dict set params TX_SCHEDULER_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params TDMA_INDEX_WIDTH "6"
# Interface configuration
dict set params PTP_TS_ENABLE "1"
dict set params TX_CPL_FIFO_DEPTH "32"
dict set params TX_CHECKSUM_ENABLE "1"
dict set params RX_HASH_ENABLE "1"
dict set params RX_CHECKSUM_ENABLE "1"
dict set params TX_FIFO_DEPTH "32768"
dict set params RX_FIFO_DEPTH "32768"
dict set params MAX_TX_SIZE "9214"
dict set params MAX_RX_SIZE "9214"
dict set params TX_RAM_SIZE "32768"
dict set params RX_RAM_SIZE "32768"
# Application block configuration
dict set params APP_ID "32'h00000000"
dict set params APP_ENABLE "0"
dict set params APP_CTRL_ENABLE "1"
dict set params APP_DMA_ENABLE "1"
dict set params APP_AXIS_DIRECT_ENABLE "1"
dict set params APP_AXIS_SYNC_ENABLE "1"
dict set params APP_AXIS_IF_ENABLE "1"
dict set params APP_STAT_ENABLE "1"
# AXI DMA interface configuration
open_bd_design [get_files zynq_ps.bd]
set s_axi_dma [get_bd_intf_ports s_axi_dma]
dict set params AXI_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $s_axi_dma]
# dict set params AXI_ADDR_WIDTH [get_property CONFIG.ADDR_WIDTH $s_axi_dma]
dict set params AXI_ADDR_WIDTH 64
dict set params AXI_ID_WIDTH [get_property CONFIG.ID_WIDTH $s_axi_dma]
# DMA interface configuration
dict set params DMA_IMM_ENABLE "0"
dict set params DMA_IMM_WIDTH "32"
dict set params DMA_LEN_WIDTH "16"
dict set params DMA_TAG_WIDTH "16"
dict set params RAM_ADDR_WIDTH [expr int(ceil(log(max([dict get $params TX_RAM_SIZE], [dict get $params RX_RAM_SIZE]))/log(2)))]
dict set params RAM_PIPELINE "2"
# NOTE: Querying the BD top-level interface port (or even the ZynqMP's interface
# pin) yields 256 for the maximum burst length, instead of 16, which is
# the actually supported length (due to ZynqMP using AXI3 internally).
#dict set params AXI_DMA_MAX_BURST_LEN [get_property CONFIG.MAX_BURST_LENGTH $s_axi_dma]
dict set params AXI_DMA_MAX_BURST_LEN "16"
# AXI lite interface configuration (control)
set m_axil_ctrl [get_bd_intf_ports m_axil_ctrl]
dict set params AXIL_CTRL_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $m_axil_ctrl]
dict set params AXIL_CTRL_ADDR_WIDTH 24
# AXI lite interface configuration (application control)
set m_axil_app_ctrl [get_bd_intf_ports m_axil_app_ctrl]
dict set params AXIL_APP_CTRL_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $m_axil_app_ctrl]
dict set params AXIL_APP_CTRL_ADDR_WIDTH 24
# Interrupt configuration
set irq [get_bd_ports pl_ps_irq0]
dict set params IRQ_COUNT [get_property CONFIG.PortWidth $irq]
close_bd_design [get_bd_designs zynq_ps]
dict set params IRQ_STRETCH "10"
# Ethernet interface configuration
dict set params AXIS_ETH_TX_PIPELINE "0"
dict set params AXIS_ETH_TX_FIFO_PIPELINE "2"
dict set params AXIS_ETH_TX_TS_PIPELINE "0"
dict set params AXIS_ETH_RX_PIPELINE "0"
dict set params AXIS_ETH_RX_FIFO_PIPELINE "2"
# Statistics counter subsystem
dict set params STAT_ENABLE "1"
dict set params STAT_DMA_ENABLE "1"
dict set params STAT_AXI_ENABLE "1"
dict set params STAT_INC_WIDTH "24"
dict set params STAT_ID_WIDTH "12"
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
# set_property generic $param_list [current_fileset]
set_property generic $param_list [get_filesets sources_1]

View File

@ -0,0 +1,170 @@
# FPGA settings
FPGA_PART = xck26-sfvc784-2LV-c
FPGA_TOP = fpga
FPGA_ARCH = zynquplus
# 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_axi.v
SYN_FILES += rtl/common/mqnic_core.v
SYN_FILES += rtl/common/mqnic_dram_if.v
SYN_FILES += rtl/common/mqnic_interface.v
SYN_FILES += rtl/common/mqnic_interface_tx.v
SYN_FILES += rtl/common/mqnic_interface_rx.v
SYN_FILES += rtl/common/mqnic_port.v
SYN_FILES += rtl/common/mqnic_port_tx.v
SYN_FILES += rtl/common/mqnic_port_rx.v
SYN_FILES += rtl/common/mqnic_egress.v
SYN_FILES += rtl/common/mqnic_ingress.v
SYN_FILES += rtl/common/mqnic_l2_egress.v
SYN_FILES += rtl/common/mqnic_l2_ingress.v
SYN_FILES += rtl/common/mqnic_rx_queue_map.v
SYN_FILES += rtl/common/mqnic_ptp.v
SYN_FILES += rtl/common/mqnic_ptp_clock.v
SYN_FILES += rtl/common/mqnic_ptp_perout.v
SYN_FILES += rtl/common/mqnic_rb_clk_info.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_dma_if_axi.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 += app/dma_bench/rtl/mqnic_app_block_dma_bench.v
SYN_FILES += app/dma_bench/rtl/dma_bench.v
SYN_FILES += app/dma_bench/rtl/dram_test_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/axi_vfifo_raw.v
SYN_FILES += lib/axi/rtl/axi_vfifo_raw_rd.v
SYN_FILES += lib/axi/rtl/axi_vfifo_raw_wr.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/irq_rate_limit.v
SYN_FILES += lib/pcie/rtl/dma_if_axi.v
SYN_FILES += lib/pcie/rtl/dma_if_axi_rd.v
SYN_FILES += lib/pcie/rtl/dma_if_axi_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
# XDC files
XDC_FILES = fpga.xdc
XDC_FILES += lib/axi/syn/vivado/axi_vfifo_raw.tcl
XDC_FILES += lib/axi/syn/vivado/axi_vfifo_raw_wr.tcl
XDC_FILES += lib/axi/syn/vivado/axi_vfifo_raw_rd.tcl
XDC_FILES += lib/axis/syn/vivado/axis_async_fifo.tcl
XDC_FILES += lib/axis/syn/vivado/sync_reset.tcl
XDC_FILES += lib/eth/syn/vivado/ptp_clock_cdc.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_port.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_ptp_clock.tcl
XDC_FILES += ../../../common/syn/vivado/mqnic_rb_clk_info.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
XDC_FILES += app/dma_bench/syn/vivado/dram_test_ch.tcl
# IP
IP_TCL_FILES = ip/zynq_ps.tcl
IP_TCL_FILES += ip/eth_xcvr_gth.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit
echo "open_hw" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
APP_DIR = app
$(APP_DIR)/shell.json:
@mkdir -p $(@D)
echo '{"shell_type": "XRT_FLAT", "num_slots": "1"}' > $@
$(APP_DIR)/$(FPGA_TOP).bin: $(FPGA_TOP).bin
@mkdir -p $(@D)
cp $< $@
$(APP_DIR)/overlay.dtbo: ../ps/overlay.dtsi
@mkdir -p $(@D)
dtc -@ -O dtb -o $@ $^
.PHONY: app
app: $(APP_DIR)/$(FPGA_TOP).bin $(APP_DIR)/shell.json $(APP_DIR)/overlay.dtbo
clean::
-rm -rf $(APP_DIR)

View File

@ -0,0 +1,203 @@
# 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 0x4A49093]
set fw_id [expr 0x00000000]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9104]
set board_ver 1.0
set release_info [expr 0x00000000]
# 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]
# Board configuration
dict set params TDMA_BER_ENABLE "0"
# Structural configuration
dict set params IF_COUNT "1"
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"
# Clock configuration
dict set params CLK_PERIOD_NS_NUM "4"
dict set params CLK_PERIOD_NS_DENOM "1"
# PTP configuration
dict set params PTP_CLOCK_PIPELINE "0"
dict set params PTP_CLOCK_CDC_PIPELINE "0"
dict set params PTP_PORT_CDC_PIPELINE "0"
dict set params PTP_PEROUT_ENABLE "1"
dict set params PTP_PEROUT_COUNT "1"
# Queue manager configuration
dict set params EVENT_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_QUEUE_OP_TABLE_SIZE "32"
dict set params RX_QUEUE_OP_TABLE_SIZE "32"
dict set params TX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params TX_QUEUE_OP_TABLE_SIZE]
dict set params RX_CPL_QUEUE_OP_TABLE_SIZE [dict get $params RX_QUEUE_OP_TABLE_SIZE]
dict set params EVENT_QUEUE_INDEX_WIDTH "2"
dict set params TX_QUEUE_INDEX_WIDTH "5"
dict set params RX_QUEUE_INDEX_WIDTH "5"
dict set params TX_CPL_QUEUE_INDEX_WIDTH [dict get $params TX_QUEUE_INDEX_WIDTH]
dict set params RX_CPL_QUEUE_INDEX_WIDTH [dict get $params RX_QUEUE_INDEX_WIDTH]
dict set params EVENT_QUEUE_PIPELINE "3"
dict set params TX_QUEUE_PIPELINE [expr 3+([dict get $params TX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params TX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params RX_QUEUE_PIPELINE [expr 3+([dict get $params RX_QUEUE_INDEX_WIDTH] > 12 ? [dict get $params RX_QUEUE_INDEX_WIDTH]-12 : 0)]
dict set params TX_CPL_QUEUE_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params RX_CPL_QUEUE_PIPELINE [dict get $params RX_QUEUE_PIPELINE]
# TX and RX engine configuration
dict set params TX_DESC_TABLE_SIZE "32"
dict set params RX_DESC_TABLE_SIZE "32"
dict set params RX_INDIR_TBL_ADDR_WIDTH [expr min([dict get $params RX_QUEUE_INDEX_WIDTH], 8)]
# Scheduler configuration
dict set params TX_SCHEDULER_OP_TABLE_SIZE [dict get $params TX_DESC_TABLE_SIZE]
dict set params TX_SCHEDULER_PIPELINE [dict get $params TX_QUEUE_PIPELINE]
dict set params TDMA_INDEX_WIDTH "6"
# Interface configuration
dict set params PTP_TS_ENABLE "1"
dict set params TX_CPL_FIFO_DEPTH "32"
dict set params TX_CHECKSUM_ENABLE "1"
dict set params RX_HASH_ENABLE "1"
dict set params RX_CHECKSUM_ENABLE "1"
dict set params TX_FIFO_DEPTH "32768"
dict set params RX_FIFO_DEPTH "32768"
dict set params MAX_TX_SIZE "9214"
dict set params MAX_RX_SIZE "9214"
dict set params TX_RAM_SIZE "32768"
dict set params RX_RAM_SIZE "32768"
# Application block configuration
dict set params APP_ID "32'h12348001"
dict set params APP_ENABLE "1"
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"
# AXI DMA interface configuration
open_bd_design [get_files zynq_ps.bd]
set s_axi_dma [get_bd_intf_ports s_axi_dma]
dict set params AXI_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $s_axi_dma]
# dict set params AXI_ADDR_WIDTH [get_property CONFIG.ADDR_WIDTH $s_axi_dma]
dict set params AXI_ADDR_WIDTH 64
dict set params AXI_ID_WIDTH [get_property CONFIG.ID_WIDTH $s_axi_dma]
# DMA interface configuration
dict set params DMA_IMM_ENABLE "0"
dict set params DMA_IMM_WIDTH "32"
dict set params DMA_LEN_WIDTH "16"
dict set params DMA_TAG_WIDTH "16"
dict set params RAM_ADDR_WIDTH [expr int(ceil(log(max([dict get $params TX_RAM_SIZE], [dict get $params RX_RAM_SIZE]))/log(2)))]
dict set params RAM_PIPELINE "2"
# NOTE: Querying the BD top-level interface port (or even the ZynqMP's interface
# pin) yields 256 for the maximum burst length, instead of 16, which is
# the actually supported length (due to ZynqMP using AXI3 internally).
#dict set params AXI_DMA_MAX_BURST_LEN [get_property CONFIG.MAX_BURST_LENGTH $s_axi_dma]
dict set params AXI_DMA_MAX_BURST_LEN "16"
# AXI lite interface configuration (control)
set m_axil_ctrl [get_bd_intf_ports m_axil_ctrl]
dict set params AXIL_CTRL_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $m_axil_ctrl]
dict set params AXIL_CTRL_ADDR_WIDTH 24
# AXI lite interface configuration (application control)
set m_axil_app_ctrl [get_bd_intf_ports m_axil_app_ctrl]
dict set params AXIL_APP_CTRL_DATA_WIDTH [get_property CONFIG.DATA_WIDTH $m_axil_app_ctrl]
dict set params AXIL_APP_CTRL_ADDR_WIDTH 24
# Interrupt configuration
set irq [get_bd_ports pl_ps_irq0]
dict set params IRQ_COUNT [get_property CONFIG.PortWidth $irq]
close_bd_design [get_bd_designs zynq_ps]
dict set params IRQ_STRETCH "10"
# Ethernet interface configuration
dict set params AXIS_ETH_TX_PIPELINE "0"
dict set params AXIS_ETH_TX_FIFO_PIPELINE "2"
dict set params AXIS_ETH_TX_TS_PIPELINE "0"
dict set params AXIS_ETH_RX_PIPELINE "0"
dict set params AXIS_ETH_RX_FIFO_PIPELINE "2"
# Statistics counter subsystem
dict set params STAT_ENABLE "1"
dict set params STAT_DMA_ENABLE "1"
dict set params STAT_AXI_ENABLE "1"
dict set params STAT_INC_WIDTH "24"
dict set params STAT_ID_WIDTH "12"
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
# set_property generic $param_list [current_fileset]
set_property generic $param_list [get_filesets sources_1]

View File

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

View File

@ -0,0 +1,356 @@
# 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.
# create block design
create_bd_design "zynq_ps"
# Create blocks
# Zynq PS
set zynq_ultra_ps [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e zynq_ultra_ps ]
set_property -dict [list \
CONFIG.PSU__PRESET_APPLIED {1} \
CONFIG.PSU_BANK_0_IO_STANDARD {LVCMOS18} \
CONFIG.PSU_BANK_1_IO_STANDARD {LVCMOS18} \
CONFIG.PSU_BANK_2_IO_STANDARD {LVCMOS18} \
CONFIG.PSU_BANK_3_IO_STANDARD {LVCMOS18} \
CONFIG.PSU__GPIO0_MIO__IO {MIO 0 .. 25} \
CONFIG.PSU__GPIO0_MIO__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__GPIO1_MIO__IO {MIO 26 .. 51} \
CONFIG.PSU__GPIO1_MIO__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__QSPI__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__QSPI__PERIPHERAL__DATA_MODE {x4} \
CONFIG.PSU__QSPI__PERIPHERAL__IO {MIO 0 .. 5} \
CONFIG.PSU__QSPI__PERIPHERAL__MODE {Single} \
CONFIG.PSU__QSPI__GRP_FBCLK__ENABLE {0} \
CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__FREQMHZ {125} \
CONFIG.PSU__SPI1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__SPI1__GRP_SS1__ENABLE {0} \
CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__FREQMHZ {200} \
CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \
CONFIG.PSU__DP__LANE_SEL {None} \
CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk1} \
CONFIG.PSU__DP__REF_CLK_FREQ {27} \
CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \
CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__FREQMHZ {300} \
CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \
CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__FREQMHZ {25} \
CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \
CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__FREQMHZ {27} \
CONFIG.PSU__USE__IRQ0 {1} \
CONFIG.PSU__USE__M_AXI_GP0 {1} \
CONFIG.PSU__USE__M_AXI_GP1 {1} \
CONFIG.PSU__USE__M_AXI_GP2 {0} \
CONFIG.PSU__PMU__GPO0__ENABLE {0} \
CONFIG.PSU__PMU__GPO1__ENABLE {0} \
CONFIG.PSU__PMU__GPO2__ENABLE {0} \
CONFIG.PSU__PMU__GPO3__ENABLE {1} \
CONFIG.PSU__PMU__GPO4__ENABLE {0} \
CONFIG.PSU__PMU__GPO5__ENABLE {0} \
CONFIG.PSU__PMU__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__PMU__GPI0__ENABLE {1} \
CONFIG.PSU__PMU__GPI1__ENABLE {0} \
CONFIG.PSU__PMU__GPI2__ENABLE {0} \
CONFIG.PSU__PMU__GPI3__ENABLE {0} \
CONFIG.PSU__PMU__GPI4__ENABLE {0} \
CONFIG.PSU__PMU__GPI5__ENABLE {1} \
CONFIG.PSU_MIO_34_DIRECTION {inout} \
CONFIG.PSU_MIO_43_DIRECTION {inout} \
CONFIG.PSU_MIO_44_DIRECTION {inout} \
CONFIG.PSU__DDRC__VREF {1} \
CONFIG.PSU__DDRC__ECC {Disabled} \
CONFIG.PSU__DDRC__BUS_WIDTH {64 Bit} \
CONFIG.PSU__DDRC__DRAM_WIDTH {16 Bits} \
CONFIG.PSU__DDRC__MEMORY_TYPE {DDR 4} \
CONFIG.PSU__DDRC__COMPONENTS {Components} \
CONFIG.PSU__DDRC__SPEED_BIN {DDR4_2400R} \
CONFIG.PSU__DDRC__DEVICE_CAPACITY {8192 MBits} \
CONFIG.PSU__DDRC__RANK_ADDR_COUNT {0} \
CONFIG.PSU__DDRC__BG_ADDR_COUNT {1} \
CONFIG.PSU__DDRC__BANK_ADDR_COUNT {2} \
CONFIG.PSU__DDRC__ROW_ADDR_COUNT {16} \
CONFIG.PSU__DDRC__COL_ADDR_COUNT {10} \
CONFIG.PSU__DDRC__CL {16} \
CONFIG.PSU__DDRC__CWL {14} \
CONFIG.PSU__DDRC__T_RCD {16} \
CONFIG.PSU__DDRC__T_RP {16} \
CONFIG.PSU__DDRC__T_RC {47.06} \
CONFIG.PSU__DDRC__T_RAS_MIN {33} \
CONFIG.PSU__DDRC__T_FAW {30.0} \
CONFIG.PSU__DDRC__DDR4_T_REF_MODE {0} \
CONFIG.PSU__DDRC__DDR4_T_REF_RANGE {Normal (0-85)} \
CONFIG.PSU__DDRC__PHY_DBI_MODE {0} \
CONFIG.PSU__DDRC__PARITY_ENABLE {0} \
CONFIG.PSU__DDRC__CLOCK_STOP_EN {0} \
CONFIG.PSU__DDRC__DDR4_CAL_MODE_ENABLE {0} \
CONFIG.PSU__DDRC__DDR4_CRC_CONTROL {0} \
CONFIG.PSU__DDRC__TRAIN_DATA_EYE {1} \
CONFIG.PSU__DDRC__TRAIN_READ_GATE {1} \
CONFIG.PSU__DDRC__TRAIN_WRITE_LEVEL {1} \
CONFIG.PSU__DDRC__DDR4_ADDR_MAPPING {0} \
CONFIG.PSU__DDRC__BRC_MAPPING {ROW_BANK_COL} \
CONFIG.PSU__DDRC__DM_DBI {DM_NO_DBI} \
CONFIG.PSU__DDRC__PER_BANK_REFRESH {0} \
CONFIG.PSU__DDRC__FGRM {1X} \
CONFIG.PSU__DDRC__LP_ASR {manual normal} \
CONFIG.PSU__DDRC__DIMM_ADDR_MIRROR {0} \
CONFIG.PSU__DDRC__STATIC_RD_MODE {0} \
CONFIG.PSU__DDRC__SELF_REF_ABORT {0} \
CONFIG.PSU__PSS_REF_CLK__FREQMHZ {33.333} \
CONFIG.PSU__OVERRIDE__BASIC_CLOCK {0} \
CONFIG.PSU__CRF_APB__APLL_CTRL__SRCSEL {PSS_REF_CLK} \
CONFIG.PSU__CRF_APB__DPLL_CTRL__SRCSEL {PSS_REF_CLK} \
CONFIG.PSU__CRF_APB__VPLL_CTRL__SRCSEL {PSS_REF_CLK} \
CONFIG.PSU__CRL_APB__IOPLL_CTRL__SRCSEL {PSS_REF_CLK} \
CONFIG.PSU__CRL_APB__RPLL_CTRL__SRCSEL {PSS_REF_CLK} \
CONFIG.PSU__CRF_APB__DDR_CTRL__SRCSEL {DPLL} \
CONFIG.PSU__CRF_APB__DDR_CTRL__FREQMHZ {1200} \
CONFIG.PSU__CRL_APB__CPU_R5_CTRL__SRCSEL {RPLL} \
CONFIG.PSU__CRL_APB__CPU_R5_CTRL__FREQMHZ {533.333} \
CONFIG.PSU__CRF_APB__ACPU_CTRL__SRCSEL {APLL} \
CONFIG.PSU__CRF_APB__ACPU__FRAC_ENABLED {1} \
CONFIG.PSU__CRF_APB__ACPU_CTRL__FREQMHZ {1333.333} \
CONFIG.PSU__CRF_APB__GPU_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRF_APB__GPU_REF_CTRL__FREQMHZ {600} \
CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__SWDT1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__TTC0__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC0_SEL {APB} \
CONFIG.PSU__TTC1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC1_SEL {APB} \
CONFIG.PSU__TTC2__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC2_SEL {APB} \
CONFIG.PSU__TTC3__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC3_SEL {APB} \
CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__FREQMHZ {500} \
CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__FREQMHZ {100} \
CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__FREQMHZ {100} \
CONFIG.PSU__CRL_APB__PCAP_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__PCAP_CTRL__FREQMHZ {200} \
CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__FREQMHZ {500} \
CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__SRCSEL {APLL} \
CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__FREQMHZ {600} \
CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__SRCSEL {DPLL} \
CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__FREQMHZ {600} \
CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__SRCSEL {DPLL} \
CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__FREQMHZ {533.33} \
CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__FREQMHZ {100} \
CONFIG.PSU__I2C1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__I2C1__PERIPHERAL__IO {MIO 24 .. 25} \
CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__FREQMHZ {100} \
CONFIG.PSU__UART1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__UART1__PERIPHERAL__IO {MIO 36 .. 37} \
CONFIG.PSU__CRL_APB__UART1_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__UART1_REF_CTRL__FREQMHZ {100} \
CONFIG.PSU__ENET1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__ENET1__PERIPHERAL__IO {MIO 38 .. 49} \
CONFIG.PSU__ENET1__GRP_MDIO__ENABLE {1} \
CONFIG.PSU__ENET1__GRP_MDIO__IO {MIO 50 .. 51} \
CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__FREQMHZ {125} \
CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__FREQMHZ {250} \
CONFIG.PSU_MIO_45_PULLUPDOWN {disable} \
CONFIG.PSU_MIO_47_PULLUPDOWN {disable} \
CONFIG.PSU_MIO_49_PULLUPDOWN {disable} \
CONFIG.PSU__ENET0__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__ENET0__PERIPHERAL__IO {GT Lane0} \
CONFIG.PSU__GEM0__REF_CLK_SEL {Ref Clk0} \
CONFIG.PSU__GEM0__REF_CLK_FREQ {125} \
CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__FREQMHZ {125} \
CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \
CONFIG.PSU__DP__LANE_SEL {Single Lower} \
CONFIG.PSU__DISPLAYPORT__LANE0__ENABLE {1} \
CONFIG.PSU__DISPLAYPORT__LANE0__IO {GT Lane1} \
CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk1} \
CONFIG.PSU__DP__REF_CLK_FREQ {27} \
CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \
CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__FREQMHZ {300} \
CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \
CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__FREQMHZ {25} \
CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \
CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__FREQMHZ {27} \
CONFIG.PSU__USB0__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__USB0__PERIPHERAL__IO {MIO 52 .. 63} \
CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__FREQMHZ {250} \
CONFIG.PSU__USB3_0__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__USB3_0__PERIPHERAL__IO {GT Lane2} \
CONFIG.PSU__USB0__REF_CLK_SEL {Ref Clk2} \
CONFIG.PSU__USB0__REF_CLK_FREQ {26} \
CONFIG.PSU__USB1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__USB1__PERIPHERAL__IO {MIO 64 .. 75} \
CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__FREQMHZ {250} \
CONFIG.PSU__USB1__RESET__ENABLE {1} \
CONFIG.PSU__USB1__RESET__IO {MIO 77} \
CONFIG.PSU__USB3_1__PERIPHERAL__ENABLE {1} \
CONFIG.PSU__USB3_1__PERIPHERAL__IO {GT Lane3} \
CONFIG.PSU__USB1__REF_CLK_SEL {Ref Clk2} \
CONFIG.PSU__USB1__REF_CLK_FREQ {26} \
CONFIG.PSU__USB__RESET__MODE {Separate MIO Pin} \
CONFIG.PSU__USB0__RESET__ENABLE {1} \
CONFIG.PSU__USB0__RESET__IO {MIO 76} \
CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__SRCSEL {IOPLL} \
CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__FREQMHZ {20} \
CONFIG.PSU__USE__M_AXI_GP0 {1} \
CONFIG.PSU__MAXIGP0__DATA_WIDTH {32} \
CONFIG.PSU__USE__M_AXI_GP1 {0} \
CONFIG.PSU__USE__M_AXI_GP2 {0} \
CONFIG.PSU__USE__S_AXI_GP0 {1} \
CONFIG.PSU__USE__IRQ0 {1} \
CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {250} \
CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL}
] $zynq_ultra_ps
# control AXI interconnect
set axi_interconnect_ctrl [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect axi_interconnect_ctrl ]
# reset
set proc_sys_reset [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset proc_sys_reset ]
# Create connections
# Clock
set pl_clk0 [get_bd_pins $zynq_ultra_ps/pl_clk0]
make_bd_pins_external $pl_clk0
set_property name pl_clk0 [get_bd_ports -of_objects [get_bd_nets -of_objects $pl_clk0]]
set pl_clk0_port [get_bd_ports -of_objects [get_bd_nets -of_objects $pl_clk0]]
connect_bd_net $pl_clk0 [get_bd_pins $zynq_ultra_ps/maxihpm0_fpd_aclk]
connect_bd_net $pl_clk0 [get_bd_pins $zynq_ultra_ps/saxihpc0_fpd_aclk]
connect_bd_net $pl_clk0 [get_bd_pins $proc_sys_reset/slowest_sync_clk]
connect_bd_net $pl_clk0 [get_bd_pins $axi_interconnect_ctrl/ACLK]
connect_bd_net $pl_clk0 [get_bd_pins $axi_interconnect_ctrl/S00_ACLK]
connect_bd_net $pl_clk0 [get_bd_pins $axi_interconnect_ctrl/M00_ACLK]
connect_bd_net $pl_clk0 [get_bd_pins $axi_interconnect_ctrl/M01_ACLK]
set pl_clk0_busif [list]
# Reset
set pl_resetn0 [get_bd_pins $zynq_ultra_ps/pl_resetn0]
connect_bd_net $pl_resetn0 [get_bd_pins $proc_sys_reset/ext_reset_in]
set pl_reset [get_bd_pins $proc_sys_reset/peripheral_reset]
make_bd_pins_external $pl_reset
set_property name pl_reset [get_bd_ports -of_objects [get_bd_nets -of_objects $pl_reset]]
set interconnect_aresetn [get_bd_pins $proc_sys_reset/interconnect_aresetn]
connect_bd_net $interconnect_aresetn [get_bd_pins $axi_interconnect_ctrl/ARESETN]
connect_bd_net $interconnect_aresetn [get_bd_pins $axi_interconnect_ctrl/S00_ARESETN]
connect_bd_net $interconnect_aresetn [get_bd_pins $axi_interconnect_ctrl/M00_ARESETN]
connect_bd_net $interconnect_aresetn [get_bd_pins $axi_interconnect_ctrl/M01_ARESETN]
# MMIO
connect_bd_intf_net [get_bd_intf_pins $zynq_ultra_ps/M_AXI_HPM0_FPD] [get_bd_intf_pins $axi_interconnect_ctrl/S00_AXI]
# Control interface
set m_axil_ctrl_pin [get_bd_intf_pins $axi_interconnect_ctrl/M00_AXI]
make_bd_intf_pins_external $m_axil_ctrl_pin
set_property name m_axil_ctrl [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $m_axil_ctrl_pin]]
set m_axil_ctrl_port [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $m_axil_ctrl_pin]]
set_property -dict [list \
CONFIG.PROTOCOL AXI4LITE \
CONFIG.DATA_WIDTH 32 \
CONFIG.ADDR_WIDTH 24 \
] $m_axil_ctrl_port
lappend pl_clk0_busif $m_axil_ctrl_port
# Application control interface
set m_axil_app_ctrl_pin [get_bd_intf_pins $axi_interconnect_ctrl/M01_AXI]
make_bd_intf_pins_external $m_axil_app_ctrl_pin
set_property name m_axil_app_ctrl [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $m_axil_app_ctrl_pin]]
set m_axil_app_ctrl_port [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $m_axil_app_ctrl_pin]]
set_property -dict [list \
CONFIG.PROTOCOL AXI4LITE \
CONFIG.DATA_WIDTH 32 \
CONFIG.ADDR_WIDTH 24 \
] $m_axil_app_ctrl_port
lappend pl_clk0_busif $m_axil_app_ctrl_port
# DMA interface
set s_axi_dma_pin [get_bd_intf_pins $zynq_ultra_ps/S_AXI_HPC0_FPD]
make_bd_intf_pins_external $s_axi_dma_pin
set_property name s_axi_dma [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $s_axi_dma_pin]]
set s_axi_dma_port [get_bd_intf_ports -of_objects [get_bd_intf_nets -of_objects $s_axi_dma_pin]]
lappend pl_clk0_busif $s_axi_dma_port
# IRQ
set pl_ps_irq0 [get_bd_pins $zynq_ultra_ps/pl_ps_irq0]
make_bd_pins_external $pl_ps_irq0
set_property name pl_ps_irq0 [get_bd_ports -of_objects [get_bd_nets -of_objects $pl_ps_irq0]]
set pl_ps_irq0_port [get_bd_ports -of_objects [get_bd_nets -of_objects $pl_ps_irq0]]
set_property -dict [list \
CONFIG.PortWidth 8 \
] $pl_ps_irq0_port
# Port clock associations
set lst [list]
foreach port $pl_clk0_busif {
lappend lst [get_property name $port]
}
set_property CONFIG.ASSOCIATED_BUSIF [join $lst ":"] $pl_clk0_port
# Assign addresses
assign_bd_address -target_address_space /s_axi_dma [get_bd_addr_segs $zynq_ultra_ps/SAXIGP0/HPC0_DDR_HIGH] -force
assign_bd_address -target_address_space /s_axi_dma [get_bd_addr_segs $zynq_ultra_ps/SAXIGP0/HPC0_QSPI] -force
assign_bd_address -target_address_space /s_axi_dma [get_bd_addr_segs $zynq_ultra_ps/SAXIGP0/HPC0_DDR_LOW] -force
assign_bd_address -target_address_space /s_axi_dma [get_bd_addr_segs $zynq_ultra_ps/SAXIGP0/HPC0_LPS_OCM] -force
assign_bd_address -offset 0xA000_0000 -range 16M -target_address_space $zynq_ultra_ps/Data [get_bd_addr_segs $m_axil_ctrl_port/Reg] -force
assign_bd_address -offset 0xA800_0000 -range 16M -target_address_space $zynq_ultra_ps/Data [get_bd_addr_segs $m_axil_app_ctrl_port/Reg] -force
validate_bd_design
# Save block design
save_bd_design [current_bd_design]
close_bd_design [current_bd_design]

1
fpga/mqnic/KR260/fpga/lib Symbolic link
View File

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

View File

@ -0,0 +1,58 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&fpga_full>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
firmware-name = "fpga.bin";
};
};
fragment@1 {
target = <&amba>;
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
afi0: afi0 {
compatible = "xlnx,afi-fpga";
config-afi =
// PL-to-PS AXI
// 0: 128-bit, 1: 64-bit, 2: 32-bit
<0 0>, // AFIFM0_RDCTRL [1:0] S_AXI_HPC0_FPD
<1 0>, // AFIFM0_WRCTRL [1:0] S_AXI_HPC0_FPD
<2 0>, // AFIFM1_RDCTRL [1:0] S_AXI_HPC1_FPD
<3 0>, // AFIFM1_WRCTRL [1:0] S_AXI_HPC1_FPD
<4 0>, // AFIFM2_RDCTRL [1:0] S_AXI_HP0_FPD
<5 0>, // AFIFM2_WRCTRL [1:0] S_AXI_HP0_FPD
<6 0>, // AFIFM3_RDCTRL [1:0] S_AXI_HP1_FPD
<7 0>, // AFIFM3_WRCTRL [1:0] S_AXI_HP1_FPD
<8 0>, // AFIFM4_RDCTRL [1:0] S_AXI_HP2_FPD
<9 0>, // AFIFM4_WRCTRL [1:0] S_AXI_HP2_FPD
<10 0>, // AFIFM5_RDCTRL [1:0] S_AXI_HP3_FPD
<11 0>, // AFIFM5_WRCTRL [1:0] S_AXI_HP3_FPD
<12 0>, // AFIFM6_RDCTRL [1:0] S_AXI_LPD
<13 0>, // AFIFM6_WRCTRL [1:0] S_AXI_LPD
// PS-to-PL AXI
// 0: 32-bit, 1: 64-bit, 2: 128-bit
<14 0x000>, // FPD_SLCR [9:8] AFIFS0 M_AXI_HPM0_FPD [11:10] AFIFS1 M_AXI_HPM1_FPD
<15 0x000>; // LPD_SLCR [9:8] AFIFS2 M_AXI_HPM0_LPD
};
mqnic0: ethernet@a0000000 {
compatible = "corundum,mqnic";
reg = <0x0 0xa0000000 0x0 0x1000000>,
<0x0 0xa8000000 0x0 0x1000000>;
reg-names = "csr", "app";
interrupt-parent = <&gic>;
interrupts = <0x0 0x59 0x1>, <0x0 0x5a 0x1>, <0x0 0x5b 0x1>,
<0x0 0x5c 0x1>;
assigned-clocks = <&zynqmp_clk 71>; // PL0_REF
assigned-clock-rates = <250000000>;
resets = <&zynqmp_reset 116>; // ZYNQMP_RESET_PS_PL0
reset-names = "reset";
};
};
};
};

View File

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

View File

@ -0,0 +1,944 @@
/*
Copyright 2023, 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 MISSINGLINKELECTRONICS INC. ''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 MISSINGLINKELECTRONICS INC. 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 MissingLinkElectronics Inc.
*/
// Language: Verilog 2001
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// FW and board IDs
parameter FPGA_ID = 32'h4A49093,
parameter FW_ID = 32'h00000000,
parameter FW_VER = 32'h00_00_01_00,
parameter BOARD_ID = 32'h10ee_9104,
parameter BOARD_VER = 32'h01_00_00_00,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'hdce357bf,
parameter RELEASE_INFO = 32'h00000000,
// Board configuration
parameter TDMA_BER_ENABLE = 0,
// Structural configuration
parameter IF_COUNT = 1,
parameter PORTS_PER_IF = 1,
parameter SCHED_PER_IF = PORTS_PER_IF,
parameter PORT_MASK = 0,
// Clock configuration
parameter CLK_PERIOD_NS_NUM = 4,
parameter CLK_PERIOD_NS_DENOM = 1,
// PTP configuration
parameter PTP_CLOCK_PIPELINE = 0,
parameter PTP_CLOCK_CDC_PIPELINE = 0,
parameter PTP_PORT_CDC_PIPELINE = 0,
parameter PTP_PEROUT_ENABLE = 1,
parameter PTP_PEROUT_COUNT = 1,
// Queue manager configuration
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
parameter TX_DESC_TABLE_SIZE = 32,
parameter RX_DESC_TABLE_SIZE = 32,
parameter RX_INDIR_TBL_ADDR_WIDTH = RX_QUEUE_INDEX_WIDTH > 8 ? 8 : RX_QUEUE_INDEX_WIDTH,
// Scheduler configuration
parameter TX_SCHEDULER_OP_TABLE_SIZE = TX_DESC_TABLE_SIZE,
parameter TX_SCHEDULER_PIPELINE = TX_QUEUE_PIPELINE,
parameter TDMA_INDEX_WIDTH = 6,
// Interface configuration
parameter PTP_TS_ENABLE = 1,
parameter TX_CPL_FIFO_DEPTH = 32,
parameter TX_CHECKSUM_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_ID = 32'h00000000,
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,
// AXI interface configuration (DMA)
parameter AXI_DATA_WIDTH = 128,
parameter AXI_ADDR_WIDTH = 32,
parameter AXI_STRB_WIDTH = (AXI_DATA_WIDTH/8),
parameter AXI_ID_WIDTH = 8,
// DMA interface configuration
parameter DMA_IMM_ENABLE = 0,
parameter DMA_IMM_WIDTH = 32,
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,
parameter AXI_DMA_MAX_BURST_LEN = 256,
// Interrupts
parameter IRQ_COUNT = 32,
parameter IRQ_STRETCH = 10,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_WIDTH = 32,
parameter AXIL_CTRL_ADDR_WIDTH = 24,
parameter AXIL_CTRL_STRB_WIDTH = (AXIL_CTRL_DATA_WIDTH/8),
// AXI lite interface configuration (application control)
parameter AXIL_APP_CTRL_DATA_WIDTH = AXIL_CTRL_DATA_WIDTH,
parameter AXIL_APP_CTRL_ADDR_WIDTH = 24,
parameter AXIL_APP_CTRL_STRB_WIDTH = (AXIL_APP_CTRL_DATA_WIDTH/8),
// Ethernet interface configuration
parameter AXIS_ETH_TX_PIPELINE = 0,
parameter AXIS_ETH_TX_FIFO_PIPELINE = 2,
parameter AXIS_ETH_TX_TS_PIPELINE = 0,
parameter AXIS_ETH_RX_PIPELINE = 0,
parameter AXIS_ETH_RX_FIFO_PIPELINE = 2,
// Statistics counter subsystem
parameter STAT_ENABLE = 1,
parameter STAT_DMA_ENABLE = 1,
parameter STAT_AXI_ENABLE = 1,
parameter STAT_INC_WIDTH = 24,
parameter STAT_ID_WIDTH = 12
)
(
/*
* Clock: 125MHz LVDS
*/
input wire clk_125mhz_p,
input wire clk_125mhz_n,
/*
* GPIO
*/
output wire [1:0] led,
output wire [1:0] sfp_led,
/*
* Ethernet: SFP+
*/
input wire sfp_rx_p,
input wire sfp_rx_n,
output wire sfp_tx_p,
output wire sfp_tx_n,
input wire sfp_mgt_refclk_p,
input wire sfp_mgt_refclk_n,
output wire sfp_tx_disable,
input wire sfp_tx_fault,
input wire sfp_rx_los,
input wire sfp_mod_abs,
inout wire sfp_i2c_scl,
inout wire sfp_i2c_sda
);
// PTP configuration
parameter PTP_CLK_PERIOD_NS_NUM = 32;
parameter PTP_CLK_PERIOD_NS_DENOM = 5;
parameter PTP_TS_WIDTH = 96;
parameter PTP_USE_SAMPLE_CLOCK = 1;
parameter IF_PTP_PERIOD_NS = 6'h6;
parameter IF_PTP_PERIOD_FNS = 16'h6666;
// Interface configuration
parameter TX_TAG_WIDTH = 16;
// 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 = TX_TAG_WIDTH + 1;
parameter AXIS_ETH_RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1;
// Clock and reset
wire zynq_pl_clk;
wire zynq_pl_reset;
wire clk_156mhz_int;
wire clk_125mhz_mmcm_out;
// Internal 125 MHz clock
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = zynq_pl_reset;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
// 156.25 MHz in, 125 MHz out
// PFD range: 10 MHz to 500 MHz
// VCO range: 800 MHz to 1600 MHz
// M = 8, D = 1 sets Fvco = 1250 MHz
// Divide by 10 to get output frequency of 125 MHz
MMCME4_BASE #(
.BANDWIDTH("OPTIMIZED"),
.CLKOUT0_DIVIDE_F(10),
.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(8),
.CLKFBOUT_PHASE(0),
.DIVCLK_DIVIDE(1),
.REF_JITTER1(0.010),
.CLKIN1_PERIOD(6.4),
.STARTUP_WAIT("FALSE"),
.CLKOUT4_CASCADE("FALSE")
)
clk_mmcm_inst (
.CLKIN1(clk_156mhz_int),
.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
wire sfp_tx_fault_int;
wire sfp_rx_los_int;
wire sfp_mod_abs_int;
wire sfp_i2c_scl_i;
wire sfp_i2c_scl_o;
wire sfp_i2c_scl_t;
wire sfp_i2c_sda_i;
wire sfp_i2c_sda_o;
wire sfp_i2c_sda_t;
reg sfp_i2c_scl_o_reg;
reg sfp_i2c_scl_t_reg;
reg sfp_i2c_sda_o_reg;
reg sfp_i2c_sda_t_reg;
always @(posedge zynq_pl_clk) begin
sfp_i2c_scl_o_reg <= sfp_i2c_scl_o;
sfp_i2c_scl_t_reg <= sfp_i2c_scl_t;
sfp_i2c_sda_o_reg <= sfp_i2c_sda_o;
sfp_i2c_sda_t_reg <= sfp_i2c_sda_t;
end
sync_signal #(
.WIDTH(5),
.N(2)
)
sync_signal_inst (
.clk(zynq_pl_clk),
.in({sfp_tx_fault, sfp_rx_los, sfp_mod_abs, sfp_i2c_scl, sfp_i2c_sda}),
.out({sfp_tx_fault_int, sfp_rx_los_int, sfp_mod_abs_int, sfp_i2c_scl_i, sfp_i2c_sda_i})
);
assign sfp_i2c_scl = sfp_i2c_scl_t_reg ? 1'bz : sfp_i2c_scl_o_reg;
assign sfp_i2c_sda = sfp_i2c_sda_t_reg ? 1'bz : sfp_i2c_sda_o_reg;
// Zynq AXI MM
wire [IRQ_COUNT-1:0] irq;
wire [AXI_ID_WIDTH-1:0] axi_awid;
wire [AXI_ADDR_WIDTH-1:0] axi_awaddr;
wire [7:0] axi_awlen;
wire [2:0] axi_awsize;
wire [1:0] axi_awburst;
wire axi_awlock;
wire [3:0] axi_awcache;
wire [2:0] axi_awprot;
wire axi_awvalid;
wire axi_awready;
wire [AXI_DATA_WIDTH-1:0] axi_wdata;
wire [AXI_STRB_WIDTH-1:0] axi_wstrb;
wire axi_wlast;
wire axi_wvalid;
wire axi_wready;
wire [AXI_ID_WIDTH-1:0] axi_bid;
wire [1:0] axi_bresp;
wire axi_bvalid;
wire axi_bready;
wire [AXI_ID_WIDTH-1:0] axi_arid;
wire [AXI_ADDR_WIDTH-1:0] axi_araddr;
wire [7:0] axi_arlen;
wire [2:0] axi_arsize;
wire [1:0] axi_arburst;
wire axi_arlock;
wire [3:0] axi_arcache;
wire [2:0] axi_arprot;
wire axi_arvalid;
wire axi_arready;
wire [AXI_ID_WIDTH-1:0] axi_rid;
wire [AXI_DATA_WIDTH-1:0] axi_rdata;
wire [1:0] axi_rresp;
wire axi_rlast;
wire axi_rvalid;
wire axi_rready;
// AXI lite connections
wire [AXIL_CTRL_ADDR_WIDTH-1:0] axil_ctrl_awaddr;
wire [2:0] axil_ctrl_awprot;
wire axil_ctrl_awvalid;
wire axil_ctrl_awready;
wire [AXIL_CTRL_DATA_WIDTH-1:0] axil_ctrl_wdata;
wire [AXIL_CTRL_STRB_WIDTH-1:0] axil_ctrl_wstrb;
wire axil_ctrl_wvalid;
wire axil_ctrl_wready;
wire [1:0] axil_ctrl_bresp;
wire axil_ctrl_bvalid;
wire axil_ctrl_bready;
wire [AXIL_CTRL_ADDR_WIDTH-1:0] axil_ctrl_araddr;
wire [2:0] axil_ctrl_arprot;
wire axil_ctrl_arvalid;
wire axil_ctrl_arready;
wire [AXIL_CTRL_DATA_WIDTH-1:0] axil_ctrl_rdata;
wire [1:0] axil_ctrl_rresp;
wire axil_ctrl_rvalid;
wire axil_ctrl_rready;
wire [AXIL_APP_CTRL_ADDR_WIDTH-1:0] axil_app_ctrl_awaddr;
wire [2:0] axil_app_ctrl_awprot;
wire axil_app_ctrl_awvalid;
wire axil_app_ctrl_awready;
wire [AXIL_APP_CTRL_DATA_WIDTH-1:0] axil_app_ctrl_wdata;
wire [AXIL_APP_CTRL_STRB_WIDTH-1:0] axil_app_ctrl_wstrb;
wire axil_app_ctrl_wvalid;
wire axil_app_ctrl_wready;
wire [1:0] axil_app_ctrl_bresp;
wire axil_app_ctrl_bvalid;
wire axil_app_ctrl_bready;
wire [AXIL_APP_CTRL_ADDR_WIDTH-1:0] axil_app_ctrl_araddr;
wire [2:0] axil_app_ctrl_arprot;
wire axil_app_ctrl_arvalid;
wire axil_app_ctrl_arready;
wire [AXIL_APP_CTRL_DATA_WIDTH-1:0] axil_app_ctrl_rdata;
wire [1:0] axil_app_ctrl_rresp;
wire axil_app_ctrl_rvalid;
wire axil_app_ctrl_rready;
reg [(IRQ_COUNT*IRQ_STRETCH)-1:0] irq_stretch = {(IRQ_COUNT*IRQ_STRETCH){1'b0}};
always @(posedge zynq_pl_clk) begin
if (zynq_pl_reset) begin
irq_stretch <= {(IRQ_COUNT*IRQ_STRETCH){1'b0}};
end else begin
/* IRQ shift vector */
irq_stretch <= {irq_stretch[0 +: (IRQ_COUNT*IRQ_STRETCH)-IRQ_COUNT], irq};
end
end
reg [IRQ_COUNT-1:0] zynq_irq;
integer i, k;
always @* begin
for (k = 0; k < IRQ_COUNT; k = k + 1) begin
zynq_irq[k] = 1'b0;
for (i = 0; i < (IRQ_COUNT*IRQ_STRETCH); i = i + IRQ_COUNT) begin
zynq_irq[k] = zynq_irq[k] | irq_stretch[k + i];
end
end
end
zynq_ps zynq_ps_inst (
.pl_clk0(zynq_pl_clk),
.pl_reset(zynq_pl_reset),
.pl_ps_irq0(zynq_irq),
.m_axil_ctrl_araddr(axil_ctrl_araddr),
.m_axil_ctrl_arprot(axil_ctrl_arprot),
.m_axil_ctrl_arready(axil_ctrl_arready),
.m_axil_ctrl_arvalid(axil_ctrl_arvalid),
.m_axil_ctrl_awaddr(axil_ctrl_awaddr),
.m_axil_ctrl_awprot(axil_ctrl_awprot),
.m_axil_ctrl_awready(axil_ctrl_awready),
.m_axil_ctrl_awvalid(axil_ctrl_awvalid),
.m_axil_ctrl_bready(axil_ctrl_bready),
.m_axil_ctrl_bresp(axil_ctrl_bresp),
.m_axil_ctrl_bvalid(axil_ctrl_bvalid),
.m_axil_ctrl_rdata(axil_ctrl_rdata),
.m_axil_ctrl_rready(axil_ctrl_rready),
.m_axil_ctrl_rresp(axil_ctrl_rresp),
.m_axil_ctrl_rvalid(axil_ctrl_rvalid),
.m_axil_ctrl_wdata(axil_ctrl_wdata),
.m_axil_ctrl_wready(axil_ctrl_wready),
.m_axil_ctrl_wstrb(axil_ctrl_wstrb),
.m_axil_ctrl_wvalid(axil_ctrl_wvalid),
.m_axil_app_ctrl_araddr(axil_app_ctrl_araddr),
.m_axil_app_ctrl_arprot(axil_app_ctrl_arprot),
.m_axil_app_ctrl_arready(axil_app_ctrl_arready),
.m_axil_app_ctrl_arvalid(axil_app_ctrl_arvalid),
.m_axil_app_ctrl_awaddr(axil_app_ctrl_awaddr),
.m_axil_app_ctrl_awprot(axil_app_ctrl_awprot),
.m_axil_app_ctrl_awready(axil_app_ctrl_awready),
.m_axil_app_ctrl_awvalid(axil_app_ctrl_awvalid),
.m_axil_app_ctrl_bready(axil_app_ctrl_bready),
.m_axil_app_ctrl_bresp(axil_app_ctrl_bresp),
.m_axil_app_ctrl_bvalid(axil_app_ctrl_bvalid),
.m_axil_app_ctrl_rdata(axil_app_ctrl_rdata),
.m_axil_app_ctrl_rready(axil_app_ctrl_rready),
.m_axil_app_ctrl_rresp(axil_app_ctrl_rresp),
.m_axil_app_ctrl_rvalid(axil_app_ctrl_rvalid),
.m_axil_app_ctrl_wdata(axil_app_ctrl_wdata),
.m_axil_app_ctrl_wready(axil_app_ctrl_wready),
.m_axil_app_ctrl_wstrb(axil_app_ctrl_wstrb),
.m_axil_app_ctrl_wvalid(axil_app_ctrl_wvalid),
.s_axi_dma_araddr(axi_araddr),
.s_axi_dma_arburst(axi_arburst),
.s_axi_dma_arcache(axi_arcache),
.s_axi_dma_arid(axi_arid),
.s_axi_dma_arlen(axi_arlen),
.s_axi_dma_arlock(axi_arlock),
.s_axi_dma_arprot(axi_arprot),
.s_axi_dma_arqos({4{1'b0}}),
.s_axi_dma_arready(axi_arready),
.s_axi_dma_arsize(axi_arsize),
.s_axi_dma_aruser(1'b0),
.s_axi_dma_arvalid(axi_arvalid),
.s_axi_dma_awaddr(axi_awaddr),
.s_axi_dma_awburst(axi_awburst),
.s_axi_dma_awcache(axi_awcache),
.s_axi_dma_awid(axi_awid),
.s_axi_dma_awlen(axi_awlen),
.s_axi_dma_awlock(axi_awlock),
.s_axi_dma_awprot(axi_awprot),
.s_axi_dma_awqos({4{1'b0}}),
.s_axi_dma_awready(axi_awready),
.s_axi_dma_awsize(axi_awsize),
.s_axi_dma_awuser(1'b0),
.s_axi_dma_awvalid(axi_awvalid),
.s_axi_dma_bid(axi_bid),
.s_axi_dma_bready(axi_bready),
.s_axi_dma_bresp(axi_bresp),
.s_axi_dma_bvalid(axi_bvalid),
.s_axi_dma_rdata(axi_rdata),
.s_axi_dma_rid(axi_rid),
.s_axi_dma_rlast(axi_rlast),
.s_axi_dma_rready(axi_rready),
.s_axi_dma_rresp(axi_rresp),
.s_axi_dma_rvalid(axi_rvalid),
.s_axi_dma_wdata(axi_wdata),
.s_axi_dma_wlast(axi_wlast),
.s_axi_dma_wready(axi_wready),
.s_axi_dma_wstrb(axi_wstrb),
.s_axi_dma_wvalid(axi_wvalid)
);
// XGMII 10G PHY
wire sfp_tx_clk_int;
wire sfp_tx_rst_int;
wire [XGMII_DATA_WIDTH-1:0] sfp_txd_int;
wire [XGMII_CTRL_WIDTH-1:0] sfp_txc_int;
wire sfp_tx_prbs31_enable_int;
wire sfp_rx_clk_int;
wire sfp_rx_rst_int;
wire [XGMII_DATA_WIDTH-1:0] sfp_rxd_int;
wire [XGMII_CTRL_WIDTH-1:0] sfp_rxc_int;
wire sfp_rx_prbs31_enable_int;
wire [6:0] sfp_rx_error_count_int;
wire sfp_drp_clk = clk_125mhz_int;
wire sfp_drp_rst = rst_125mhz_int;
wire [23:0] sfp_drp_addr;
wire [15:0] sfp_drp_di;
wire sfp_drp_en;
wire sfp_drp_we;
wire [15:0] sfp_drp_do;
wire sfp_drp_rdy;
wire sfp_rx_block_lock;
wire sfp_rx_status;
wire sfp_gtpowergood;
wire sfp_mgt_refclk;
wire sfp_mgt_refclk_int;
wire sfp_mgt_refclk_bufg;
assign clk_156mhz_int = sfp_mgt_refclk_bufg;
IBUFDS_GTE4 ibufds_gte4_sfp_mgt_refclk_inst (
.I (sfp_mgt_refclk_p),
.IB (sfp_mgt_refclk_n),
.CEB (1'b0),
.O (sfp_mgt_refclk),
.ODIV2 (sfp_mgt_refclk_int)
);
BUFG_GT bufg_gt_sfp_mgt_refclk_inst (
.CE (sfp_gtpowergood),
.CEMASK (1'b1),
.CLR (1'b0),
.CLRMASK (1'b1),
.DIV (3'd0),
.I (sfp_mgt_refclk_int),
.O (sfp_mgt_refclk_bufg)
);
wire sfp_rst;
sync_reset #(
.N(4)
)
sfp_sync_reset_inst (
.clk(sfp_mgt_refclk_bufg),
.rst(rst_125mhz_int),
.out(sfp_rst)
);
eth_xcvr_phy_10g_gty_quad_wrapper #(
.COUNT(1),
.GT_GTH(1),
.PRBS31_ENABLE(1)
)
sfp_phy_quad_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(sfp_rst),
/*
* Common
*/
.xcvr_gtpowergood_out(sfp_gtpowergood),
.xcvr_ref_clk(sfp_mgt_refclk),
/*
* DRP
*/
.drp_clk(sfp_drp_clk),
.drp_rst(sfp_drp_rst),
.drp_addr(sfp_drp_addr),
.drp_di(sfp_drp_di),
.drp_en(sfp_drp_en),
.drp_we(sfp_drp_we),
.drp_do(sfp_drp_do),
.drp_rdy(sfp_drp_rdy),
/*
* Serial data
*/
.xcvr_txp({sfp_tx_p}),
.xcvr_txn({sfp_tx_n}),
.xcvr_rxp({sfp_rx_p}),
.xcvr_rxn({sfp_rx_n}),
/*
* PHY connections
*/
.phy_1_tx_clk(sfp_tx_clk_int),
.phy_1_tx_rst(sfp_tx_rst_int),
.phy_1_xgmii_txd(sfp_txd_int),
.phy_1_xgmii_txc(sfp_txc_int),
.phy_1_rx_clk(sfp_rx_clk_int),
.phy_1_rx_rst(sfp_rx_rst_int),
.phy_1_xgmii_rxd(sfp_rxd_int),
.phy_1_xgmii_rxc(sfp_rxc_int),
.phy_1_tx_bad_block(),
.phy_1_rx_error_count(sfp_rx_error_count_int),
.phy_1_rx_bad_block(),
.phy_1_rx_sequence_error(),
.phy_1_rx_block_lock(sfp_rx_block_lock),
.phy_1_rx_high_ber(),
.phy_1_rx_status(sfp_rx_status),
.phy_1_tx_prbs31_enable(sfp_tx_prbs31_enable_int),
.phy_1_rx_prbs31_enable(sfp_rx_prbs31_enable_int)
);
wire ptp_clk;
wire ptp_rst;
wire ptp_sample_clk;
assign ptp_clk = sfp_mgt_refclk_bufg;
assign ptp_rst = sfp_rst;
assign ptp_sample_clk = clk_125mhz_int;
assign sfp_led[0] = sfp_rx_status;
assign sfp_led[1] = 1'b0;
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),
// Board configuration
.TDMA_BER_ENABLE(TDMA_BER_ENABLE),
// Structural configuration
.IF_COUNT(IF_COUNT),
.PORTS_PER_IF(PORTS_PER_IF),
.SCHED_PER_IF(SCHED_PER_IF),
.PORT_MASK(PORT_MASK),
// Clock configuration
.CLK_PERIOD_NS_NUM(CLK_PERIOD_NS_NUM),
.CLK_PERIOD_NS_DENOM(CLK_PERIOD_NS_DENOM),
// PTP configuration
.PTP_CLK_PERIOD_NS_NUM(PTP_CLK_PERIOD_NS_NUM),
.PTP_CLK_PERIOD_NS_DENOM(PTP_CLK_PERIOD_NS_DENOM),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_CLOCK_PIPELINE(PTP_CLOCK_PIPELINE),
.PTP_CLOCK_CDC_PIPELINE(PTP_CLOCK_CDC_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
.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
.TX_DESC_TABLE_SIZE(TX_DESC_TABLE_SIZE),
.RX_DESC_TABLE_SIZE(RX_DESC_TABLE_SIZE),
.RX_INDIR_TBL_ADDR_WIDTH(RX_INDIR_TBL_ADDR_WIDTH),
// Scheduler configuration
.TX_SCHEDULER_OP_TABLE_SIZE(TX_SCHEDULER_OP_TABLE_SIZE),
.TX_SCHEDULER_PIPELINE(TX_SCHEDULER_PIPELINE),
.TDMA_INDEX_WIDTH(TDMA_INDEX_WIDTH),
// Interface configuration
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.TX_CPL_FIFO_DEPTH(TX_CPL_FIFO_DEPTH),
.TX_TAG_WIDTH(TX_TAG_WIDTH),
.TX_CHECKSUM_ENABLE(TX_CHECKSUM_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_ID(APP_ID),
.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),
// AXI interface configuration (DMA)
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),
.AXI_STRB_WIDTH(AXI_STRB_WIDTH),
.AXI_ID_WIDTH(AXI_ID_WIDTH),
// DMA interface configuration
.DMA_IMM_ENABLE(DMA_IMM_ENABLE),
.DMA_IMM_WIDTH(DMA_IMM_WIDTH),
.DMA_LEN_WIDTH(DMA_LEN_WIDTH),
.DMA_TAG_WIDTH(DMA_TAG_WIDTH),
.RAM_ADDR_WIDTH(RAM_ADDR_WIDTH),
.RAM_PIPELINE(RAM_PIPELINE),
.AXI_DMA_MAX_BURST_LEN(AXI_DMA_MAX_BURST_LEN),
// Interrupts
.IRQ_COUNT(IRQ_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),
// 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),
.AXIL_APP_CTRL_STRB_WIDTH(AXIL_APP_CTRL_STRB_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_AXI_ENABLE(STAT_AXI_ENABLE),
.STAT_INC_WIDTH(STAT_INC_WIDTH),
.STAT_ID_WIDTH(STAT_ID_WIDTH)
)
core_inst (
/*
* Clock: 250 MHz
* Synchronous reset
*/
.clk_250mhz(zynq_pl_clk),
.rst_250mhz(zynq_pl_reset),
/*
* PTP clock
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
/*
* GPIO
*/
.led(led),
// .sfp_led(sfp_led),
/*
* Interrupt outputs
*/
.irq(irq),
/*
* AXI master interface (DMA)
*/
.m_axi_awid(axi_awid),
.m_axi_awaddr(axi_awaddr),
.m_axi_awlen(axi_awlen),
.m_axi_awsize(axi_awsize),
.m_axi_awburst(axi_awburst),
.m_axi_awlock(axi_awlock),
.m_axi_awcache(axi_awcache),
.m_axi_awprot(axi_awprot),
.m_axi_awvalid(axi_awvalid),
.m_axi_awready(axi_awready),
.m_axi_wdata(axi_wdata),
.m_axi_wstrb(axi_wstrb),
.m_axi_wlast(axi_wlast),
.m_axi_wvalid(axi_wvalid),
.m_axi_wready(axi_wready),
.m_axi_bid(axi_bid),
.m_axi_bresp(axi_bresp),
.m_axi_bvalid(axi_bvalid),
.m_axi_bready(axi_bready),
.m_axi_arid(axi_arid),
.m_axi_araddr(axi_araddr),
.m_axi_arlen(axi_arlen),
.m_axi_arsize(axi_arsize),
.m_axi_arburst(axi_arburst),
.m_axi_arlock(axi_arlock),
.m_axi_arcache(axi_arcache),
.m_axi_arprot(axi_arprot),
.m_axi_arvalid(axi_arvalid),
.m_axi_arready(axi_arready),
.m_axi_rid(axi_rid),
.m_axi_rdata(axi_rdata),
.m_axi_rresp(axi_rresp),
.m_axi_rlast(axi_rlast),
.m_axi_rvalid(axi_rvalid),
.m_axi_rready(axi_rready),
/*
* AXI lite interface configuration (control)
*/
.s_axil_ctrl_awaddr(axil_ctrl_awaddr),
.s_axil_ctrl_awprot(axil_ctrl_awprot),
.s_axil_ctrl_awvalid(axil_ctrl_awvalid),
.s_axil_ctrl_awready(axil_ctrl_awready),
.s_axil_ctrl_wdata(axil_ctrl_wdata),
.s_axil_ctrl_wstrb(axil_ctrl_wstrb),
.s_axil_ctrl_wvalid(axil_ctrl_wvalid),
.s_axil_ctrl_wready(axil_ctrl_wready),
.s_axil_ctrl_bresp(axil_ctrl_bresp),
.s_axil_ctrl_bvalid(axil_ctrl_bvalid),
.s_axil_ctrl_bready(axil_ctrl_bready),
.s_axil_ctrl_araddr(axil_ctrl_araddr),
.s_axil_ctrl_arprot(axil_ctrl_arprot),
.s_axil_ctrl_arvalid(axil_ctrl_arvalid),
.s_axil_ctrl_arready(axil_ctrl_arready),
.s_axil_ctrl_rdata(axil_ctrl_rdata),
.s_axil_ctrl_rresp(axil_ctrl_rresp),
.s_axil_ctrl_rvalid(axil_ctrl_rvalid),
.s_axil_ctrl_rready(axil_ctrl_rready),
/*
* AXI lite interface configuration (application control)
*/
.s_axil_app_ctrl_awaddr(axil_app_ctrl_awaddr),
.s_axil_app_ctrl_awprot(axil_app_ctrl_awprot),
.s_axil_app_ctrl_awvalid(axil_app_ctrl_awvalid),
.s_axil_app_ctrl_awready(axil_app_ctrl_awready),
.s_axil_app_ctrl_wdata(axil_app_ctrl_wdata),
.s_axil_app_ctrl_wstrb(axil_app_ctrl_wstrb),
.s_axil_app_ctrl_wvalid(axil_app_ctrl_wvalid),
.s_axil_app_ctrl_wready(axil_app_ctrl_wready),
.s_axil_app_ctrl_bresp(axil_app_ctrl_bresp),
.s_axil_app_ctrl_bvalid(axil_app_ctrl_bvalid),
.s_axil_app_ctrl_bready(axil_app_ctrl_bready),
.s_axil_app_ctrl_araddr(axil_app_ctrl_araddr),
.s_axil_app_ctrl_arprot(axil_app_ctrl_arprot),
.s_axil_app_ctrl_arvalid(axil_app_ctrl_arvalid),
.s_axil_app_ctrl_arready(axil_app_ctrl_arready),
.s_axil_app_ctrl_rdata(axil_app_ctrl_rdata),
.s_axil_app_ctrl_rresp(axil_app_ctrl_rresp),
.s_axil_app_ctrl_rvalid(axil_app_ctrl_rvalid),
.s_axil_app_ctrl_rready(axil_app_ctrl_rready),
/*
* Ethernet: SFP+
*/
.sfp_tx_clk(sfp_tx_clk_int),
.sfp_tx_rst(sfp_tx_rst_int),
.sfp_txd(sfp_txd_int),
.sfp_txc(sfp_txc_int),
.sfp_tx_prbs31_enable(sfp_tx_prbs31_enable_int),
.sfp_rx_clk(sfp_rx_clk_int),
.sfp_rx_rst(sfp_rx_rst_int),
.sfp_rxd(sfp_rxd_int),
.sfp_rxc(sfp_rxc_int),
.sfp_rx_prbs31_enable(sfp_rx_prbs31_enable_int),
.sfp_rx_error_count(sfp_rx_error_count_int),
.sfp_rx_status(sfp_rx_status),
.sfp_tx_disable(sfp_tx_disable),
.sfp_tx_fault(sfp_tx_fault_int),
.sfp_rx_los(sfp_rx_los_int),
.sfp_mod_abs(sfp_mod_abs_int),
.sfp_i2c_scl_i(sfp_i2c_scl_i),
.sfp_i2c_scl_o(sfp_i2c_scl_o),
.sfp_i2c_scl_t(sfp_i2c_scl_t),
.sfp_i2c_sda_i(sfp_i2c_sda_i),
.sfp_i2c_sda_o(sfp_i2c_sda_o),
.sfp_i2c_sda_t(sfp_i2c_sda_t),
.sfp_drp_clk(sfp_drp_clk),
.sfp_drp_rst(sfp_drp_rst),
.sfp_drp_addr(sfp_drp_addr),
.sfp_drp_di(sfp_drp_di),
.sfp_drp_en(sfp_drp_en),
.sfp_drp_we(sfp_drp_we),
.sfp_drp_do(sfp_drp_do),
.sfp_drp_rdy(sfp_drp_rdy)
);
endmodule
`resetall

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,268 @@
# 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_axi.v
VERILOG_SOURCES += ../../rtl/common/mqnic_core.v
VERILOG_SOURCES += ../../rtl/common/mqnic_dram_if.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface_tx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_interface_rx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port_tx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_port_rx.v
VERILOG_SOURCES += ../../rtl/common/mqnic_egress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ingress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_l2_egress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_l2_ingress.v
VERILOG_SOURCES += ../../rtl/common/mqnic_rx_queue_map.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp_clock.v
VERILOG_SOURCES += ../../rtl/common/mqnic_ptp_perout.v
VERILOG_SOURCES += ../../rtl/common/mqnic_rb_clk_info.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_dma_if_axi.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/irq_rate_limit.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_axi.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_axi_rd.v
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_axi_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/pulse_merge.v
# module parameters
# Structural configuration
export PARAM_IF_COUNT := 1
export PARAM_PORTS_PER_IF := 1
export PARAM_SCHED_PER_IF := $(PARAM_PORTS_PER_IF)
export PARAM_PORT_MASK := 0
# Clock configuration
export PARAM_CLK_PERIOD_NS_NUM := 4
export PARAM_CLK_PERIOD_NS_DENOM := 1
# PTP configuration
export PARAM_PTP_CLK_PERIOD_NS_NUM := 32
export PARAM_PTP_CLK_PERIOD_NS_DENOM := 5
export PARAM_PTP_CLOCK_PIPELINE := 0
export PARAM_PTP_CLOCK_CDC_PIPELINE := 0
export PARAM_PTP_USE_SAMPLE_CLOCK := 1
export PARAM_PTP_PORT_CDC_PIPELINE := 0
export PARAM_PTP_PEROUT_ENABLE := 1
export PARAM_PTP_PEROUT_COUNT := 1
# Queue manager configuration
export PARAM_EVENT_QUEUE_OP_TABLE_SIZE := 32
export PARAM_TX_QUEUE_OP_TABLE_SIZE := 32
export PARAM_RX_QUEUE_OP_TABLE_SIZE := 32
export PARAM_TX_CPL_QUEUE_OP_TABLE_SIZE := $(PARAM_TX_QUEUE_OP_TABLE_SIZE)
export PARAM_RX_CPL_QUEUE_OP_TABLE_SIZE := $(PARAM_RX_QUEUE_OP_TABLE_SIZE)
export PARAM_EVENT_QUEUE_INDEX_WIDTH := 2
export PARAM_TX_QUEUE_INDEX_WIDTH := 5
export PARAM_RX_QUEUE_INDEX_WIDTH := 5
export PARAM_TX_CPL_QUEUE_INDEX_WIDTH := $(PARAM_TX_QUEUE_INDEX_WIDTH)
export PARAM_RX_CPL_QUEUE_INDEX_WIDTH := $(PARAM_RX_QUEUE_INDEX_WIDTH)
export PARAM_EVENT_QUEUE_PIPELINE := 3
export PARAM_TX_QUEUE_PIPELINE := $(shell python -c "print(3 + max($(PARAM_TX_QUEUE_INDEX_WIDTH)-12, 0))")
export PARAM_RX_QUEUE_PIPELINE := $(shell python -c "print(3 + max($(PARAM_RX_QUEUE_INDEX_WIDTH)-12, 0))")
export PARAM_TX_CPL_QUEUE_PIPELINE := $(PARAM_TX_QUEUE_PIPELINE)
export PARAM_RX_CPL_QUEUE_PIPELINE := $(PARAM_RX_QUEUE_PIPELINE)
# TX and RX engine configuration
export PARAM_TX_DESC_TABLE_SIZE := 32
export PARAM_RX_DESC_TABLE_SIZE := 32
export PARAM_RX_INDIR_TBL_ADDR_WIDTH := $(shell python -c "print(min($(PARAM_RX_QUEUE_INDEX_WIDTH), 8))")
# Scheduler configuration
export PARAM_TX_SCHEDULER_OP_TABLE_SIZE := $(PARAM_TX_DESC_TABLE_SIZE)
export PARAM_TX_SCHEDULER_PIPELINE := $(PARAM_TX_QUEUE_PIPELINE)
export PARAM_TDMA_INDEX_WIDTH := 6
# Interface configuration
export PARAM_PTP_TS_ENABLE := 1
export PARAM_TX_CPL_FIFO_DEPTH := 32
export PARAM_TX_CHECKSUM_ENABLE := 1
export PARAM_RX_HASH_ENABLE := 1
export PARAM_RX_CHECKSUM_ENABLE := 1
export PARAM_TX_FIFO_DEPTH := 32768
export PARAM_RX_FIFO_DEPTH := 32768
export PARAM_MAX_TX_SIZE := 9214
export PARAM_MAX_RX_SIZE := 9214
export PARAM_TX_RAM_SIZE := 32768
export PARAM_RX_RAM_SIZE := 32768
# Application block configuration
export PARAM_APP_ID := $(shell echo $$((0x00000000)) )
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
# AXI DMA interface configuration
export PARAM_AXI_DATA_WIDTH := 128
export PARAM_AXI_ADDR_WIDTH := 40
export PARAM_AXI_ID_WIDTH := 4
# DMA interface configuration
export PARAM_DMA_IMM_ENABLE := 0
export PARAM_DMA_IMM_WIDTH := 32
export PARAM_DMA_LEN_WIDTH := 16
export PARAM_DMA_TAG_WIDTH := 16
export PARAM_RAM_ADDR_WIDTH := $(shell python -c "print((max($(PARAM_TX_RAM_SIZE), $(PARAM_RX_RAM_SIZE))-1).bit_length())")
export PARAM_RAM_PIPELINE := 2
export PARAM_AXI_DMA_MAX_BURST_LEN := 16
# AXI lite interface configuration (control)
export PARAM_AXIL_CTRL_DATA_WIDTH := 32
export PARAM_AXIL_CTRL_ADDR_WIDTH := 24
# AXI lite interface configuration (application control)
export PARAM_AXIL_APP_CTRL_DATA_WIDTH := $(PARAM_AXIL_CTRL_DATA_WIDTH)
export PARAM_AXIL_APP_CTRL_ADDR_WIDTH := 24
# Ethernet interface configuration
export PARAM_AXIS_ETH_TX_PIPELINE := 0
export PARAM_AXIS_ETH_TX_FIFO_PIPELINE := 2
export PARAM_AXIS_ETH_TX_TS_PIPELINE := 0
export PARAM_AXIS_ETH_RX_PIPELINE := 0
export PARAM_AXIS_ETH_RX_FIFO_PIPELINE := 2
# Statistics counter subsystem
export PARAM_STAT_ENABLE := 1
export PARAM_STAT_DMA_ENABLE := 1
export PARAM_STAT_AXI_ENABLE := 1
export PARAM_STAT_INC_WIDTH := 24
export PARAM_STAT_ID_WIDTH := 12
ifeq ($(SIM), icarus)
PLUSARGS += -fst
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
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 += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,537 @@
"""
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
from cocotbext.axi import AddressSpace
from cocotbext.axi import AxiLiteMaster, AxiLiteBus
from cocotbext.axi import AxiSlave, AxiBus
from cocotbext.eth import XgmiiSource, XgmiiSink
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)
cocotb.start_soon(Clock(dut.clk_250mhz, 4, units="ns").start())
# AXI
self.address_space = AddressSpace()
self.pool = self.address_space.create_pool(0, 0x8000_0000)
self.axil_master = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_axil_ctrl"), dut.clk_250mhz, dut.rst_250mhz)
self.address_space.register_region(self.axil_master, 0x10_0000_0000)
self.hw_regs = self.address_space.create_window(0x10_0000_0000, self.axil_master.size)
self.axi_slave = AxiSlave(AxiBus.from_prefix(dut, "m_axi"), dut.clk_250mhz, dut.rst_250mhz, self.address_space)
self.driver = mqnic.Driver()
cocotb.start_soon(Clock(dut.ptp_clk, 6.4, units="ns").start())
dut.ptp_rst.setimmediatevalue(0)
cocotb.start_soon(Clock(dut.ptp_sample_clk, 8, units="ns").start())
# Ethernet
cocotb.start_soon(Clock(dut.sfp_rx_clk, 6.4, units="ns").start())
self.sfp_source = XgmiiSource(dut.sfp_rxd, dut.sfp_rxc, dut.sfp_rx_clk, dut.sfp_rx_rst)
cocotb.start_soon(Clock(dut.sfp_tx_clk, 6.4, units="ns").start())
self.sfp_sink = XgmiiSink(dut.sfp_txd, dut.sfp_txc, dut.sfp_tx_clk, dut.sfp_tx_rst)
dut.sfp_rx_status.setimmediatevalue(1)
dut.sfp_tx_fault.setimmediatevalue(0)
dut.sfp_rx_los.setimmediatevalue(0)
dut.sfp_mod_abs.setimmediatevalue(0)
dut.sfp_i2c_scl_i.setimmediatevalue(1)
dut.sfp_i2c_sda_i.setimmediatevalue(1)
cocotb.start_soon(Clock(dut.sfp_drp_clk, 8, units="ns").start())
dut.sfp_drp_rst.setimmediatevalue(0)
dut.sfp_drp_do.setimmediatevalue(0)
dut.sfp_drp_rdy.setimmediatevalue(0)
dut.sfp_rx_error_count.setimmediatevalue(0)
self.loopback_enable = False
cocotb.start_soon(self._run_loopback())
async def init(self):
self.dut.rst_250mhz.setimmediatevalue(0)
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.sfp_rx_rst.setimmediatevalue(0)
self.dut.sfp_tx_rst.setimmediatevalue(0)
await RisingEdge(self.dut.clk_250mhz)
await RisingEdge(self.dut.clk_250mhz)
self.dut.rst_250mhz.value = 1
self.dut.ptp_rst.setimmediatevalue(1)
self.dut.sfp_rx_rst.setimmediatevalue(1)
self.dut.sfp_tx_rst.setimmediatevalue(1)
await RisingEdge(self.dut.clk_250mhz)
await RisingEdge(self.dut.clk_250mhz)
self.dut.rst_250mhz.value = 0
self.dut.ptp_rst.setimmediatevalue(0)
self.dut.sfp_rx_rst.setimmediatevalue(0)
self.dut.sfp_tx_rst.setimmediatevalue(0)
async def _run_loopback(self):
while True:
await RisingEdge(self.dut.clk_250mhz)
if self.loopback_enable:
if not self.sfp_sink.empty():
await self.sfp_source.send(await self.sfp_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_axi_dev(tb.pool, tb.hw_regs, irq=dut.irq)
await tb.driver.interfaces[0].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(len(tb.driver.interfaces[0].txq)):
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.sfp_sink.recv()
tb.log.info("Packet: %s", pkt)
await tb.sfp_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
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.sfp_sink.recv()
tb.log.info("Packet: %s", pkt)
await tb.sfp_source.send(pkt)
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
assert Ether(pkt.data).build() == test_pkt.build()
tb.log.info("Queue mapping offset test")
data = bytearray([x % 256 for x in range(1024)])
tb.loopback_enable = True
for k in range(4):
await tb.driver.interfaces[0].set_rx_queue_map_indir_table(0, 0, k)
await tb.driver.interfaces[0].start_xmit(data, 0)
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
assert pkt.queue == k
tb.loopback_enable = False
await tb.driver.interfaces[0].set_rx_queue_map_indir_table(0, 0, 0)
tb.log.info("Queue mapping RSS mask test")
await tb.driver.interfaces[0].set_rx_queue_map_rss_mask(0, 0x00000003)
for k in range(4):
await tb.driver.interfaces[0].set_rx_queue_map_indir_table(0, k, k)
tb.loopback_enable = True
queues = set()
for k in range(64):
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
ip = IP(src='192.168.1.100', dst='192.168.1.101')
udp = UDP(sport=1, dport=k+0)
test_pkt = eth / ip / udp / payload
test_pkt2 = test_pkt.copy()
test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP]))
await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6)
for k in range(64):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
queues.add(pkt.queue)
assert len(queues) == 4
tb.loopback_enable = False
await tb.driver.interfaces[0].set_rx_queue_map_rss_mask(0, 0)
tb.log.info("Multiple small packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await tb.driver.interfaces[0].start_xmit(p, 0)
for k in range(count):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.data == pkts[k]
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
tb.loopback_enable = False
tb.log.info("Multiple large packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await tb.driver.interfaces[0].start_xmit(p, 0)
for k in range(count):
pkt = await tb.driver.interfaces[0].recv()
tb.log.info("Packet: %s", pkt)
assert pkt.data == pkts[k]
assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff
tb.loopback_enable = False
await RisingEdge(dut.clk_250mhz)
await RisingEdge(dut.clk_250mhz)
# cocotb-test
tests_dir = os.path.dirname(__file__)
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
app_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'app'))
axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl'))
pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl'))
def test_fpga_core(request):
dut = "fpga_core"
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = dut
verilog_sources = [
os.path.join(rtl_dir, f"{dut}.v"),
os.path.join(rtl_dir, "common", "mqnic_core_axi.v"),
os.path.join(rtl_dir, "common", "mqnic_core.v"),
os.path.join(rtl_dir, "common", "mqnic_dram_if.v"),
os.path.join(rtl_dir, "common", "mqnic_interface.v"),
os.path.join(rtl_dir, "common", "mqnic_interface_tx.v"),
os.path.join(rtl_dir, "common", "mqnic_interface_rx.v"),
os.path.join(rtl_dir, "common", "mqnic_port.v"),
os.path.join(rtl_dir, "common", "mqnic_port_tx.v"),
os.path.join(rtl_dir, "common", "mqnic_port_rx.v"),
os.path.join(rtl_dir, "common", "mqnic_egress.v"),
os.path.join(rtl_dir, "common", "mqnic_ingress.v"),
os.path.join(rtl_dir, "common", "mqnic_l2_egress.v"),
os.path.join(rtl_dir, "common", "mqnic_l2_ingress.v"),
os.path.join(rtl_dir, "common", "mqnic_rx_queue_map.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp_clock.v"),
os.path.join(rtl_dir, "common", "mqnic_ptp_perout.v"),
os.path.join(rtl_dir, "common", "mqnic_rb_clk_info.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_dma_if_axi.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, "irq_rate_limit.v"),
os.path.join(pcie_rtl_dir, "dma_if_axi.v"),
os.path.join(pcie_rtl_dir, "dma_if_axi_rd.v"),
os.path.join(pcie_rtl_dir, "dma_if_axi_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, "pulse_merge.v"),
]
parameters = {}
# Structural configuration
parameters['IF_COUNT'] = 1
parameters['PORTS_PER_IF'] = 1
parameters['SCHED_PER_IF'] = parameters['PORTS_PER_IF']
parameters['PORT_MASK'] = 0
# Clock configuration
parameters['CLK_PERIOD_NS_NUM'] = 4
parameters['CLK_PERIOD_NS_DENOM'] = 1
# PTP configuration
parameters['PTP_CLK_PERIOD_NS_NUM'] = 32
parameters['PTP_CLK_PERIOD_NS_DENOM'] = 5
parameters['PTP_CLOCK_PIPELINE'] = 0
parameters['PTP_CLOCK_CDC_PIPELINE'] = 0
parameters['PTP_USE_SAMPLE_CLOCK'] = 1
parameters['PTP_PORT_CDC_PIPELINE'] = 0
parameters['PTP_PEROUT_ENABLE'] = 1
parameters['PTP_PEROUT_COUNT'] = 1
# Queue manager configuration
parameters['EVENT_QUEUE_OP_TABLE_SIZE'] = 32
parameters['TX_QUEUE_OP_TABLE_SIZE'] = 32
parameters['RX_QUEUE_OP_TABLE_SIZE'] = 32
parameters['TX_CPL_QUEUE_OP_TABLE_SIZE'] = parameters['TX_QUEUE_OP_TABLE_SIZE']
parameters['RX_CPL_QUEUE_OP_TABLE_SIZE'] = parameters['RX_QUEUE_OP_TABLE_SIZE']
parameters['EVENT_QUEUE_INDEX_WIDTH'] = 2
parameters['TX_QUEUE_INDEX_WIDTH'] = 5
parameters['RX_QUEUE_INDEX_WIDTH'] = 5
parameters['TX_CPL_QUEUE_INDEX_WIDTH'] = parameters['TX_QUEUE_INDEX_WIDTH']
parameters['RX_CPL_QUEUE_INDEX_WIDTH'] = parameters['RX_QUEUE_INDEX_WIDTH']
parameters['EVENT_QUEUE_PIPELINE'] = 3
parameters['TX_QUEUE_PIPELINE'] = 3 + max(parameters['TX_QUEUE_INDEX_WIDTH']-12, 0)
parameters['RX_QUEUE_PIPELINE'] = 3 + max(parameters['RX_QUEUE_INDEX_WIDTH']-12, 0)
parameters['TX_CPL_QUEUE_PIPELINE'] = parameters['TX_QUEUE_PIPELINE']
parameters['RX_CPL_QUEUE_PIPELINE'] = parameters['RX_QUEUE_PIPELINE']
# TX and RX engine configuration
parameters['TX_DESC_TABLE_SIZE'] = 32
parameters['RX_DESC_TABLE_SIZE'] = 32
parameters['RX_INDIR_TBL_ADDR_WIDTH'] = min(parameters['RX_QUEUE_INDEX_WIDTH'], 8)
# Scheduler configuration
parameters['TX_SCHEDULER_OP_TABLE_SIZE'] = parameters['TX_DESC_TABLE_SIZE']
parameters['TX_SCHEDULER_PIPELINE'] = parameters['TX_QUEUE_PIPELINE']
parameters['TDMA_INDEX_WIDTH'] = 6
# Interface configuration
parameters['PTP_TS_ENABLE'] = 1
parameters['TX_CPL_FIFO_DEPTH'] = 32
parameters['TX_CHECKSUM_ENABLE'] = 1
parameters['RX_HASH_ENABLE'] = 1
parameters['RX_CHECKSUM_ENABLE'] = 1
parameters['TX_FIFO_DEPTH'] = 32768
parameters['RX_FIFO_DEPTH'] = 32768
parameters['MAX_TX_SIZE'] = 9214
parameters['MAX_RX_SIZE'] = 9214
parameters['TX_RAM_SIZE'] = 32768
parameters['RX_RAM_SIZE'] = 32768
# Application block configuration
parameters['APP_ID'] = 0x00000000
parameters['APP_ENABLE'] = 0
parameters['APP_CTRL_ENABLE'] = 1
parameters['APP_DMA_ENABLE'] = 1
parameters['APP_AXIS_DIRECT_ENABLE'] = 1
parameters['APP_AXIS_SYNC_ENABLE'] = 1
parameters['APP_AXIS_IF_ENABLE'] = 1
parameters['APP_STAT_ENABLE'] = 1
# AXI DMA interface configuration
parameters['AXI_DATA_WIDTH'] = 128
parameters['AXI_ADDR_WIDTH'] = 40
parameters['AXI_ID_WIDTH'] = 4
# DMA interface configuration
parameters['DMA_IMM_ENABLE'] = 0
parameters['DMA_IMM_WIDTH'] = 32
parameters['DMA_LEN_WIDTH'] = 16
parameters['DMA_TAG_WIDTH'] = 16
parameters['RAM_ADDR_WIDTH'] = (max(parameters['TX_RAM_SIZE'], parameters['RX_RAM_SIZE'])-1).bit_length()
parameters['RAM_PIPELINE'] = 2
parameters['AXI_DMA_MAX_BURST_LEN'] = 16
# AXI lite interface configuration (control)
parameters['AXIL_CTRL_DATA_WIDTH'] = 32
parameters['AXIL_CTRL_ADDR_WIDTH'] = 24
# AXI lite interface configuration (application control)
parameters['AXIL_APP_CTRL_DATA_WIDTH'] = parameters['AXIL_CTRL_DATA_WIDTH']
parameters['AXIL_APP_CTRL_ADDR_WIDTH'] = 24
# Ethernet interface configuration
parameters['AXIS_ETH_TX_PIPELINE'] = 0
parameters['AXIS_ETH_TX_FIFO_PIPELINE'] = 2
parameters['AXIS_ETH_TX_TS_PIPELINE'] = 0
parameters['AXIS_ETH_RX_PIPELINE'] = 0
parameters['AXIS_ETH_RX_FIFO_PIPELINE'] = 2
# Statistics counter subsystem
parameters['STAT_ENABLE'] = 1
parameters['STAT_DMA_ENABLE'] = 1
parameters['STAT_AXI_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,
)