mirror of
https://github.com/fpganinja/taxi.git
synced 2025-12-07 16:28:40 -08:00
example/Nexus_K3P_S: Add example design for Cisco Nexus K35-S/K3P-S
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -93,6 +93,8 @@ To facilitate the dual-license model, contributions to the project can only be a
|
||||
Example designs are provided for several different FPGA boards, showcasing many of the capabilities of this library. Building the example designs will require the appropriate vendor toolchain and may also require tool and IP licenses.
|
||||
|
||||
* Alpha Data ADM-PCIE-9V3 (Xilinx Virtex UltraScale+ XCVU3P)
|
||||
* Cisco Nexus K35-S/ExaNIC X10 (Xilinx Kintex UltraScale XCKU035)
|
||||
* Cisco Nexus K3P-S/ExaNIC X25 (Xilinx Kintex UltraScale+ XCKU3P)
|
||||
* Digilent Arty A7 (Xilinx Artix 7 XC7A35T)
|
||||
* HiTech Global HTG-940 (Xilinx Virtex UltraScale+ XCVU9P/XCVU13P)
|
||||
* Xilinx KC705 (Xilinx Kintex 7 XC7K325T)
|
||||
|
||||
34
example/Nexus_K3P_S/fpga/README.md
Normal file
34
example/Nexus_K3P_S/fpga/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Taxi Example Design for Nexus K35-S/K3P-S (ExaNIC X10/X25)
|
||||
|
||||
## Introduction
|
||||
|
||||
This example design targets the Cisco Nexus K35-S/K3P-S (ExaNIC X10/X25) FPGA board.
|
||||
|
||||
The design places looped-back MACs on the SFP+ cages.
|
||||
|
||||
* SFP+ cages
|
||||
* Looped-back 10GBASE-R or 25GBASE-R MAC via GTH or GTY transceiver
|
||||
|
||||
## Board details
|
||||
|
||||
* FPGA:
|
||||
* K35-S/X10: xcku035-fbva676-2-e
|
||||
* K3P-S/X235: xcku3p-ffvb676-2-e
|
||||
* 25GBASE-R PHY: Soft PCS with GTH or GTY transceiver
|
||||
|
||||
## Licensing
|
||||
|
||||
* Toolchain
|
||||
* Vivado Standard (enterprise license not required)
|
||||
* IP
|
||||
* No licensed vendor IP or 3rd party IP
|
||||
|
||||
## How to build
|
||||
|
||||
Run `make` in the appropriate `fpga*` subdirectory to build the bitstream. Ensure that the Xilinx Vivado toolchain components are in PATH.
|
||||
|
||||
## How to test
|
||||
|
||||
Run `make program` to program the board with Vivado.
|
||||
|
||||
To test the looped-back MAC, it is recommended to use a network tester like the Viavi T-BERD 5800 that supports basic layer 2 tests with a loopback. Do not connect the looped-back MAC to a network as the reflected packets may cause problems.
|
||||
153
example/Nexus_K3P_S/fpga/common/vivado.mk
Normal file
153
example/Nexus_K3P_S/fpga/common/vivado.mk
Normal file
@@ -0,0 +1,153 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
###################################################################
|
||||
#
|
||||
# Xilinx Vivado FPGA Makefile
|
||||
#
|
||||
# Copyright (c) 2016-2025 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 - list of source files
|
||||
# INC_FILES - list of include files
|
||||
# XDC_FILES - list of timing constraint files
|
||||
# XCI_FILES - list of IP XCI files
|
||||
# IP_TCL_FILES - list of IP TCL files (sourced during project creation)
|
||||
# CONFIG_TCL_FILES - list of config TCL files (sourced before each build)
|
||||
#
|
||||
# Note: both SYN_FILES and INC_FILES support file list files. File list
|
||||
# files are files with a .f extension that contain a list of additional
|
||||
# files to include, one path relative to the .f file location per line.
|
||||
# The .f files are processed recursively, and then the complete file list
|
||||
# is de-duplicated, with later files in the list taking precedence.
|
||||
#
|
||||
# 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 %.ltx %.xsa %.mcs %.prm
|
||||
.SECONDARY:
|
||||
|
||||
CONFIG ?= config.mk
|
||||
-include $(CONFIG)
|
||||
|
||||
FPGA_TOP ?= fpga
|
||||
PROJECT ?= $(FPGA_TOP)
|
||||
XDC_FILES ?= $(PROJECT).xdc
|
||||
|
||||
# handle file list files
|
||||
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
|
||||
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
|
||||
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
|
||||
SYN_FILES := $(call uniq_base,$(call process_f_files,$(SYN_FILES)))
|
||||
INC_FILES := $(call uniq_base,$(call process_f_files,$(INC_FILES)))
|
||||
|
||||
###################################################################
|
||||
# Main Targets
|
||||
#
|
||||
# all: build everything (fpga)
|
||||
# fpga: build FPGA config
|
||||
# vivado: open project in Vivado
|
||||
# tmpclean: remove intermediate files
|
||||
# clean: remove output files and project files
|
||||
# distclean: remove archived output 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 fresh project if Makefile or IP files have changed
|
||||
create_project.tcl: Makefile $(XCI_FILES) $(IP_TCL_FILES)
|
||||
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)" >> $@
|
||||
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
|
||||
echo "add_files -fileset constrs_1 $(XDC_FILES)" >> $@
|
||||
for x in $(XCI_FILES); do echo "import_ip $$x" >> $@; done
|
||||
for x in $(IP_TCL_FILES); do echo "source $$x" >> $@; done
|
||||
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
|
||||
|
||||
# source config TCL scripts if any source file has changed
|
||||
update_config.tcl: $(CONFIG_TCL_FILES) $(SYN_FILES) $(INC_FILES) $(XDC_FILES)
|
||||
echo "open_project -quiet $(PROJECT).xpr" > $@
|
||||
for x in $(CONFIG_TCL_FILES); 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: create_project.tcl update_config.tcl $(SYN_FILES) $(INC_FILES) $(XDC_FILES) | $(PROJECT).xpr
|
||||
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
|
||||
|
||||
# output files (including potentially bit, bin, ltx, and xsa)
|
||||
$(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; \
|
||||
if [ -e $(PROJECT).xsa ]; then cp -pv $(PROJECT).xsa rev/$(PROJECT)_rev$$COUNT.xsa; fi
|
||||
83
example/Nexus_K3P_S/fpga/fpga_K35/Makefile
Normal file
83
example/Nexus_K3P_S/fpga/fpga_K35/Makefile
Normal file
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcku035-fbva676-2-e
|
||||
FPGA_TOP = fpga
|
||||
FPGA_ARCH = kintexu
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = ../rtl/fpga_k35.sv
|
||||
SYN_FILES += ../rtl/fpga_core.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us.f
|
||||
SYN_FILES += ../lib/taxi/rtl/axis/taxi_axis_async_fifo.f
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_reset.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_signal.sv
|
||||
|
||||
# XDC files
|
||||
XDC_FILES = ../fpga_k35.xdc
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_eth_mac_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_axis_async_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_sync_reset.tcl
|
||||
|
||||
# IP
|
||||
IP_TCL_FILES = ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_161.tcl
|
||||
|
||||
# Configuration
|
||||
# CONFIG_TCL_FILES = ./config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
program: $(PROJECT).bit
|
||||
echo "open_hw_manager" > program.tcl
|
||||
echo "connect_hw_server" >> program.tcl
|
||||
echo "open_hw_target" >> program.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||
echo "exit" >> program.tcl
|
||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||
|
||||
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
||||
echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x00800000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||
echo "exit" >> generate_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||
mkdir -p rev
|
||||
COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
for x in .mcs .prm; \
|
||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(PROJECT).mcs $(PROJECT).prm
|
||||
echo "open_hw_manager" > flash.tcl
|
||||
echo "connect_hw_server" >> flash.tcl
|
||||
echo "open_hw_target" >> flash.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {28f256p30t-bpi-x16}] 0]" >> flash.tcl
|
||||
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.BPI_RS_PINS {24:23} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "exit" >> flash.tcl
|
||||
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||
83
example/Nexus_K3P_S/fpga/fpga_K3P/Makefile
Normal file
83
example/Nexus_K3P_S/fpga/fpga_K3P/Makefile
Normal file
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcku3p-ffvb676-2-e
|
||||
FPGA_TOP = fpga
|
||||
FPGA_ARCH = kintexuplus
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = ../rtl/fpga_k3p.sv
|
||||
SYN_FILES += ../rtl/fpga_core.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us.f
|
||||
SYN_FILES += ../lib/taxi/rtl/axis/taxi_axis_async_fifo.f
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_reset.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_signal.sv
|
||||
|
||||
# XDC files
|
||||
XDC_FILES = ../fpga_k3p.xdc
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_eth_mac_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_axis_async_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_sync_reset.tcl
|
||||
|
||||
# IP
|
||||
IP_TCL_FILES = ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_161.tcl
|
||||
|
||||
# Configuration
|
||||
# CONFIG_TCL_FILES = ./config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
program: $(PROJECT).bit
|
||||
echo "open_hw_manager" > program.tcl
|
||||
echo "connect_hw_server" >> program.tcl
|
||||
echo "open_hw_target" >> program.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||
echo "exit" >> program.tcl
|
||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||
|
||||
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
||||
echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x00800000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||
echo "exit" >> generate_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||
mkdir -p rev
|
||||
COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
for x in .mcs .prm; \
|
||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(PROJECT).mcs $(PROJECT).prm
|
||||
echo "open_hw_manager" > flash.tcl
|
||||
echo "connect_hw_server" >> flash.tcl
|
||||
echo "open_hw_target" >> flash.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {s29gl256p-bpi-x16}] 0]" >> flash.tcl
|
||||
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.BPI_RS_PINS {24:23} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "exit" >> flash.tcl
|
||||
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||
84
example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile
Normal file
84
example/Nexus_K3P_S/fpga/fpga_K3P_10g/Makefile
Normal file
@@ -0,0 +1,84 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcku3p-ffvb676-2-e
|
||||
FPGA_TOP = fpga
|
||||
FPGA_ARCH = kintexuplus
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = ../rtl/fpga_k3p.sv
|
||||
SYN_FILES += ../rtl/fpga_core.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us.f
|
||||
SYN_FILES += ../lib/taxi/rtl/axis/taxi_axis_async_fifo.f
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_reset.sv
|
||||
SYN_FILES += ../lib/taxi/rtl/sync/taxi_sync_signal.sv
|
||||
|
||||
# XDC files
|
||||
XDC_FILES = ../fpga_k3p.xdc
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_eth_mac_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_axis_async_fifo.tcl
|
||||
XDC_FILES += ../lib/taxi/syn/vivado/taxi_sync_reset.tcl
|
||||
|
||||
# IP
|
||||
IP_TCL_FILES = ../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_161.tcl
|
||||
|
||||
# Configuration
|
||||
# CONFIG_TCL_FILES = ./config.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
program: $(PROJECT).bit
|
||||
echo "open_hw_manager" > program.tcl
|
||||
echo "connect_hw_server" >> program.tcl
|
||||
echo "open_hw_target" >> program.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||
echo "exit" >> program.tcl
|
||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||
|
||||
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
||||
echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x00800000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||
echo "exit" >> generate_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||
mkdir -p rev
|
||||
COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
for x in .mcs .prm; \
|
||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(PROJECT).mcs $(PROJECT).prm
|
||||
echo "open_hw_manager" > flash.tcl
|
||||
echo "connect_hw_server" >> flash.tcl
|
||||
echo "open_hw_target" >> flash.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {s29gl256p-bpi-x16}] 0]" >> flash.tcl
|
||||
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.BPI_RS_PINS {24:23} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "exit" >> flash.tcl
|
||||
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||
|
||||
192
example/Nexus_K3P_S/fpga/fpga_k35.xdc
Normal file
192
example/Nexus_K3P_S/fpga/fpga_k35.xdc
Normal file
@@ -0,0 +1,192 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# XDC constraints for the Cisco Nexus K35-S / ExaNIC X10
|
||||
# part: xcku035-fbva676-2-e
|
||||
|
||||
# General configuration
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
|
||||
set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type2 [current_design]
|
||||
set_property CONFIG_MODE BPI16 [current_design]
|
||||
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
|
||||
|
||||
# 100 MHz system clock
|
||||
set_property -dict {LOC D18 IOSTANDARD LVDS} [get_ports {clk_100mhz_p}]
|
||||
set_property -dict {LOC C18 IOSTANDARD LVDS} [get_ports {clk_100mhz_n}]
|
||||
create_clock -period 10 -name clk_100mhz [get_ports {clk_100mhz_p}]
|
||||
|
||||
# LEDs
|
||||
set_property -dict {LOC A25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_led[0][0]}]
|
||||
set_property -dict {LOC A24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_led[0][1]}]
|
||||
set_property -dict {LOC E23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_led[1][0]}]
|
||||
set_property -dict {LOC D26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_led[1][1]}]
|
||||
set_property -dict {LOC C23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[0]}]
|
||||
set_property -dict {LOC D23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_led[1]}]
|
||||
|
||||
set_false_path -to [get_ports {sfp_led[*][*] sma_led[*]}]
|
||||
set_output_delay 0 [get_ports {sfp_led[*][*] sma_led[*]}]
|
||||
|
||||
# GPIO
|
||||
#set_property -dict {LOC W26 IOSTANDARD LVCMOS18} [get_ports {gpio[0]}]
|
||||
#set_property -dict {LOC Y26 IOSTANDARD LVCMOS18} [get_ports {gpio[1]}]
|
||||
#set_property -dict {LOC AB26 IOSTANDARD LVCMOS18} [get_ports {gpio[2]}]
|
||||
#set_property -dict {LOC AC26 IOSTANDARD LVCMOS18} [get_ports {gpio[3]}]
|
||||
|
||||
# SMA
|
||||
#set_property -dict {LOC B17 IOSTANDARD LVCMOS18} [get_ports {sma_in}]
|
||||
#set_property -dict {LOC B16 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {sma_out}]
|
||||
#set_property -dict {LOC B19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_out_en}]
|
||||
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sma_term_en}]
|
||||
|
||||
#set_false_path -to [get_ports {sma_out sma_term sma_term_en}]
|
||||
#set_output_delay 0 [get_ports {sma_out sma_term sma_term_en}]
|
||||
#set_false_path -from [get_ports {sma_in}]
|
||||
#set_input_delay 0 [get_ports {sma_in}]
|
||||
|
||||
# SFP+ Interfaces
|
||||
set_property -dict {LOC D2 } [get_ports {sfp_rx_p[0]}] ;# MGTHRXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC D1 } [get_ports {sfp_rx_n[0]}] ;# MGTHRXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC E4 } [get_ports {sfp_tx_p[0]}] ;# MGTHTXP0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC E3 } [get_ports {sfp_tx_n[0]}] ;# MGTHTXN0_227 GTHE3_CHANNEL_X0Y12 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC C4 } [get_ports {sfp_rx_p[1]}] ;# MGTHRXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC C3 } [get_ports {sfp_rx_n[1]}] ;# MGTHRXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC D6 } [get_ports {sfp_tx_p[1]}] ;# MGTHTXP1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC D5 } [get_ports {sfp_tx_n[1]}] ;# MGTHTXN1_227 GTHE3_CHANNEL_X0Y13 / GTHE3_COMMON_X0Y3
|
||||
set_property -dict {LOC H6 } [get_ports {sfp_mgt_refclk_p}] ;# MGTREFCLK0P_227 from X2
|
||||
set_property -dict {LOC H5 } [get_ports {sfp_mgt_refclk_n}] ;# MGTREFCLK0N_227 from X2
|
||||
set_property -dict {LOC AA12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_tx_disable[0]}]
|
||||
set_property -dict {LOC W14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_tx_disable[1]}]
|
||||
set_property -dict {LOC C24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_npres[0]}]
|
||||
set_property -dict {LOC D24 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_npres[1]}]
|
||||
set_property -dict {LOC W13 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_los[0]}]
|
||||
set_property -dict {LOC AB12 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_los[1]}]
|
||||
set_property -dict {LOC B25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_rs[0]}]
|
||||
set_property -dict {LOC D25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_rs[1]}]
|
||||
#set_property -dict {LOC W11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl}]
|
||||
#set_property -dict {LOC Y11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[0]}]
|
||||
#set_property -dict {LOC Y13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[1]}]
|
||||
|
||||
# 161.1328125 MHz MGT reference clock
|
||||
create_clock -period 6.206 -name sfp_mgt_refclk [get_ports {sfp_mgt_refclk_p}]
|
||||
|
||||
set_false_path -to [get_ports {sfp_tx_disable[*] sfp_rs[*]}]
|
||||
set_output_delay 0 [get_ports {sfp_tx_disable[*] sfp_rs[*]}]
|
||||
set_false_path -from [get_ports {sfp_npres[*] sfp_los[*]}]
|
||||
set_input_delay 0 [get_ports {sfp_npres[*] sfp_los[*]}]
|
||||
|
||||
#set_false_path -to [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_output_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_false_path -from [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_input_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
|
||||
# I2C interface
|
||||
#set_property -dict {LOC B26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {eeprom_i2c_scl}]
|
||||
#set_property -dict {LOC C26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {eeprom_i2c_sda}]
|
||||
|
||||
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
|
||||
# PCIe Interface
|
||||
#set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTHRXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTHRXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC R4 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC R3 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTHRXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTHRXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC U4 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC U3 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTHRXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTHRXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC W4 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC W3 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTHRXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTHRXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC AA4 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC AA3 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
|
||||
#set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTHRXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTHRXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AB6 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTHRXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTHRXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AC4 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AC3 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTHRXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTHRXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD6 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTHRXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTHRXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF6 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
|
||||
#set_property -dict {LOC T6 } [get_ports pcie_mgt_refclk_p] ;# MGTREFCLK0P_225
|
||||
#set_property -dict {LOC T5 } [get_ports pcie_mgt_refclk_n] ;# MGTREFCLK0N_225
|
||||
#set_property -dict {LOC AC22 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
|
||||
|
||||
# 100 MHz MGT reference clock
|
||||
#create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_mgt_refclk_p]
|
||||
|
||||
#set_false_path -from [get_ports {pcie_reset_n}]
|
||||
#set_input_delay 0 [get_ports {pcie_reset_n}]
|
||||
|
||||
# BPI flash
|
||||
#set_property -dict {LOC AE10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[0]}]
|
||||
#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[1]}]
|
||||
#set_property -dict {LOC AD10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[2]}]
|
||||
#set_property -dict {LOC AD9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[3]}]
|
||||
#set_property -dict {LOC AC11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[4]}]
|
||||
#set_property -dict {LOC AF10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[5]}]
|
||||
#set_property -dict {LOC AF14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[6]}]
|
||||
#set_property -dict {LOC AE12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[7]}]
|
||||
#set_property -dict {LOC AD14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[8]}]
|
||||
#set_property -dict {LOC AF13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[9]}]
|
||||
#set_property -dict {LOC AE13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[10]}]
|
||||
#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[11]}]
|
||||
#set_property -dict {LOC AC13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[12]}]
|
||||
#set_property -dict {LOC AD13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[13]}]
|
||||
#set_property -dict {LOC AA14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[14]}]
|
||||
#set_property -dict {LOC AB15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_dq[15]}]
|
||||
#set_property -dict {LOC AD11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[0]}]
|
||||
#set_property -dict {LOC AE11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[1]}]
|
||||
#set_property -dict {LOC AF12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[2]}]
|
||||
#set_property -dict {LOC AB11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[3]}]
|
||||
#set_property -dict {LOC AB9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[4]}]
|
||||
#set_property -dict {LOC AB14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[5]}]
|
||||
#set_property -dict {LOC AA10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[6]}]
|
||||
#set_property -dict {LOC AA9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[7]}]
|
||||
#set_property -dict {LOC W10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[8]}]
|
||||
#set_property -dict {LOC AA13 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[9]}]
|
||||
#set_property -dict {LOC Y15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[10]}]
|
||||
#set_property -dict {LOC AC12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[11]}]
|
||||
#set_property -dict {LOC V12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[12]}]
|
||||
#set_property -dict {LOC V11 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[13]}]
|
||||
#set_property -dict {LOC Y12 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[14]}]
|
||||
#set_property -dict {LOC W9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[15]}]
|
||||
#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[16]}]
|
||||
#set_property -dict {LOC W8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[17]}]
|
||||
#set_property -dict {LOC W15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[18]}]
|
||||
#set_property -dict {LOC AA15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[19]}]
|
||||
#set_property -dict {LOC AE16 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[20]}]
|
||||
#set_property -dict {LOC AF15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[21]}]
|
||||
#set_property -dict {LOC AE15 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_addr[22]}]
|
||||
#set_property -dict {LOC AD15 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {flash_region}]
|
||||
#set_property -dict {LOC AC9 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_ce_n}]
|
||||
#set_property -dict {LOC AC14 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_oe_n}]
|
||||
#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_we_n}]
|
||||
#set_property -dict {LOC Y10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {flash_adv_n}]
|
||||
|
||||
#set_false_path -to [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
|
||||
#set_output_delay 0 [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
|
||||
#set_false_path -from [get_ports {flash_dq[*]}]
|
||||
#set_input_delay 0 [get_ports {flash_dq[*]}]
|
||||
195
example/Nexus_K3P_S/fpga/fpga_k3p.xdc
Normal file
195
example/Nexus_K3P_S/fpga/fpga_k3p.xdc
Normal file
@@ -0,0 +1,195 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
#
|
||||
|
||||
# XDC constraints for the Cisco Nexus K3P-S / ExaNIC X25
|
||||
# part: xcku3p-ffvb676-2-e
|
||||
|
||||
# General configuration
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 31.9 [current_design]
|
||||
set_property BITSTREAM.CONFIG.BPI_PAGE_SIZE 8 [current_design]
|
||||
set_property BITSTREAM.CONFIG.BPI_1ST_READ_CYCLE 4 [current_design]
|
||||
set_property CONFIG_MODE BPI16 [current_design]
|
||||
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
|
||||
|
||||
# 10 MHz TXCO
|
||||
#set_property -dict {LOC D14 IOSTANDARD LVCMOS33} [get_ports clk_10mhz]
|
||||
#create_clock -period 100 -name clk_100mhz [get_ports clk_10mhz]
|
||||
|
||||
# LEDs
|
||||
set_property -dict {LOC J12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_led[0][0]}]
|
||||
set_property -dict {LOC H12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_led[0][1]}]
|
||||
set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_led[1][0]}]
|
||||
set_property -dict {LOC H13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_led[1][1]}]
|
||||
set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led[0]}]
|
||||
set_property -dict {LOC G12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led[1]}]
|
||||
|
||||
set_false_path -to [get_ports {sfp_led[*][*] sma_led[*]}]
|
||||
set_output_delay 0 [get_ports {sfp_led[*][*] sma_led[*]}]
|
||||
|
||||
# GPIO
|
||||
#set_property -dict {LOC F9 IOSTANDARD LVCMOS18} [get_ports {gpio[0]}]
|
||||
#set_property -dict {LOC F10 IOSTANDARD LVCMOS18} [get_ports {gpio[1]}]
|
||||
#set_property -dict {LOC G9 IOSTANDARD LVCMOS18} [get_ports {gpio[2]}]
|
||||
#set_property -dict {LOC G10 IOSTANDARD LVCMOS18} [get_ports {gpio[3]}]
|
||||
|
||||
# SMA
|
||||
#set_property -dict {LOC A14 IOSTANDARD LVCMOS33} [get_ports {sma_in}]
|
||||
#set_property -dict {LOC A12 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {sma_out}]
|
||||
#set_property -dict {LOC A13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_out_en}]
|
||||
#set_property -dict {LOC B12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_term_en}]
|
||||
|
||||
#set_false_path -to [get_ports {sma_out sma_term sma_term_en}]
|
||||
#set_output_delay 0 [get_ports {sma_out sma_term sma_term_en}]
|
||||
#set_false_path -from [get_ports {sma_in}]
|
||||
#set_input_delay 0 [get_ports {sma_in}]
|
||||
|
||||
# Config
|
||||
#set_property -dict {LOC C14 IOSTANDARD LVCMOS33} [get_ports {ddr_npres}]
|
||||
|
||||
# SFP28 Interfaces
|
||||
set_property -dict {LOC D2 } [get_ports {sfp_rx_p[0]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC D1 } [get_ports {sfp_rx_n[0]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC A4 } [get_ports {sfp_rx_p[1]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC A3 } [get_ports {sfp_rx_n[1]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC F7 } [get_ports {sfp_tx_p[0]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC F6 } [get_ports {sfp_tx_n[0]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC B7 } [get_ports {sfp_tx_p[1]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC B6 } [get_ports {sfp_tx_n[1]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
|
||||
set_property -dict {LOC K7 } [get_ports {sfp_mgt_refclk_p}] ;# MGTREFCLK0P_227 from X2
|
||||
set_property -dict {LOC K6 } [get_ports {sfp_mgt_refclk_n}] ;# MGTREFCLK0N_227 from X2
|
||||
set_property -dict {LOC AC17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_tx_disable[0]}]
|
||||
set_property -dict {LOC AA17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {sfp_tx_disable[1]}]
|
||||
set_property -dict {LOC F12 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_npres[0]}]
|
||||
set_property -dict {LOC F14 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {sfp_npres[1]}]
|
||||
set_property -dict {LOC AC16 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_los[0]}]
|
||||
set_property -dict {LOC Y17 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {sfp_los[1]}]
|
||||
set_property -dict {LOC G14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_rs[0]}]
|
||||
set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_rs[1]}]
|
||||
#set_property -dict {LOC A10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_scl}]
|
||||
#set_property -dict {LOC C11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[0]}]
|
||||
#set_property -dict {LOC B11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {sfp_i2c_sda[1]}]
|
||||
|
||||
# 161.1328125 MHz MGT reference clock
|
||||
create_clock -period 6.206 -name sfp_mgt_refclk [get_ports {sfp_mgt_refclk_p}]
|
||||
|
||||
set_false_path -to [get_ports {sfp_tx_disable[*] sfp_rs[*]}]
|
||||
set_output_delay 0 [get_ports {sfp_tx_disable[*] sfp_rs[*]}]
|
||||
set_false_path -from [get_ports {sfp_npres[*] sfp_los[*]}]
|
||||
set_input_delay 0 [get_ports {sfp_npres[*] sfp_los[*]}]
|
||||
|
||||
#set_false_path -to [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_output_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_false_path -from [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
#set_input_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
|
||||
|
||||
# I2C interface
|
||||
#set_property -dict {LOC B9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {eeprom_i2c_scl}]
|
||||
#set_property -dict {LOC A9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {eeprom_i2c_sda}]
|
||||
|
||||
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
|
||||
|
||||
# PCIe Interface
|
||||
#set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC R5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC R4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC U5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC U4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC W5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC W4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC AA5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC AA4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
|
||||
#set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AC5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AC4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AD6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AE8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
|
||||
#set_property -dict {LOC V7 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_225
|
||||
#set_property -dict {LOC V6 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_225
|
||||
#set_property -dict {LOC T19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
|
||||
|
||||
#set_false_path -from [get_ports {pcie_reset_n}]
|
||||
#set_input_delay 0 [get_ports {pcie_reset_n}]
|
||||
|
||||
# 100 MHz MGT reference clock
|
||||
#create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p]
|
||||
|
||||
# BPI flash
|
||||
#set_property -dict {LOC AF20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[0]}]
|
||||
#set_property -dict {LOC AE18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[1]}]
|
||||
#set_property -dict {LOC AF19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[2]}]
|
||||
#set_property -dict {LOC AF17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[3]}]
|
||||
#set_property -dict {LOC AB19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[4]}]
|
||||
#set_property -dict {LOC AD19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[5]}]
|
||||
#set_property -dict {LOC AB17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[6]}]
|
||||
#set_property -dict {LOC AE17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[7]}]
|
||||
#set_property -dict {LOC AD16 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[8]}]
|
||||
#set_property -dict {LOC AE16 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[9]}]
|
||||
#set_property -dict {LOC AD18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[10]}]
|
||||
#set_property -dict {LOC AC21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[11]}]
|
||||
#set_property -dict {LOC AE22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[12]}]
|
||||
#set_property -dict {LOC AF22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[13]}]
|
||||
#set_property -dict {LOC AF25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[14]}]
|
||||
#set_property -dict {LOC AF24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[15]}]
|
||||
#set_property -dict {LOC AE20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[0]}]
|
||||
#set_property -dict {LOC AE26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[1]}]
|
||||
#set_property -dict {LOC AD24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[2]}]
|
||||
#set_property -dict {LOC AC23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[3]}]
|
||||
#set_property -dict {LOC AE23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[4]}]
|
||||
#set_property -dict {LOC AD20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[5]}]
|
||||
#set_property -dict {LOC AC24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[6]}]
|
||||
#set_property -dict {LOC AC22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[7]}]
|
||||
#set_property -dict {LOC AD23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[8]}]
|
||||
#set_property -dict {LOC AD21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[9]}]
|
||||
#set_property -dict {LOC AB22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[10]}]
|
||||
#set_property -dict {LOC AA22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[11]}]
|
||||
#set_property -dict {LOC AE25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[12]}]
|
||||
#set_property -dict {LOC AD26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[13]}]
|
||||
#set_property -dict {LOC AB25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[14]}]
|
||||
#set_property -dict {LOC AB26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[15]}]
|
||||
#set_property -dict {LOC AD25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[16]}]
|
||||
#set_property -dict {LOC AC26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[17]}]
|
||||
#set_property -dict {LOC AB21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[18]}]
|
||||
#set_property -dict {LOC AB24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[19]}]
|
||||
#set_property -dict {LOC Y18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[20]}]
|
||||
#set_property -dict {LOC AA20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[21]}]
|
||||
#set_property -dict {LOC AC19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[22]}]
|
||||
#set_property -dict {LOC Y20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {flash_region}]
|
||||
#set_property -dict {LOC AF18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_ce_n}]
|
||||
#set_property -dict {LOC Y21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_oe_n}]
|
||||
#set_property -dict {LOC AB20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_we_n}]
|
||||
#set_property -dict {LOC AF23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_adv_n}]
|
||||
|
||||
#set_false_path -to [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
|
||||
#set_output_delay 0 [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
|
||||
#set_false_path -from [get_ports {flash_dq[*]}]
|
||||
#set_input_delay 0 [get_ports {flash_dq[*]}]
|
||||
1
example/Nexus_K3P_S/fpga/lib/taxi
Symbolic link
1
example/Nexus_K3P_S/fpga/lib/taxi
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../
|
||||
367
example/Nexus_K3P_S/fpga/rtl/fpga_core.sv
Normal file
367
example/Nexus_K3P_S/fpga/rtl/fpga_core.sv
Normal file
@@ -0,0 +1,367 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2025 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
|
||||
*/
|
||||
|
||||
`resetall
|
||||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* FPGA core logic
|
||||
*/
|
||||
module fpga_core #
|
||||
(
|
||||
parameter logic SIM = 1'b0,
|
||||
parameter string VENDOR = "XILINX",
|
||||
parameter string FAMILY = "kintexuplus"
|
||||
)
|
||||
(
|
||||
/*
|
||||
* Clock: 125MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
input wire logic clk_125mhz,
|
||||
input wire logic rst_125mhz,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
output wire logic [1:0][1:0] sfp_led,
|
||||
output wire logic [1:0] sma_led,
|
||||
|
||||
/*
|
||||
* Ethernet: SFP+
|
||||
*/
|
||||
input wire logic [1:0] sfp_rx_p,
|
||||
input wire logic [1:0] sfp_rx_n,
|
||||
output wire logic [1:0] sfp_tx_p,
|
||||
output wire logic [1:0] sfp_tx_n,
|
||||
input wire logic sfp_mgt_refclk_p,
|
||||
input wire logic sfp_mgt_refclk_n,
|
||||
output wire logic sfp_mgt_refclk_out,
|
||||
output wire logic [1:0] sfp_tx_disable,
|
||||
input wire logic [1:0] sfp_npres,
|
||||
input wire logic [1:0] sfp_los,
|
||||
output wire logic [1:0] sfp_rs
|
||||
);
|
||||
|
||||
// SFP+
|
||||
wire [1:0] sfp_tx_clk;
|
||||
wire [1:0] sfp_tx_rst;
|
||||
wire [1:0] sfp_rx_clk;
|
||||
wire [1:0] sfp_rx_rst;
|
||||
|
||||
wire [1:0] sfp_rx_status;
|
||||
|
||||
assign sfp_led[0][0] = sfp_rx_status[0];
|
||||
assign sfp_led[0][1] = 1'b0;
|
||||
assign sfp_led[1][0] = sfp_rx_status[1];
|
||||
assign sfp_led[1][1] = 1'b0;
|
||||
assign sma_led = '0;
|
||||
|
||||
assign sfp_tx_disable = '1;
|
||||
assign sfp_rs = '1;
|
||||
|
||||
wire sfp_gtpowergood;
|
||||
|
||||
wire sfp_mgt_refclk;
|
||||
wire sfp_mgt_refclk_int;
|
||||
wire sfp_mgt_refclk_bufg;
|
||||
|
||||
assign sfp_mgt_refclk_out = sfp_mgt_refclk_bufg;
|
||||
|
||||
wire sfp_rst;
|
||||
|
||||
taxi_axis_if #(.DATA_W(64), .ID_W(8)) axis_sfp_tx[1:0]();
|
||||
taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl[1:0]();
|
||||
taxi_axis_if #(.DATA_W(64), .ID_W(8)) axis_sfp_rx[1:0]();
|
||||
|
||||
if (SIM) begin
|
||||
|
||||
assign sfp_mgt_refclk = sfp_mgt_refclk_p;
|
||||
assign sfp_mgt_refclk_int = sfp_mgt_refclk_p;
|
||||
assign sfp_mgt_refclk_bufg = sfp_mgt_refclk_int;
|
||||
|
||||
end else begin
|
||||
|
||||
if (FAMILY == "kintexu") begin
|
||||
|
||||
IBUFDS_GTE3 ibufds_gte3_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)
|
||||
);
|
||||
|
||||
end else begin
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
taxi_sync_reset #(
|
||||
.N(4)
|
||||
)
|
||||
sfp_sync_reset_inst (
|
||||
.clk(sfp_mgt_refclk_bufg),
|
||||
.rst(rst_125mhz),
|
||||
.out(sfp_rst)
|
||||
);
|
||||
|
||||
taxi_eth_mac_25g_us #(
|
||||
.SIM(SIM),
|
||||
.VENDOR(VENDOR),
|
||||
.FAMILY(FAMILY),
|
||||
|
||||
.CNT(2),
|
||||
|
||||
// GT type
|
||||
.GT_TYPE(FAMILY == "kintexu" ? "GTH" : "GTY"),
|
||||
|
||||
// GT parameters
|
||||
.GT_TX_POLARITY('1),
|
||||
.GT_RX_POLARITY('0),
|
||||
|
||||
// MAC/PHY parameters
|
||||
.PADDING_EN(1'b1),
|
||||
.DIC_EN(1'b1),
|
||||
.MIN_FRAME_LEN(64),
|
||||
.PTP_TS_EN(1'b0),
|
||||
.PTP_TS_FMT_TOD(1'b1),
|
||||
.PTP_TS_W(96),
|
||||
.PRBS31_EN(1'b0),
|
||||
.TX_SERDES_PIPELINE(1),
|
||||
.RX_SERDES_PIPELINE(1),
|
||||
.COUNT_125US(125000/6.4)
|
||||
)
|
||||
sfp_mac_inst (
|
||||
.xcvr_ctrl_clk(clk_125mhz),
|
||||
.xcvr_ctrl_rst(sfp_rst),
|
||||
|
||||
/*
|
||||
* Common
|
||||
*/
|
||||
.xcvr_gtpowergood_out(sfp_gtpowergood),
|
||||
.xcvr_gtrefclk00_in(sfp_mgt_refclk),
|
||||
.xcvr_qpll0lock_out(),
|
||||
.xcvr_qpll0clk_out(),
|
||||
.xcvr_qpll0refclk_out(),
|
||||
|
||||
/*
|
||||
* Serial data
|
||||
*/
|
||||
.xcvr_txp(sfp_tx_p),
|
||||
.xcvr_txn(sfp_tx_n),
|
||||
.xcvr_rxp(sfp_rx_p),
|
||||
.xcvr_rxn(sfp_rx_n),
|
||||
|
||||
/*
|
||||
* MAC clocks
|
||||
*/
|
||||
.rx_clk(sfp_rx_clk),
|
||||
.rx_rst_in('0),
|
||||
.rx_rst_out(sfp_rx_rst),
|
||||
.tx_clk(sfp_tx_clk),
|
||||
.tx_rst_in('0),
|
||||
.tx_rst_out(sfp_tx_rst),
|
||||
.ptp_sample_clk('0),
|
||||
|
||||
/*
|
||||
* Transmit interface (AXI stream)
|
||||
*/
|
||||
.s_axis_tx(axis_sfp_tx),
|
||||
.m_axis_tx_cpl(axis_sfp_tx_cpl),
|
||||
|
||||
/*
|
||||
* Receive interface (AXI stream)
|
||||
*/
|
||||
.m_axis_rx(axis_sfp_rx),
|
||||
|
||||
/*
|
||||
* PTP clock
|
||||
*/
|
||||
.tx_ptp_ts('0),
|
||||
.tx_ptp_ts_step('0),
|
||||
.rx_ptp_ts('0),
|
||||
.rx_ptp_ts_step('0),
|
||||
|
||||
|
||||
/*
|
||||
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
|
||||
*/
|
||||
.tx_lfc_req('0),
|
||||
.tx_lfc_resend('0),
|
||||
.rx_lfc_en('0),
|
||||
.rx_lfc_req(),
|
||||
.rx_lfc_ack('0),
|
||||
|
||||
/*
|
||||
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
|
||||
*/
|
||||
.tx_pfc_req('0),
|
||||
.tx_pfc_resend('0),
|
||||
.rx_pfc_en('0),
|
||||
.rx_pfc_req(),
|
||||
.rx_pfc_ack('0),
|
||||
|
||||
/*
|
||||
* Pause interface
|
||||
*/
|
||||
.tx_lfc_pause_en('0),
|
||||
.tx_pause_req('0),
|
||||
.tx_pause_ack(),
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
.tx_start_packet(),
|
||||
.tx_error_underflow(),
|
||||
.rx_start_packet(),
|
||||
.rx_error_count(),
|
||||
.rx_error_bad_frame(),
|
||||
.rx_error_bad_fcs(),
|
||||
.rx_bad_block(),
|
||||
.rx_sequence_error(),
|
||||
.rx_block_lock(),
|
||||
.rx_high_ber(),
|
||||
.rx_status(sfp_rx_status),
|
||||
.stat_tx_mcf(),
|
||||
.stat_rx_mcf(),
|
||||
.stat_tx_lfc_pkt(),
|
||||
.stat_tx_lfc_xon(),
|
||||
.stat_tx_lfc_xoff(),
|
||||
.stat_tx_lfc_paused(),
|
||||
.stat_tx_pfc_pkt(),
|
||||
.stat_tx_pfc_xon(),
|
||||
.stat_tx_pfc_xoff(),
|
||||
.stat_tx_pfc_paused(),
|
||||
.stat_rx_lfc_pkt(),
|
||||
.stat_rx_lfc_xon(),
|
||||
.stat_rx_lfc_xoff(),
|
||||
.stat_rx_lfc_paused(),
|
||||
.stat_rx_pfc_pkt(),
|
||||
.stat_rx_pfc_xon(),
|
||||
.stat_rx_pfc_xoff(),
|
||||
.stat_rx_pfc_paused(),
|
||||
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
.cfg_ifg('{2{8'd12}}),
|
||||
.cfg_tx_enable('1),
|
||||
.cfg_rx_enable('1),
|
||||
.cfg_tx_prbs31_enable('0),
|
||||
.cfg_rx_prbs31_enable('0),
|
||||
.cfg_mcf_rx_eth_dst_mcast('{2{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_mcf_rx_check_eth_dst_mcast('1),
|
||||
.cfg_mcf_rx_eth_dst_ucast('{2{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_dst_ucast('0),
|
||||
.cfg_mcf_rx_eth_src('{2{48'd0}}),
|
||||
.cfg_mcf_rx_check_eth_src('0),
|
||||
.cfg_mcf_rx_eth_type('{2{16'h8808}}),
|
||||
.cfg_mcf_rx_opcode_lfc('{2{16'h0001}}),
|
||||
.cfg_mcf_rx_check_opcode_lfc('1),
|
||||
.cfg_mcf_rx_opcode_pfc('{2{16'h0101}}),
|
||||
.cfg_mcf_rx_check_opcode_pfc('1),
|
||||
.cfg_mcf_rx_forward('0),
|
||||
.cfg_mcf_rx_enable('0),
|
||||
.cfg_tx_lfc_eth_dst('{2{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_lfc_eth_src('{2{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_lfc_eth_type('{2{16'h8808}}),
|
||||
.cfg_tx_lfc_opcode('{2{16'h0001}}),
|
||||
.cfg_tx_lfc_en('0),
|
||||
.cfg_tx_lfc_quanta('{2{16'hffff}}),
|
||||
.cfg_tx_lfc_refresh('{2{16'h7fff}}),
|
||||
.cfg_tx_pfc_eth_dst('{2{48'h01_80_C2_00_00_01}}),
|
||||
.cfg_tx_pfc_eth_src('{2{48'h80_23_31_43_54_4C}}),
|
||||
.cfg_tx_pfc_eth_type('{2{16'h8808}}),
|
||||
.cfg_tx_pfc_opcode('{2{16'h0101}}),
|
||||
.cfg_tx_pfc_en('0),
|
||||
.cfg_tx_pfc_quanta('{2{'{8{16'hffff}}}}),
|
||||
.cfg_tx_pfc_refresh('{2{'{8{16'h7fff}}}}),
|
||||
.cfg_rx_lfc_opcode('{2{16'h0001}}),
|
||||
.cfg_rx_lfc_en('0),
|
||||
.cfg_rx_pfc_opcode('{2{16'h0101}}),
|
||||
.cfg_rx_pfc_en('0)
|
||||
);
|
||||
|
||||
for (genvar n = 0; n < 2; n = n + 1) begin : sfp_ch
|
||||
|
||||
taxi_axis_async_fifo #(
|
||||
.DEPTH(16384),
|
||||
.RAM_PIPELINE(2),
|
||||
.FRAME_FIFO(1),
|
||||
.USER_BAD_FRAME_VALUE(1'b1),
|
||||
.USER_BAD_FRAME_MASK(1'b1),
|
||||
.DROP_OVERSIZE_FRAME(1),
|
||||
.DROP_BAD_FRAME(1),
|
||||
.DROP_WHEN_FULL(1)
|
||||
)
|
||||
ch_fifo (
|
||||
/*
|
||||
* AXI4-Stream input (sink)
|
||||
*/
|
||||
.s_clk(sfp_rx_clk[n]),
|
||||
.s_rst(sfp_rx_rst[n]),
|
||||
.s_axis(axis_sfp_rx[n]),
|
||||
|
||||
/*
|
||||
* AXI4-Stream output (source)
|
||||
*/
|
||||
.m_clk(sfp_tx_clk[n]),
|
||||
.m_rst(sfp_tx_rst[n]),
|
||||
.m_axis(axis_sfp_tx[n]),
|
||||
|
||||
/*
|
||||
* Pause
|
||||
*/
|
||||
.s_pause_req(1'b0),
|
||||
.s_pause_ack(),
|
||||
.m_pause_req(1'b0),
|
||||
.m_pause_ack(),
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
.s_status_depth(),
|
||||
.s_status_depth_commit(),
|
||||
.s_status_overflow(),
|
||||
.s_status_bad_frame(),
|
||||
.s_status_good_frame(),
|
||||
.m_status_depth(),
|
||||
.m_status_depth_commit(),
|
||||
.m_status_overflow(),
|
||||
.m_status_bad_frame(),
|
||||
.m_status_good_frame()
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
||||
205
example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv
Normal file
205
example/Nexus_K3P_S/fpga/rtl/fpga_k35.sv
Normal file
@@ -0,0 +1,205 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2025 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
|
||||
*/
|
||||
|
||||
`resetall
|
||||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* FPGA top-level module
|
||||
*/
|
||||
module fpga #
|
||||
(
|
||||
parameter logic SIM = 1'b0,
|
||||
parameter string VENDOR = "XILINX",
|
||||
parameter string FAMILY = "kintexu"
|
||||
)
|
||||
(
|
||||
/*
|
||||
* Clock: 100MHz LVDS
|
||||
*/
|
||||
input wire logic clk_100mhz_p,
|
||||
input wire logic clk_100mhz_n,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
output wire logic [1:0][1:0] sfp_led,
|
||||
output wire logic [1:0] sma_led,
|
||||
|
||||
/*
|
||||
* Ethernet: SFP+
|
||||
*/
|
||||
input wire logic [1:0] sfp_rx_p,
|
||||
input wire logic [1:0] sfp_rx_n,
|
||||
output wire logic [1:0] sfp_tx_p,
|
||||
output wire logic [1:0] sfp_tx_n,
|
||||
input wire logic sfp_mgt_refclk_p,
|
||||
input wire logic sfp_mgt_refclk_n,
|
||||
output wire logic [1:0] sfp_tx_disable,
|
||||
input wire logic [1:0] sfp_npres,
|
||||
input wire logic [1:0] sfp_los,
|
||||
output wire logic [1:0] sfp_rs
|
||||
);
|
||||
|
||||
// Clock and reset
|
||||
|
||||
wire clk_100mhz_ibufg;
|
||||
|
||||
// Internal 125 MHz clock
|
||||
wire clk_125mhz_mmcm_out;
|
||||
wire clk_125mhz_int;
|
||||
wire rst_125mhz_int;
|
||||
|
||||
wire mmcm_rst = 1'b0;
|
||||
wire mmcm_locked;
|
||||
wire mmcm_clkfb;
|
||||
|
||||
IBUFGDS #(
|
||||
.DIFF_TERM("FALSE"),
|
||||
.IBUF_LOW_PWR("FALSE")
|
||||
)
|
||||
clk_100mhz_ibufg_inst (
|
||||
.O (clk_100mhz_ibufg),
|
||||
.I (clk_100mhz_p),
|
||||
.IB (clk_100mhz_n)
|
||||
);
|
||||
|
||||
// MMCM instance
|
||||
MMCME3_BASE #(
|
||||
// 100 MHz input
|
||||
.CLKIN1_PERIOD(10.0),
|
||||
.REF_JITTER1(0.010),
|
||||
// 100 MHz input / 1 = 100 MHz PFD (range 10 MHz to 500 MHz)
|
||||
.DIVCLK_DIVIDE(1),
|
||||
// 100 MHz PFD * 10 = 1000 MHz VCO (range 600 MHz to 1440 MHz)
|
||||
.CLKFBOUT_MULT_F(10),
|
||||
.CLKFBOUT_PHASE(0),
|
||||
// 1250 MHz / 8 = 125 MHz, 0 degrees
|
||||
.CLKOUT0_DIVIDE_F(8),
|
||||
.CLKOUT0_DUTY_CYCLE(0.5),
|
||||
.CLKOUT0_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT1_DIVIDE(1),
|
||||
.CLKOUT1_DUTY_CYCLE(0.5),
|
||||
.CLKOUT1_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT2_DIVIDE(1),
|
||||
.CLKOUT2_DUTY_CYCLE(0.5),
|
||||
.CLKOUT2_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT3_DIVIDE(1),
|
||||
.CLKOUT3_DUTY_CYCLE(0.5),
|
||||
.CLKOUT3_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT4_DIVIDE(1),
|
||||
.CLKOUT4_DUTY_CYCLE(0.5),
|
||||
.CLKOUT4_PHASE(0),
|
||||
.CLKOUT4_CASCADE("FALSE"),
|
||||
// Not used
|
||||
.CLKOUT5_DIVIDE(1),
|
||||
.CLKOUT5_DUTY_CYCLE(0.5),
|
||||
.CLKOUT5_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT6_DIVIDE(1),
|
||||
.CLKOUT6_DUTY_CYCLE(0.5),
|
||||
.CLKOUT6_PHASE(0),
|
||||
|
||||
// optimized bandwidth
|
||||
.BANDWIDTH("OPTIMIZED"),
|
||||
// don't wait for lock during startup
|
||||
.STARTUP_WAIT("FALSE")
|
||||
)
|
||||
clk_mmcm_inst (
|
||||
// 100 MHz input
|
||||
.CLKIN1(clk_100mhz_ibufg),
|
||||
// direct clkfb feeback
|
||||
.CLKFBIN(mmcm_clkfb),
|
||||
.CLKFBOUT(mmcm_clkfb),
|
||||
.CLKFBOUTB(),
|
||||
// 125 MHz, 0 degrees
|
||||
.CLKOUT0(clk_125mhz_mmcm_out),
|
||||
.CLKOUT0B(),
|
||||
// Not used
|
||||
.CLKOUT1(),
|
||||
.CLKOUT1B(),
|
||||
// Not used
|
||||
.CLKOUT2(),
|
||||
.CLKOUT2B(),
|
||||
// Not used
|
||||
.CLKOUT3(),
|
||||
.CLKOUT3B(),
|
||||
// Not used
|
||||
.CLKOUT4(),
|
||||
// Not used
|
||||
.CLKOUT5(),
|
||||
// Not used
|
||||
.CLKOUT6(),
|
||||
// reset input
|
||||
.RST(mmcm_rst),
|
||||
// don't power down
|
||||
.PWRDWN(1'b0),
|
||||
// locked output
|
||||
.LOCKED(mmcm_locked)
|
||||
);
|
||||
|
||||
BUFG
|
||||
clk_125mhz_bufg_inst (
|
||||
.I(clk_125mhz_mmcm_out),
|
||||
.O(clk_125mhz_int)
|
||||
);
|
||||
|
||||
taxi_sync_reset #(
|
||||
.N(4)
|
||||
)
|
||||
sync_reset_125mhz_inst (
|
||||
.clk(clk_125mhz_int),
|
||||
.rst(~mmcm_locked),
|
||||
.out(rst_125mhz_int)
|
||||
);
|
||||
|
||||
fpga_core #(
|
||||
.SIM(SIM),
|
||||
.VENDOR(VENDOR),
|
||||
.FAMILY(FAMILY)
|
||||
)
|
||||
core_inst (
|
||||
/*
|
||||
* Clock: 125 MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
.clk_125mhz(clk_125mhz_int),
|
||||
.rst_125mhz(rst_125mhz_int),
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.sfp_led(sfp_led),
|
||||
.sma_led(sma_led),
|
||||
|
||||
/*
|
||||
* Ethernet: SFP+
|
||||
*/
|
||||
.sfp_rx_p(sfp_rx_p),
|
||||
.sfp_rx_n(sfp_rx_n),
|
||||
.sfp_tx_p(sfp_tx_p),
|
||||
.sfp_tx_n(sfp_tx_n),
|
||||
.sfp_mgt_refclk_p(sfp_mgt_refclk_p),
|
||||
.sfp_mgt_refclk_n(sfp_mgt_refclk_n),
|
||||
.sfp_mgt_refclk_out(),
|
||||
.sfp_tx_disable(sfp_tx_disable),
|
||||
.sfp_npres(sfp_npres),
|
||||
.sfp_los(sfp_los),
|
||||
.sfp_rs(sfp_rs)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
||||
189
example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv
Normal file
189
example/Nexus_K3P_S/fpga/rtl/fpga_k3p.sv
Normal file
@@ -0,0 +1,189 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2025 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
|
||||
*/
|
||||
|
||||
`resetall
|
||||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* FPGA top-level module
|
||||
*/
|
||||
module fpga #
|
||||
(
|
||||
parameter logic SIM = 1'b0,
|
||||
parameter string VENDOR = "XILINX",
|
||||
parameter string FAMILY = "kintexuplus"
|
||||
)
|
||||
(
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
output wire logic [1:0][1:0] sfp_led,
|
||||
output wire logic [1:0] sma_led,
|
||||
|
||||
/*
|
||||
* Ethernet: SFP+
|
||||
*/
|
||||
input wire logic [1:0] sfp_rx_p,
|
||||
input wire logic [1:0] sfp_rx_n,
|
||||
output wire logic [1:0] sfp_tx_p,
|
||||
output wire logic [1:0] sfp_tx_n,
|
||||
input wire logic sfp_mgt_refclk_p,
|
||||
input wire logic sfp_mgt_refclk_n,
|
||||
output wire logic [1:0] sfp_tx_disable,
|
||||
input wire logic [1:0] sfp_npres,
|
||||
input wire logic [1:0] sfp_los,
|
||||
output wire logic [1:0] sfp_rs
|
||||
);
|
||||
|
||||
// Clock and reset
|
||||
|
||||
wire sfp_mgt_refclk_out;
|
||||
|
||||
// Internal 125 MHz clock
|
||||
wire clk_125mhz_mmcm_out;
|
||||
wire clk_125mhz_int;
|
||||
wire rst_125mhz_int;
|
||||
|
||||
wire mmcm_rst = 1'b0;
|
||||
wire mmcm_locked;
|
||||
wire mmcm_clkfb;
|
||||
|
||||
// MMCM instance
|
||||
MMCME4_BASE #(
|
||||
// 161.13 MHz input
|
||||
.CLKIN1_PERIOD(6.206),
|
||||
.REF_JITTER1(0.010),
|
||||
// 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz)
|
||||
.DIVCLK_DIVIDE(11),
|
||||
// 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz)
|
||||
.CLKFBOUT_MULT_F(64),
|
||||
.CLKFBOUT_PHASE(0),
|
||||
// 937.5 MHz / 7.5 = 125 MHz, 0 degrees
|
||||
.CLKOUT0_DIVIDE_F(7.5),
|
||||
.CLKOUT0_DUTY_CYCLE(0.5),
|
||||
.CLKOUT0_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT1_DIVIDE(1),
|
||||
.CLKOUT1_DUTY_CYCLE(0.5),
|
||||
.CLKOUT1_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT2_DIVIDE(1),
|
||||
.CLKOUT2_DUTY_CYCLE(0.5),
|
||||
.CLKOUT2_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT3_DIVIDE(1),
|
||||
.CLKOUT3_DUTY_CYCLE(0.5),
|
||||
.CLKOUT3_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT4_DIVIDE(1),
|
||||
.CLKOUT4_DUTY_CYCLE(0.5),
|
||||
.CLKOUT4_PHASE(0),
|
||||
.CLKOUT4_CASCADE("FALSE"),
|
||||
// Not used
|
||||
.CLKOUT5_DIVIDE(1),
|
||||
.CLKOUT5_DUTY_CYCLE(0.5),
|
||||
.CLKOUT5_PHASE(0),
|
||||
// Not used
|
||||
.CLKOUT6_DIVIDE(1),
|
||||
.CLKOUT6_DUTY_CYCLE(0.5),
|
||||
.CLKOUT6_PHASE(0),
|
||||
|
||||
// optimized bandwidth
|
||||
.BANDWIDTH("OPTIMIZED"),
|
||||
// don't wait for lock during startup
|
||||
.STARTUP_WAIT("FALSE")
|
||||
)
|
||||
clk_mmcm_inst (
|
||||
// 161.13 MHz input
|
||||
.CLKIN1(sfp_mgt_refclk_out),
|
||||
// direct clkfb feeback
|
||||
.CLKFBIN(mmcm_clkfb),
|
||||
.CLKFBOUT(mmcm_clkfb),
|
||||
.CLKFBOUTB(),
|
||||
// 125 MHz, 0 degrees
|
||||
.CLKOUT0(clk_125mhz_mmcm_out),
|
||||
.CLKOUT0B(),
|
||||
// Not used
|
||||
.CLKOUT1(),
|
||||
.CLKOUT1B(),
|
||||
// Not used
|
||||
.CLKOUT2(),
|
||||
.CLKOUT2B(),
|
||||
// Not used
|
||||
.CLKOUT3(),
|
||||
.CLKOUT3B(),
|
||||
// Not used
|
||||
.CLKOUT4(),
|
||||
// Not used
|
||||
.CLKOUT5(),
|
||||
// Not used
|
||||
.CLKOUT6(),
|
||||
// reset input
|
||||
.RST(mmcm_rst),
|
||||
// don't power down
|
||||
.PWRDWN(1'b0),
|
||||
// locked output
|
||||
.LOCKED(mmcm_locked)
|
||||
);
|
||||
|
||||
BUFG
|
||||
clk_125mhz_bufg_inst (
|
||||
.I(clk_125mhz_mmcm_out),
|
||||
.O(clk_125mhz_int)
|
||||
);
|
||||
|
||||
taxi_sync_reset #(
|
||||
.N(4)
|
||||
)
|
||||
sync_reset_125mhz_inst (
|
||||
.clk(clk_125mhz_int),
|
||||
.rst(~mmcm_locked),
|
||||
.out(rst_125mhz_int)
|
||||
);
|
||||
|
||||
fpga_core #(
|
||||
.SIM(SIM),
|
||||
.VENDOR(VENDOR),
|
||||
.FAMILY(FAMILY)
|
||||
)
|
||||
core_inst (
|
||||
/*
|
||||
* Clock: 125 MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
.clk_125mhz(clk_125mhz_int),
|
||||
.rst_125mhz(rst_125mhz_int),
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.sfp_led(sfp_led),
|
||||
.sma_led(sma_led),
|
||||
|
||||
/*
|
||||
* Ethernet: SFP+
|
||||
*/
|
||||
.sfp_rx_p(sfp_rx_p),
|
||||
.sfp_rx_n(sfp_rx_n),
|
||||
.sfp_tx_p(sfp_tx_p),
|
||||
.sfp_tx_n(sfp_tx_n),
|
||||
.sfp_mgt_refclk_p(sfp_mgt_refclk_p),
|
||||
.sfp_mgt_refclk_n(sfp_mgt_refclk_n),
|
||||
.sfp_mgt_refclk_out(sfp_mgt_refclk_out),
|
||||
.sfp_tx_disable(sfp_tx_disable),
|
||||
.sfp_npres(sfp_npres),
|
||||
.sfp_los(sfp_los),
|
||||
.sfp_rs(sfp_rs)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
||||
51
example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile
Normal file
51
example/Nexus_K3P_S/fpga/tb/fpga_core/Makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (c) 2020-2025 FPGA Ninja, LLC
|
||||
#
|
||||
# Authors:
|
||||
# - Alex Forencich
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
|
||||
SIM ?= verilator
|
||||
WAVES ?= 0
|
||||
|
||||
COCOTB_HDL_TIMEUNIT = 1ns
|
||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||
|
||||
DUT = fpga_core
|
||||
COCOTB_TEST_MODULES = test_$(DUT)
|
||||
COCOTB_TOPLEVEL = $(DUT)
|
||||
MODULE = $(COCOTB_TEST_MODULES)
|
||||
TOPLEVEL = $(COCOTB_TOPLEVEL)
|
||||
VERILOG_SOURCES += ../../rtl/$(DUT).sv
|
||||
VERILOG_SOURCES += ../../lib/taxi/rtl/eth/us/taxi_eth_mac_25g_us.f
|
||||
VERILOG_SOURCES += ../../lib/taxi/rtl/axis/taxi_axis_async_fifo.f
|
||||
VERILOG_SOURCES += ../../lib/taxi/rtl/sync/taxi_sync_reset.sv
|
||||
VERILOG_SOURCES += ../../lib/taxi/rtl/sync/taxi_sync_signal.sv
|
||||
|
||||
# handle file list files
|
||||
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
|
||||
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
|
||||
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
|
||||
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||
|
||||
# module parameters
|
||||
export PARAM_SIM := "1'b1"
|
||||
export PARAM_VENDOR := "\"XILINX\""
|
||||
export PARAM_FAMILY := "\"kintexuplus\""
|
||||
|
||||
ifeq ($(SIM), icarus)
|
||||
PLUSARGS += -fst
|
||||
|
||||
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(COCOTB_TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
|
||||
else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
|
||||
|
||||
ifeq ($(WAVES), 1)
|
||||
COMPILE_ARGS += --trace-fst
|
||||
VERILATOR_TRACE = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
1
example/Nexus_K3P_S/fpga/tb/fpga_core/baser.py
Symbolic link
1
example/Nexus_K3P_S/fpga/tb/fpga_core/baser.py
Symbolic link
@@ -0,0 +1 @@
|
||||
../../lib/taxi/tb/eth/baser.py
|
||||
192
example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py
Normal file
192
example/Nexus_K3P_S/fpga/tb/fpga_core/test_fpga_core.py
Normal file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
|
||||
Copyright (c) 2020-2025 FPGA Ninja, LLC
|
||||
|
||||
Authors:
|
||||
- Alex Forencich
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import cocotb_test.simulator
|
||||
|
||||
import cocotb
|
||||
from cocotb.log import SimLog
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import RisingEdge, Combine
|
||||
|
||||
from cocotbext.eth import XgmiiFrame
|
||||
|
||||
try:
|
||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||
except ImportError:
|
||||
# attempt import from current directory
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
|
||||
try:
|
||||
from baser import BaseRSerdesSource, BaseRSerdesSink
|
||||
finally:
|
||||
del sys.path[0]
|
||||
|
||||
|
||||
class TB:
|
||||
def __init__(self, dut, speed=1000e6):
|
||||
self.dut = dut
|
||||
|
||||
self.log = SimLog("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
cocotb.start_soon(Clock(dut.clk_125mhz, 8, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.sfp_mgt_refclk_p, 6.206, units="ns").start())
|
||||
|
||||
self.sfp_sources = []
|
||||
self.sfp_sinks = []
|
||||
|
||||
for ch in dut.sfp_mac_inst.ch:
|
||||
cocotb.start_soon(Clock(ch.ch_inst.tx_clk, 2.56, units="ns").start())
|
||||
cocotb.start_soon(Clock(ch.ch_inst.rx_clk, 2.56, units="ns").start())
|
||||
|
||||
self.sfp_sources.append(BaseRSerdesSource(ch.ch_inst.serdes_rx_data, ch.ch_inst.serdes_rx_hdr, ch.ch_inst.rx_clk, slip=ch.ch_inst.serdes_rx_bitslip, reverse=True))
|
||||
self.sfp_sinks.append(BaseRSerdesSink(ch.ch_inst.serdes_tx_data, ch.ch_inst.serdes_tx_hdr, ch.ch_inst.tx_clk, reverse=True))
|
||||
|
||||
dut.sfp_npres.setimmediatevalue(0)
|
||||
dut.sfp_los.setimmediatevalue(0)
|
||||
|
||||
async def init(self):
|
||||
|
||||
self.dut.rst_125mhz.setimmediatevalue(0)
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(self.dut.clk_125mhz)
|
||||
|
||||
self.dut.rst_125mhz.value = 1
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(self.dut.clk_125mhz)
|
||||
|
||||
self.dut.rst_125mhz.value = 0
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(self.dut.clk_125mhz)
|
||||
|
||||
|
||||
async def mac_test(tb, source, sink):
|
||||
tb.log.info("Test MAC")
|
||||
|
||||
tb.log.info("Multiple small packets")
|
||||
|
||||
count = 64
|
||||
|
||||
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
|
||||
|
||||
for p in pkts:
|
||||
await source.send(XgmiiFrame.from_payload(p))
|
||||
|
||||
for k in range(count):
|
||||
rx_frame = await sink.recv()
|
||||
|
||||
tb.log.info("RX frame: %s", rx_frame)
|
||||
|
||||
assert rx_frame.get_payload() == pkts[k]
|
||||
assert rx_frame.check_fcs()
|
||||
|
||||
tb.log.info("Multiple large packets")
|
||||
|
||||
count = 32
|
||||
|
||||
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
|
||||
|
||||
for p in pkts:
|
||||
await source.send(XgmiiFrame.from_payload(p))
|
||||
|
||||
for k in range(count):
|
||||
rx_frame = await sink.recv()
|
||||
|
||||
tb.log.info("RX frame: %s", rx_frame)
|
||||
|
||||
assert rx_frame.get_payload() == pkts[k]
|
||||
assert rx_frame.check_fcs()
|
||||
|
||||
tb.log.info("MAC test done")
|
||||
|
||||
|
||||
@cocotb.test()
|
||||
async def run_test(dut):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
await tb.init()
|
||||
|
||||
tests = []
|
||||
|
||||
for k in range(len(tb.sfp_sources)):
|
||||
tb.log.info("Start SFP %d MAC loopback test", k)
|
||||
|
||||
tests.append(cocotb.start_soon(mac_test(tb, tb.sfp_sources[k], tb.sfp_sinks[k])))
|
||||
|
||||
await Combine(*tests)
|
||||
|
||||
await RisingEdge(dut.clk_125mhz)
|
||||
await RisingEdge(dut.clk_125mhz)
|
||||
|
||||
|
||||
# cocotb-test
|
||||
|
||||
tests_dir = os.path.abspath(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'))
|
||||
|
||||
|
||||
def process_f_files(files):
|
||||
lst = {}
|
||||
for f in files:
|
||||
if f[-2:].lower() == '.f':
|
||||
with open(f, 'r') as fp:
|
||||
l = fp.read().split()
|
||||
for f in process_f_files([os.path.join(os.path.dirname(f), x) for x in l]):
|
||||
lst[os.path.basename(f)] = f
|
||||
else:
|
||||
lst[os.path.basename(f)] = f
|
||||
return list(lst.values())
|
||||
|
||||
|
||||
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}.sv"),
|
||||
os.path.join(lib_dir, "taxi", "rtl", "eth", "us", "taxi_eth_mac_25g_us.f"),
|
||||
os.path.join(lib_dir, "taxi", "rtl", "axis", "taxi_axis_async_fifo.f"),
|
||||
os.path.join(lib_dir, "taxi", "rtl", "sync", "taxi_sync_reset.sv"),
|
||||
os.path.join(lib_dir, "taxi", "rtl", "sync", "taxi_sync_signal.sv"),
|
||||
]
|
||||
|
||||
verilog_sources = process_f_files(verilog_sources)
|
||||
|
||||
parameters = {}
|
||||
|
||||
parameters['SIM'] = "1'b1"
|
||||
parameters['VENDOR'] = "\"XILINX\""
|
||||
parameters['FAMILY'] = "\"kintexuplus\""
|
||||
|
||||
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(
|
||||
simulator="verilator",
|
||||
python_search=[tests_dir],
|
||||
verilog_sources=verilog_sources,
|
||||
toplevel=toplevel,
|
||||
module=module,
|
||||
parameters=parameters,
|
||||
sim_build=sim_build,
|
||||
extra_env=extra_env,
|
||||
)
|
||||
Reference in New Issue
Block a user