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

Use unified 10G/25G design for ADM-PCIE-9V3

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2023-07-13 18:59:33 -07:00
parent 48cbe43fa7
commit 729c5a61ce
17 changed files with 106 additions and 3050 deletions

View File

@ -1,25 +0,0 @@
# Targets
TARGETS:=
# Subdirectories
SUBDIRS = fpga
SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS))
# Rules
.PHONY: all
all: $(SUBDIRS) $(TARGETS)
.PHONY: $(SUBDIRS)
$(SUBDIRS):
cd $@ && $(MAKE)
.PHONY: $(SUBDIRS_CLEAN)
$(SUBDIRS_CLEAN):
cd $(@:.clean=) && $(MAKE) clean
.PHONY: clean
clean: $(SUBDIRS_CLEAN)
-rm -rf $(TARGETS)
program:
#djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit

View File

@ -1,30 +0,0 @@
# Verilog Ethernet ADM-PCIE-9V3 Example Design
## Introduction
This example design targets the Alpha Data ADM-PCIE-9V3 FPGA board.
The design by default listens to UDP port 1234 at IP address 192.168.1.128 and
will echo back any packets received. The design will also respond correctly
to ARP requests.
* FPGA: xcvu3p-ffvc1517-2-i
* PHY: 10G BASE-R PHY IP core and internal GTY transceiver
## How to build
Run make to build. Ensure that the Xilinx Vivado toolchain components are
in PATH.
## How to test
Run make program to program the ADM-PCIE-9V3 board with Vivado. Then run
netcat -u 192.168.1.128 1234
to open a UDP connection to port 1234. Any text entered into netcat will be
echoed back after pressing enter.
It is also possible to use hping to test the design by running
hping 192.168.1.128 -2 -p 1234 -d 1024

View File

@ -1,137 +0,0 @@
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - space-separated list of source files
# INC_FILES - space-separated list of include files
# XDC_FILES - space-separated list of timing constraint files
# XCI_FILES - space-separated list of IP XCI files
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: fpga vivado tmpclean clean distclean
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include ../$(CONFIG)
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 *.ltx 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) $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_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: create_project.tcl update_config.tcl $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) | $(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
# bit file
$(PROJECT).bit $(PROJECT).ltx: $(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 $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
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; \
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi

View File

@ -1,482 +0,0 @@
# XDC constraints for the ADM-PCIE-9V3
# part: xcvu3p-ffvc1517-2-i
# 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.EXTMASTERCCLK_EN {DIV-1} [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN {Pullnone} [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 300 MHz system clock
set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p]
set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n]
create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p]
# LEDs
set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}]
set_property -dict {LOC AU27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[1]}]
set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_r}]
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}]
set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}]
set_false_path -to [get_ports {user_led_g[*] user_led_r front_led[*]}]
set_output_delay 0 [get_ports {user_led_g[*] user_led_r front_led[*]}]
# Switches
set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
set_false_path -from [get_ports {user_sw[*]}]
set_input_delay 0 [get_ports {user_sw[*]}]
# GPIO
#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]]
#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]]
#set_property -dict {LOC J31 IOSTANDARD LVCMOS18} [get_ports gpio_p[1]]
#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]]
# QSFP28 Interfaces
set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ?
set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l]
set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p]
set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ?
set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l]
set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_sda]
set_false_path -to [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_output_delay 0 [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_false_path -from [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
set_input_delay 0 [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_false_path -to [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_false_path -from [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC AT25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC AT26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_wp]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#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 J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226
#set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226
#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224
#set_property -dict {LOC AJ6 } [get_ports pcie_refclk_2_n] ;# MGTREFCLK0N_224
#set_property -dict {LOC AJ31 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_0]
#set_property -dict {LOC AH29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_1]
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
#set_false_path -from [get_ports {perst_0}]
#set_input_delay 0 [get_ports {perst_0}]
# DDR4 C0
# 5x K4A8G085WB-RC
#set_property -dict {LOC F9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[0]}]
#set_property -dict {LOC G9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[1]}]
#set_property -dict {LOC G11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[2]}]
#set_property -dict {LOC D11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[3]}]
#set_property -dict {LOC E12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[4]}]
#set_property -dict {LOC G10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[5]}]
#set_property -dict {LOC F10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[6]}]
#set_property -dict {LOC J9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[7]}]
#set_property -dict {LOC J8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[8]}]
#set_property -dict {LOC F12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[9]}]
#set_property -dict {LOC D9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[10]}]
#set_property -dict {LOC H11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[11]}]
#set_property -dict {LOC E8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[12]}]
#set_property -dict {LOC J11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[13]}]
#set_property -dict {LOC C9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[14]}]
#set_property -dict {LOC B11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[15]}]
#set_property -dict {LOC K12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[16]}]
#set_property -dict {LOC H9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[17]}]
#set_property -dict {LOC F8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[0]}]
#set_property -dict {LOC H8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[1]}]
#set_property -dict {LOC D10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[0]}]
#set_property -dict {LOC E11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[1]}]
#set_property -dict {LOC B10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[0]}]
#set_property -dict {LOC C11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[1]}]
#set_property -dict {LOC A9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[2]}]
#set_property -dict {LOC H12 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_t}]
#set_property -dict {LOC G12 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_c}]
#set_property -dict {LOC B9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cke}]
#set_property -dict {LOC E10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n}]
#set_property -dict {LOC C12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_act_n}]
#set_property -dict {LOC A10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_odt}]
#set_property -dict {LOC G7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_par}]
#set_property -dict {LOC F7 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_reset_n}]
#set_property -dict {LOC H7 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_alert_n}]
#set_property -dict {LOC J10 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_ten}]
#set_property -dict {LOC L10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[0]}]
#set_property -dict {LOC L9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[1]}]
#set_property -dict {LOC N9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[2]}]
#set_property -dict {LOC M9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[3]}]
#set_property -dict {LOC M10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[4]}]
#set_property -dict {LOC K11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[5]}]
#set_property -dict {LOC M11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[6]}]
#set_property -dict {LOC K10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[7]}]
#set_property -dict {LOC L17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[8]}]
#set_property -dict {LOC M16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[9]}]
#set_property -dict {LOC M15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[10]}]
#set_property -dict {LOC M17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[11]}]
#set_property -dict {LOC M14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[12]}]
#set_property -dict {LOC N18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[13]}]
#set_property -dict {LOC N16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[14]}]
#set_property -dict {LOC N17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[15]}]
#set_property -dict {LOC F15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[16]}]
#set_property -dict {LOC E16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[17]}]
#set_property -dict {LOC F14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[18]}]
#set_property -dict {LOC E17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[19]}]
#set_property -dict {LOC G16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[20]}]
#set_property -dict {LOC F17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[21]}]
#set_property -dict {LOC E15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[22]}]
#set_property -dict {LOC G17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[23]}]
#set_property -dict {LOC A17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[24]}]
#set_property -dict {LOC C16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[25]}]
#set_property -dict {LOC B16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[26]}]
#set_property -dict {LOC A14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[27]}]
#set_property -dict {LOC B17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[28]}]
#set_property -dict {LOC B14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[29]}]
#set_property -dict {LOC D16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[30]}]
#set_property -dict {LOC D15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[31]}]
#set_property -dict {LOC F18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[32]}]
#set_property -dict {LOC F20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[33]}]
#set_property -dict {LOC F19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[34]}]
#set_property -dict {LOC D21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[35]}]
#set_property -dict {LOC E18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[36]}]
#set_property -dict {LOC G19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[37]}]
#set_property -dict {LOC E21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[38]}]
#set_property -dict {LOC G20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[39]}]
#set_property -dict {LOC D18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[40]}]
#set_property -dict {LOC B22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[41]}]
#set_property -dict {LOC A19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[42]}]
#set_property -dict {LOC A18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[43]}]
#set_property -dict {LOC C19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[44]}]
#set_property -dict {LOC B19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[45]}]
#set_property -dict {LOC A22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[46]}]
#set_property -dict {LOC C18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[47]}]
#set_property -dict {LOC G22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[48]}]
#set_property -dict {LOC J20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[49]}]
#set_property -dict {LOC H19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[50]}]
#set_property -dict {LOC J19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[51]}]
#set_property -dict {LOC H18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[52]}]
#set_property -dict {LOC J18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[53]}]
#set_property -dict {LOC G21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[54]}]
#set_property -dict {LOC K18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[55]}]
#set_property -dict {LOC L20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[56]}]
#set_property -dict {LOC L18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[57]}]
#set_property -dict {LOC N19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[58]}]
#set_property -dict {LOC M21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[59]}]
#set_property -dict {LOC M19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[60]}]
#set_property -dict {LOC M22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[61]}]
#set_property -dict {LOC L19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[62]}]
#set_property -dict {LOC M20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[63]}]
#set_property -dict {LOC H16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[64]}]
#set_property -dict {LOC K15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[65]}]
#set_property -dict {LOC J16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[66]}]
#set_property -dict {LOC J14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[67]}]
#set_property -dict {LOC K13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[68]}]
#set_property -dict {LOC L13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[69]}]
#set_property -dict {LOC H14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[70]}]
#set_property -dict {LOC J15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[71]}]
#set_property -dict {LOC M12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[0]}]
#set_property -dict {LOC L12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[0]}]
#set_property -dict {LOC L15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[1]}]
#set_property -dict {LOC L14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[1]}]
#set_property -dict {LOC F13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[2]}]
#set_property -dict {LOC E13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[2]}]
#set_property -dict {LOC B15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[3]}]
#set_property -dict {LOC A15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[3]}]
#set_property -dict {LOC F22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[4]}]
#set_property -dict {LOC E22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[4]}]
#set_property -dict {LOC C21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[5]}]
#set_property -dict {LOC B21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[5]}]
#set_property -dict {LOC K21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[6]}]
#set_property -dict {LOC K20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[6]}]
#set_property -dict {LOC L22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[7]}]
#set_property -dict {LOC K22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[7]}]
#set_property -dict {LOC K17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[8]}]
#set_property -dict {LOC K16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[8]}]
#set_property -dict {LOC N12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[0]}]
#set_property -dict {LOC P14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[1]}]
#set_property -dict {LOC G15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[2]}]
#set_property -dict {LOC D14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[3]}]
#set_property -dict {LOC E20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[4]}]
#set_property -dict {LOC B20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[5]}]
#set_property -dict {LOC H22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[6]}]
#set_property -dict {LOC N22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[7]}]
#set_property -dict {LOC J13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[8]}]
# DDR4 C1
# 5x K4A8G085WB-RC
#set_property -dict {LOC AN9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[0]}]
#set_property -dict {LOC AM9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[1]}]
#set_property -dict {LOC AP11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[2]}]
#set_property -dict {LOC AU9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[3]}]
#set_property -dict {LOC AT10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[4]}]
#set_property -dict {LOC AL12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[5]}]
#set_property -dict {LOC AM12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[6]}]
#set_property -dict {LOC AM10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[7]}]
#set_property -dict {LOC AL11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[8]}]
#set_property -dict {LOC AP7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[9]}]
#set_property -dict {LOC AR8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[10]}]
#set_property -dict {LOC AL10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[11]}]
#set_property -dict {LOC AP8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[12]}]
#set_property -dict {LOC AK11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[13]}]
#set_property -dict {LOC AP9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[14]}]
#set_property -dict {LOC AV10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[15]}]
#set_property -dict {LOC AT11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[16]}]
#set_property -dict {LOC AL8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[17]}]
#set_property -dict {LOC AN11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[0]}]
#set_property -dict {LOC AR9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[1]}]
#set_property -dict {LOC AP12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[0]}]
#set_property -dict {LOC AN10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[1]}]
#set_property -dict {LOC AW13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[0]}]
#set_property -dict {LOC AU10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[1]}]
#set_property -dict {LOC AW11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[2]}]
#set_property -dict {LOC AM7 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_t}]
#set_property -dict {LOC AN7 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_c}]
#set_property -dict {LOC AU12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cke}]
#set_property -dict {LOC AT12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n}]
#set_property -dict {LOC AV9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_act_n}]
#set_property -dict {LOC AR11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_odt}]
#set_property -dict {LOC AM8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_par}]
#set_property -dict {LOC AN12 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_reset_n}]
#set_property -dict {LOC AR10 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_alert_n}]
#set_property -dict {LOC AV11 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_ten}]
#set_property -dict {LOC AK9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[0]}]
#set_property -dict {LOC AK10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[1]}]
#set_property -dict {LOC AH10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[2]}]
#set_property -dict {LOC AJ11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[3]}]
#set_property -dict {LOC AJ9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[4]}]
#set_property -dict {LOC AH12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[5]}]
#set_property -dict {LOC AG10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[6]}]
#set_property -dict {LOC AJ12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[7]}]
#set_property -dict {LOC AM15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[8]}]
#set_property -dict {LOC AN14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[9]}]
#set_property -dict {LOC AL13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[10]}]
#set_property -dict {LOC AM14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[11]}]
#set_property -dict {LOC AL15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[12]}]
#set_property -dict {LOC AM17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[13]}]
#set_property -dict {LOC AL17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[14]}]
#set_property -dict {LOC AM13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[15]}]
#set_property -dict {LOC AR15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[16]}]
#set_property -dict {LOC AP14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[17]}]
#set_property -dict {LOC AT15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[18]}]
#set_property -dict {LOC AR14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[19]}]
#set_property -dict {LOC AP17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[20]}]
#set_property -dict {LOC AN16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[21]}]
#set_property -dict {LOC AN17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[22]}]
#set_property -dict {LOC AN15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[23]}]
#set_property -dict {LOC AU15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[24]}]
#set_property -dict {LOC AT17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[25]}]
#set_property -dict {LOC AV15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[26]}]
#set_property -dict {LOC AT16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[27]}]
#set_property -dict {LOC AV14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[28]}]
#set_property -dict {LOC AW17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[29]}]
#set_property -dict {LOC AW14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[30]}]
#set_property -dict {LOC AW18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[31]}]
#set_property -dict {LOC AP19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[32]}]
#set_property -dict {LOC AT20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[33]}]
#set_property -dict {LOC AN21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[34]}]
#set_property -dict {LOC AR19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[35]}]
#set_property -dict {LOC AN20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[36]}]
#set_property -dict {LOC AR18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[37]}]
#set_property -dict {LOC AR20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[38]}]
#set_property -dict {LOC AP18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[39]}]
#set_property -dict {LOC AW19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[40]}]
#set_property -dict {LOC AU22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[41]}]
#set_property -dict {LOC AV19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[42]}]
#set_property -dict {LOC AW22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[43]}]
#set_property -dict {LOC AU18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[44]}]
#set_property -dict {LOC AT22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[45]}]
#set_property -dict {LOC AW21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[46]}]
#set_property -dict {LOC AU19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[47]}]
#set_property -dict {LOC AH19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[48]}]
#set_property -dict {LOC AJ22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[49]}]
#set_property -dict {LOC AF21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[50]}]
#set_property -dict {LOC AH22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[51]}]
#set_property -dict {LOC AF20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[52]}]
#set_property -dict {LOC AJ19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[53]}]
#set_property -dict {LOC AH21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[54]}]
#set_property -dict {LOC AJ21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[55]}]
#set_property -dict {LOC AM19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[56]}]
#set_property -dict {LOC AK20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[57]}]
#set_property -dict {LOC AM22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[58]}]
#set_property -dict {LOC AL22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[59]}]
#set_property -dict {LOC AM20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[60]}]
#set_property -dict {LOC AK19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[61]}]
#set_property -dict {LOC AN19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[62]}]
#set_property -dict {LOC AL20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[63]}]
#set_property -dict {LOC AF15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[64]}]
#set_property -dict {LOC AJ17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[65]}]
#set_property -dict {LOC AH17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[66]}]
#set_property -dict {LOC AJ14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[67]}]
#set_property -dict {LOC AG15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[68]}]
#set_property -dict {LOC AJ13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[69]}]
#set_property -dict {LOC AG17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[70]}]
#set_property -dict {LOC AJ16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[71]}]
#set_property -dict {LOC AG9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[0]}]
#set_property -dict {LOC AH9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[0]}]
#set_property -dict {LOC AK16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[1]}]
#set_property -dict {LOC AL16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[1]}]
#set_property -dict {LOC AR13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[2]}]
#set_property -dict {LOC AT13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[2]}]
#set_property -dict {LOC AU17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[3]}]
#set_property -dict {LOC AV17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[3]}]
#set_property -dict {LOC AN22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[4]}]
#set_property -dict {LOC AP22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[4]}]
#set_property -dict {LOC AV22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[5]}]
#set_property -dict {LOC AV21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[5]}]
#set_property -dict {LOC AG20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[6]}]
#set_property -dict {LOC AH20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[6]}]
#set_property -dict {LOC AK21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[7]}]
#set_property -dict {LOC AL21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[7]}]
#set_property -dict {LOC AH16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[8]}]
#set_property -dict {LOC AH15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[8]}]
#set_property -dict {LOC AG12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[0]}]
#set_property -dict {LOC AK15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[1]}]
#set_property -dict {LOC AP16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[2]}]
#set_property -dict {LOC AV16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[3]}]
#set_property -dict {LOC AP21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[4]}]
#set_property -dict {LOC AU20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[5]}]
#set_property -dict {LOC AG19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[6]}]
#set_property -dict {LOC AL18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[7]}]
#set_property -dict {LOC AG14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[8]}]
# QSPI flash
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[3]}]
#set_property -dict {LOC AV30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
#set_false_path -to [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_output_delay 0 [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_false_path -from [get_ports {qspi_1_dq}]
#set_input_delay 0 [get_ports {qspi_1_dq}]

View File

@ -1,76 +0,0 @@
# Copyright (c) 2021 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.
set base_name {eth_xcvr_gt}
set preset {GTY-10GBASE-R}
set freerun_freq {125}
set line_rate {10.3125}
set refclk_freq {161.1328125}
set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}]
set user_data_width {64}
set int_data_width $user_data_width
set extra_ports [list]
set extra_pll_ports [list {qpll0lock_out}]
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 ENABLE_OPTIONAL_PORTS $extra_ports
dict set config LOCATE_COMMON {CORE}
dict set config LOCATE_RESET_CONTROLLER {CORE}
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

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

View File

@ -1,93 +0,0 @@
/*
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 switch and button inputs with a slow sampled shift register
*/
module debounce_switch #(
parameter WIDTH=1, // width of the input and output signals
parameter N=3, // length of shift register
parameter RATE=125000 // clock division factor
)(
input wire clk,
input wire rst,
input wire [WIDTH-1:0] in,
output wire [WIDTH-1:0] out
);
reg [23:0] cnt_reg = 24'd0;
reg [N-1:0] debounce_reg[WIDTH-1:0];
reg [WIDTH-1:0] state;
/*
* The synchronized output is the state register
*/
assign out = state;
integer k;
always @(posedge clk or posedge rst) begin
if (rst) begin
cnt_reg <= 0;
state <= 0;
for (k = 0; k < WIDTH; k = k + 1) begin
debounce_reg[k] <= 0;
end
end else begin
if (cnt_reg < RATE) begin
cnt_reg <= cnt_reg + 24'd1;
end else begin
cnt_reg <= 24'd0;
end
if (cnt_reg == 24'd0) begin
for (k = 0; k < WIDTH; k = k + 1) begin
debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]};
end
end
for (k = 0; k < WIDTH; k = k + 1) begin
if (|debounce_reg[k] == 0) begin
state[k] <= 0;
end else if (&debounce_reg[k] == 1) begin
state[k] <= 1;
end else begin
state[k] <= state[k];
end
end
end
end
endmodule
`resetall

View File

@ -1,299 +0,0 @@
/*
Copyright (c) 2021 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 1ns / 1ps
`default_nettype none
/*
* Transceiver and PHY wrapper
*/
module eth_xcvr_phy_wrapper #
(
parameter HAS_COMMON = 1,
parameter DATA_WIDTH = 64,
parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter HDR_WIDTH = 2,
parameter PRBS31_ENABLE = 0,
parameter TX_SERDES_PIPELINE = 0,
parameter RX_SERDES_PIPELINE = 0,
parameter BITSLIP_HIGH_CYCLES = 1,
parameter BITSLIP_LOW_CYCLES = 8,
parameter COUNT_125US = 125000/6.4
)
(
input wire xcvr_ctrl_clk,
input wire xcvr_ctrl_rst,
/*
* Common
*/
output wire xcvr_gtpowergood_out,
/*
* PLL out
*/
input wire xcvr_gtrefclk00_in,
output wire xcvr_qpll0lock_out,
output wire xcvr_qpll0outclk_out,
output wire xcvr_qpll0outrefclk_out,
/*
* PLL in
*/
input wire xcvr_qpll0lock_in,
output wire xcvr_qpll0reset_out,
input wire xcvr_qpll0clk_in,
input wire xcvr_qpll0refclk_in,
/*
* Serial data
*/
output wire xcvr_txp,
output wire xcvr_txn,
input wire xcvr_rxp,
input wire xcvr_rxn,
/*
* PHY connections
*/
output wire phy_tx_clk,
output wire phy_tx_rst,
input wire [DATA_WIDTH-1:0] phy_xgmii_txd,
input wire [CTRL_WIDTH-1:0] phy_xgmii_txc,
output wire phy_rx_clk,
output wire phy_rx_rst,
output wire [DATA_WIDTH-1:0] phy_xgmii_rxd,
output wire [CTRL_WIDTH-1:0] phy_xgmii_rxc,
output wire phy_tx_bad_block,
output wire [6:0] phy_rx_error_count,
output wire phy_rx_bad_block,
output wire phy_rx_sequence_error,
output wire phy_rx_block_lock,
output wire phy_rx_high_ber,
input wire phy_tx_prbs31_enable,
input wire phy_rx_prbs31_enable
);
wire phy_rx_reset_req;
wire gt_reset_tx_datapath = 1'b0;
wire gt_reset_rx_datapath = phy_rx_reset_req;
wire gt_reset_tx_done;
wire gt_reset_rx_done;
wire [5:0] gt_txheader;
wire [63:0] gt_txdata;
wire gt_rxgearboxslip;
wire [5:0] gt_rxheader;
wire [1:0] gt_rxheadervalid;
wire [63:0] gt_rxdata;
wire [1:0] gt_rxdatavalid;
generate
if (HAS_COMMON) begin : xcvr
eth_xcvr_gt_full
eth_xcvr_gt_full_inst (
// Common
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
.gtwiz_reset_all_in(xcvr_ctrl_rst),
.gtpowergood_out(xcvr_gtpowergood_out),
// PLL
.gtrefclk00_in(xcvr_gtrefclk00_in),
.qpll0lock_out(xcvr_qpll0lock_out),
.qpll0outclk_out(xcvr_qpll0outclk_out),
.qpll0outrefclk_out(xcvr_qpll0outrefclk_out),
// Serial data
.gtytxp_out(xcvr_txp),
.gtytxn_out(xcvr_txn),
.gtyrxp_in(xcvr_rxp),
.gtyrxn_in(xcvr_rxn),
// Transmit
.gtwiz_userclk_tx_reset_in(1'b0),
.gtwiz_userclk_tx_srcclk_out(),
.gtwiz_userclk_tx_usrclk_out(),
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
.gtwiz_userclk_tx_active_out(),
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
.txpmaresetdone_out(),
.txprgdivresetdone_out(),
.gtwiz_userdata_tx_in(gt_txdata),
.txheader_in(gt_txheader),
.txsequence_in(7'b0),
// Receive
.gtwiz_userclk_rx_reset_in(1'b0),
.gtwiz_userclk_rx_srcclk_out(),
.gtwiz_userclk_rx_usrclk_out(),
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
.gtwiz_userclk_rx_active_out(),
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
.gtwiz_reset_rx_cdr_stable_out(),
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
.rxpmaresetdone_out(),
.rxprgdivresetdone_out(),
.rxgearboxslip_in(gt_rxgearboxslip),
.gtwiz_userdata_rx_out(gt_rxdata),
.rxdatavalid_out(gt_rxdatavalid),
.rxheader_out(gt_rxheader),
.rxheadervalid_out(gt_rxheadervalid),
.rxstartofseq_out()
);
end else begin : xcvr
eth_xcvr_gt_channel
eth_xcvr_gt_channel_inst (
// Common
.gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk),
.gtwiz_reset_all_in(xcvr_ctrl_rst),
.gtpowergood_out(xcvr_gtpowergood_out),
// PLL
.gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in),
.gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out),
.qpll0clk_in(xcvr_qpll0clk_in),
.qpll0refclk_in(xcvr_qpll0refclk_in),
.qpll1clk_in(1'b0),
.qpll1refclk_in(1'b0),
// Serial data
.gtytxp_out(xcvr_txp),
.gtytxn_out(xcvr_txn),
.gtyrxp_in(xcvr_rxp),
.gtyrxn_in(xcvr_rxn),
// Transmit
.gtwiz_userclk_tx_reset_in(1'b0),
.gtwiz_userclk_tx_srcclk_out(),
.gtwiz_userclk_tx_usrclk_out(),
.gtwiz_userclk_tx_usrclk2_out(phy_tx_clk),
.gtwiz_userclk_tx_active_out(),
.gtwiz_reset_tx_pll_and_datapath_in(1'b0),
.gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath),
.gtwiz_reset_tx_done_out(gt_reset_tx_done),
.txpmaresetdone_out(),
.txprgdivresetdone_out(),
.gtwiz_userdata_tx_in(gt_txdata),
.txheader_in(gt_txheader),
.txsequence_in(7'b0),
// Receive
.gtwiz_userclk_rx_reset_in(1'b0),
.gtwiz_userclk_rx_srcclk_out(),
.gtwiz_userclk_rx_usrclk_out(),
.gtwiz_userclk_rx_usrclk2_out(phy_rx_clk),
.gtwiz_userclk_rx_active_out(),
.gtwiz_reset_rx_pll_and_datapath_in(1'b0),
.gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath),
.gtwiz_reset_rx_cdr_stable_out(),
.gtwiz_reset_rx_done_out(gt_reset_rx_done),
.rxpmaresetdone_out(),
.rxprgdivresetdone_out(),
.rxgearboxslip_in(gt_rxgearboxslip),
.gtwiz_userdata_rx_out(gt_rxdata),
.rxdatavalid_out(gt_rxdatavalid),
.rxheader_out(gt_rxheader),
.rxheadervalid_out(gt_rxheadervalid),
.rxstartofseq_out()
);
end
endgenerate
sync_reset #(
.N(4)
)
tx_reset_sync_inst (
.clk(phy_tx_clk),
.rst(!gt_reset_tx_done),
.out(phy_tx_rst)
);
sync_reset #(
.N(4)
)
rx_reset_sync_inst (
.clk(phy_rx_clk),
.rst(!gt_reset_rx_done),
.out(phy_rx_rst)
);
eth_phy_10g #(
.DATA_WIDTH(DATA_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.HDR_WIDTH(HDR_WIDTH),
.BIT_REVERSE(1),
.SCRAMBLER_DISABLE(0),
.PRBS31_ENABLE(PRBS31_ENABLE),
.TX_SERDES_PIPELINE(TX_SERDES_PIPELINE),
.RX_SERDES_PIPELINE(RX_SERDES_PIPELINE),
.BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES),
.BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES),
.COUNT_125US(COUNT_125US)
)
phy_inst (
.tx_clk(phy_tx_clk),
.tx_rst(phy_tx_rst),
.rx_clk(phy_rx_clk),
.rx_rst(phy_rx_rst),
.xgmii_txd(phy_xgmii_txd),
.xgmii_txc(phy_xgmii_txc),
.xgmii_rxd(phy_xgmii_rxd),
.xgmii_rxc(phy_xgmii_rxc),
.serdes_tx_data(gt_txdata),
.serdes_tx_hdr(gt_txheader),
.serdes_rx_data(gt_rxdata),
.serdes_rx_hdr(gt_rxheader),
.serdes_rx_bitslip(gt_rxgearboxslip),
.serdes_rx_reset_req(phy_rx_reset_req),
.tx_bad_block(phy_tx_bad_block),
.rx_error_count(phy_rx_error_count),
.rx_bad_block(phy_rx_bad_block),
.rx_sequence_error(phy_rx_sequence_error),
.rx_block_lock(phy_rx_block_lock),
.rx_high_ber(phy_rx_high_ber),
.tx_prbs31_enable(phy_tx_prbs31_enable),
.rx_prbs31_enable(phy_rx_prbs31_enable)
);
endmodule
`resetall

View File

@ -1,796 +0,0 @@
/*
Copyright (c) 2014-2021 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 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga (
/*
* Clock: 300MHz LVDS
*/
input wire clk_300mhz_p,
input wire clk_300mhz_n,
/*
* GPIO
*/
output wire [1:0] user_led_g,
output wire user_led_r,
output wire [1:0] front_led,
input wire [1:0] user_sw,
/*
* Ethernet: QSFP28
*/
output wire qsfp_0_tx_0_p,
output wire qsfp_0_tx_0_n,
input wire qsfp_0_rx_0_p,
input wire qsfp_0_rx_0_n,
output wire qsfp_0_tx_1_p,
output wire qsfp_0_tx_1_n,
input wire qsfp_0_rx_1_p,
input wire qsfp_0_rx_1_n,
output wire qsfp_0_tx_2_p,
output wire qsfp_0_tx_2_n,
input wire qsfp_0_rx_2_p,
input wire qsfp_0_rx_2_n,
output wire qsfp_0_tx_3_p,
output wire qsfp_0_tx_3_n,
input wire qsfp_0_rx_3_p,
input wire qsfp_0_rx_3_n,
input wire qsfp_0_mgt_refclk_p,
input wire qsfp_0_mgt_refclk_n,
input wire qsfp_0_modprs_l,
output wire qsfp_0_sel_l,
output wire qsfp_1_tx_0_p,
output wire qsfp_1_tx_0_n,
input wire qsfp_1_rx_0_p,
input wire qsfp_1_rx_0_n,
output wire qsfp_1_tx_1_p,
output wire qsfp_1_tx_1_n,
input wire qsfp_1_rx_1_p,
input wire qsfp_1_rx_1_n,
output wire qsfp_1_tx_2_p,
output wire qsfp_1_tx_2_n,
input wire qsfp_1_rx_2_p,
input wire qsfp_1_rx_2_n,
output wire qsfp_1_tx_3_p,
output wire qsfp_1_tx_3_n,
input wire qsfp_1_rx_3_p,
input wire qsfp_1_rx_3_n,
input wire qsfp_1_mgt_refclk_p,
input wire qsfp_1_mgt_refclk_n,
input wire qsfp_1_modprs_l,
output wire qsfp_1_sel_l,
output wire qsfp_reset_l,
input wire qsfp_int_l
);
// Clock and reset
wire clk_300mhz_ibufg;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
// Internal 156.25 MHz clock
wire clk_156mhz_int;
wire rst_156mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
IBUFGDS #(
.DIFF_TERM("FALSE"),
.IBUF_LOW_PWR("FALSE")
)
clk_300mhz_ibufg_inst (
.O (clk_300mhz_ibufg),
.I (clk_300mhz_p),
.IB (clk_300mhz_n)
);
// MMCM instance
// 300 MHz in, 125 MHz out
// PFD range: 10 MHz to 500 MHz
// VCO range: 800 MHz to 1600 MHz
// M = 10, D = 3 sets Fvco = 1000 MHz (in range)
// Divide by 8 to get output frequency of 125 MHz
MMCME3_BASE #(
.BANDWIDTH("OPTIMIZED"),
.CLKOUT0_DIVIDE_F(8),
.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(10),
.CLKFBOUT_PHASE(0),
.DIVCLK_DIVIDE(3),
.REF_JITTER1(0.010),
.CLKIN1_PERIOD(3.333),
.STARTUP_WAIT("FALSE"),
.CLKOUT4_CASCADE("FALSE")
)
clk_mmcm_inst (
.CLKIN1(clk_300mhz_ibufg),
.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 [1:0] user_sw_int;
debounce_switch #(
.WIDTH(2),
.N(4),
.RATE(125000)
)
debounce_switch_inst (
.clk(clk_125mhz_int),
.rst(rst_125mhz_int),
.in({user_sw}),
.out({user_sw_int})
);
// XGMII 10G PHY
assign qsfp_reset_l = 1'b1;
// QSFP 0
assign qsfp_0_sel_l = 1'b0;
wire qsfp_0_tx_clk_0_int;
wire qsfp_0_tx_rst_0_int;
wire [63:0] qsfp_0_txd_0_int;
wire [7:0] qsfp_0_txc_0_int;
wire qsfp_0_rx_clk_0_int;
wire qsfp_0_rx_rst_0_int;
wire [63:0] qsfp_0_rxd_0_int;
wire [7:0] qsfp_0_rxc_0_int;
wire qsfp_0_tx_clk_1_int;
wire qsfp_0_tx_rst_1_int;
wire [63:0] qsfp_0_txd_1_int;
wire [7:0] qsfp_0_txc_1_int;
wire qsfp_0_rx_clk_1_int;
wire qsfp_0_rx_rst_1_int;
wire [63:0] qsfp_0_rxd_1_int;
wire [7:0] qsfp_0_rxc_1_int;
wire qsfp_0_tx_clk_2_int;
wire qsfp_0_tx_rst_2_int;
wire [63:0] qsfp_0_txd_2_int;
wire [7:0] qsfp_0_txc_2_int;
wire qsfp_0_rx_clk_2_int;
wire qsfp_0_rx_rst_2_int;
wire [63:0] qsfp_0_rxd_2_int;
wire [7:0] qsfp_0_rxc_2_int;
wire qsfp_0_tx_clk_3_int;
wire qsfp_0_tx_rst_3_int;
wire [63:0] qsfp_0_txd_3_int;
wire [7:0] qsfp_0_txc_3_int;
wire qsfp_0_rx_clk_3_int;
wire qsfp_0_rx_rst_3_int;
wire [63:0] qsfp_0_rxd_3_int;
wire [7:0] qsfp_0_rxc_3_int;
assign clk_156mhz_int = qsfp_0_tx_clk_0_int;
assign rst_156mhz_int = qsfp_0_tx_rst_0_int;
wire qsfp_0_rx_block_lock_0;
wire qsfp_0_rx_block_lock_1;
wire qsfp_0_rx_block_lock_2;
wire qsfp_0_rx_block_lock_3;
wire qsfp_0_mgt_refclk;
IBUFDS_GTE4 ibufds_gte4_qsfp_0_mgt_refclk_inst (
.I (qsfp_0_mgt_refclk_p),
.IB (qsfp_0_mgt_refclk_n),
.CEB (1'b0),
.O (qsfp_0_mgt_refclk),
.ODIV2 ()
);
wire qsfp_0_qpll0lock;
wire qsfp_0_qpll0outclk;
wire qsfp_0_qpll0outrefclk;
eth_xcvr_phy_wrapper #(
.HAS_COMMON(1)
)
qsfp_0_phy_0_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(qsfp_0_mgt_refclk),
.xcvr_qpll0lock_out(qsfp_0_qpll0lock),
.xcvr_qpll0outclk_out(qsfp_0_qpll0outclk),
.xcvr_qpll0outrefclk_out(qsfp_0_qpll0outrefclk),
// PLL in
.xcvr_qpll0lock_in(1'b0),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(1'b0),
.xcvr_qpll0refclk_in(1'b0),
// Serial data
.xcvr_txp(qsfp_0_tx_0_p),
.xcvr_txn(qsfp_0_tx_0_n),
.xcvr_rxp(qsfp_0_rx_0_p),
.xcvr_rxn(qsfp_0_rx_0_n),
// PHY connections
.phy_tx_clk(qsfp_0_tx_clk_0_int),
.phy_tx_rst(qsfp_0_tx_rst_0_int),
.phy_xgmii_txd(qsfp_0_txd_0_int),
.phy_xgmii_txc(qsfp_0_txc_0_int),
.phy_rx_clk(qsfp_0_rx_clk_0_int),
.phy_rx_rst(qsfp_0_rx_rst_0_int),
.phy_xgmii_rxd(qsfp_0_rxd_0_int),
.phy_xgmii_rxc(qsfp_0_rxc_0_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_0_rx_block_lock_0),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_0_phy_1_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_0_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_0_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_0_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_0_tx_1_p),
.xcvr_txn(qsfp_0_tx_1_n),
.xcvr_rxp(qsfp_0_rx_1_p),
.xcvr_rxn(qsfp_0_rx_1_n),
// PHY connections
.phy_tx_clk(qsfp_0_tx_clk_1_int),
.phy_tx_rst(qsfp_0_tx_rst_1_int),
.phy_xgmii_txd(qsfp_0_txd_1_int),
.phy_xgmii_txc(qsfp_0_txc_1_int),
.phy_rx_clk(qsfp_0_rx_clk_1_int),
.phy_rx_rst(qsfp_0_rx_rst_1_int),
.phy_xgmii_rxd(qsfp_0_rxd_1_int),
.phy_xgmii_rxc(qsfp_0_rxc_1_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_0_rx_block_lock_1),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_0_phy_2_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_0_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_0_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_0_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_0_tx_2_p),
.xcvr_txn(qsfp_0_tx_2_n),
.xcvr_rxp(qsfp_0_rx_2_p),
.xcvr_rxn(qsfp_0_rx_2_n),
// PHY connections
.phy_tx_clk(qsfp_0_tx_clk_2_int),
.phy_tx_rst(qsfp_0_tx_rst_2_int),
.phy_xgmii_txd(qsfp_0_txd_2_int),
.phy_xgmii_txc(qsfp_0_txc_2_int),
.phy_rx_clk(qsfp_0_rx_clk_2_int),
.phy_rx_rst(qsfp_0_rx_rst_2_int),
.phy_xgmii_rxd(qsfp_0_rxd_2_int),
.phy_xgmii_rxc(qsfp_0_rxc_2_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_0_rx_block_lock_2),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_0_phy_3_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_0_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_0_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_0_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_0_tx_3_p),
.xcvr_txn(qsfp_0_tx_3_n),
.xcvr_rxp(qsfp_0_rx_3_p),
.xcvr_rxn(qsfp_0_rx_3_n),
// PHY connections
.phy_tx_clk(qsfp_0_tx_clk_3_int),
.phy_tx_rst(qsfp_0_tx_rst_3_int),
.phy_xgmii_txd(qsfp_0_txd_3_int),
.phy_xgmii_txc(qsfp_0_txc_3_int),
.phy_rx_clk(qsfp_0_rx_clk_3_int),
.phy_rx_rst(qsfp_0_rx_rst_3_int),
.phy_xgmii_rxd(qsfp_0_rxd_3_int),
.phy_xgmii_rxc(qsfp_0_rxc_3_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_0_rx_block_lock_3),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
// QSFP 1
assign qsfp_1_sel_l = 1'b0;
wire qsfp_1_tx_clk_0_int;
wire qsfp_1_tx_rst_0_int;
wire [63:0] qsfp_1_txd_0_int;
wire [7:0] qsfp_1_txc_0_int;
wire qsfp_1_rx_clk_0_int;
wire qsfp_1_rx_rst_0_int;
wire [63:0] qsfp_1_rxd_0_int;
wire [7:0] qsfp_1_rxc_0_int;
wire qsfp_1_tx_clk_1_int;
wire qsfp_1_tx_rst_1_int;
wire [63:0] qsfp_1_txd_1_int;
wire [7:0] qsfp_1_txc_1_int;
wire qsfp_1_rx_clk_1_int;
wire qsfp_1_rx_rst_1_int;
wire [63:0] qsfp_1_rxd_1_int;
wire [7:0] qsfp_1_rxc_1_int;
wire qsfp_1_tx_clk_2_int;
wire qsfp_1_tx_rst_2_int;
wire [63:0] qsfp_1_txd_2_int;
wire [7:0] qsfp_1_txc_2_int;
wire qsfp_1_rx_clk_2_int;
wire qsfp_1_rx_rst_2_int;
wire [63:0] qsfp_1_rxd_2_int;
wire [7:0] qsfp_1_rxc_2_int;
wire qsfp_1_tx_clk_3_int;
wire qsfp_1_tx_rst_3_int;
wire [63:0] qsfp_1_txd_3_int;
wire [7:0] qsfp_1_txc_3_int;
wire qsfp_1_rx_clk_3_int;
wire qsfp_1_rx_rst_3_int;
wire [63:0] qsfp_1_rxd_3_int;
wire [7:0] qsfp_1_rxc_3_int;
wire qsfp_1_rx_block_lock_0;
wire qsfp_1_rx_block_lock_1;
wire qsfp_1_rx_block_lock_2;
wire qsfp_1_rx_block_lock_3;
wire qsfp_1_mgt_refclk;
IBUFDS_GTE4 ibufds_gte4_qsfp_1_mgt_refclk_inst (
.I (qsfp_1_mgt_refclk_p),
.IB (qsfp_1_mgt_refclk_n),
.CEB (1'b0),
.O (qsfp_1_mgt_refclk),
.ODIV2 ()
);
wire qsfp_1_qpll0lock;
wire qsfp_1_qpll0outclk;
wire qsfp_1_qpll0outrefclk;
eth_xcvr_phy_wrapper #(
.HAS_COMMON(1)
)
qsfp_1_phy_0_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(qsfp_1_mgt_refclk),
.xcvr_qpll0lock_out(qsfp_1_qpll0lock),
.xcvr_qpll0outclk_out(qsfp_1_qpll0outclk),
.xcvr_qpll0outrefclk_out(qsfp_1_qpll0outrefclk),
// PLL in
.xcvr_qpll0lock_in(1'b0),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(1'b0),
.xcvr_qpll0refclk_in(1'b0),
// Serial data
.xcvr_txp(qsfp_1_tx_0_p),
.xcvr_txn(qsfp_1_tx_0_n),
.xcvr_rxp(qsfp_1_rx_0_p),
.xcvr_rxn(qsfp_1_rx_0_n),
// PHY connections
.phy_tx_clk(qsfp_1_tx_clk_0_int),
.phy_tx_rst(qsfp_1_tx_rst_0_int),
.phy_xgmii_txd(qsfp_1_txd_0_int),
.phy_xgmii_txc(qsfp_1_txc_0_int),
.phy_rx_clk(qsfp_1_rx_clk_0_int),
.phy_rx_rst(qsfp_1_rx_rst_0_int),
.phy_xgmii_rxd(qsfp_1_rxd_0_int),
.phy_xgmii_rxc(qsfp_1_rxc_0_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_1_rx_block_lock_0),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_1_phy_1_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_1_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_1_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_1_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_1_tx_1_p),
.xcvr_txn(qsfp_1_tx_1_n),
.xcvr_rxp(qsfp_1_rx_1_p),
.xcvr_rxn(qsfp_1_rx_1_n),
// PHY connections
.phy_tx_clk(qsfp_1_tx_clk_1_int),
.phy_tx_rst(qsfp_1_tx_rst_1_int),
.phy_xgmii_txd(qsfp_1_txd_1_int),
.phy_xgmii_txc(qsfp_1_txc_1_int),
.phy_rx_clk(qsfp_1_rx_clk_1_int),
.phy_rx_rst(qsfp_1_rx_rst_1_int),
.phy_xgmii_rxd(qsfp_1_rxd_1_int),
.phy_xgmii_rxc(qsfp_1_rxc_1_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_1_rx_block_lock_1),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_1_phy_2_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_1_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_1_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_1_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_1_tx_2_p),
.xcvr_txn(qsfp_1_tx_2_n),
.xcvr_rxp(qsfp_1_rx_2_p),
.xcvr_rxn(qsfp_1_rx_2_n),
// PHY connections
.phy_tx_clk(qsfp_1_tx_clk_2_int),
.phy_tx_rst(qsfp_1_tx_rst_2_int),
.phy_xgmii_txd(qsfp_1_txd_2_int),
.phy_xgmii_txc(qsfp_1_txc_2_int),
.phy_rx_clk(qsfp_1_rx_clk_2_int),
.phy_rx_rst(qsfp_1_rx_rst_2_int),
.phy_xgmii_rxd(qsfp_1_rxd_2_int),
.phy_xgmii_rxc(qsfp_1_rxc_2_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_1_rx_block_lock_2),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
eth_xcvr_phy_wrapper #(
.HAS_COMMON(0)
)
qsfp_1_phy_3_inst (
.xcvr_ctrl_clk(clk_125mhz_int),
.xcvr_ctrl_rst(rst_125mhz_int),
// Common
.xcvr_gtpowergood_out(),
// PLL out
.xcvr_gtrefclk00_in(1'b0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0outclk_out(),
.xcvr_qpll0outrefclk_out(),
// PLL in
.xcvr_qpll0lock_in(qsfp_1_qpll0lock),
.xcvr_qpll0reset_out(),
.xcvr_qpll0clk_in(qsfp_1_qpll0outclk),
.xcvr_qpll0refclk_in(qsfp_1_qpll0outrefclk),
// Serial data
.xcvr_txp(qsfp_1_tx_3_p),
.xcvr_txn(qsfp_1_tx_3_n),
.xcvr_rxp(qsfp_1_rx_3_p),
.xcvr_rxn(qsfp_1_rx_3_n),
// PHY connections
.phy_tx_clk(qsfp_1_tx_clk_3_int),
.phy_tx_rst(qsfp_1_tx_rst_3_int),
.phy_xgmii_txd(qsfp_1_txd_3_int),
.phy_xgmii_txc(qsfp_1_txc_3_int),
.phy_rx_clk(qsfp_1_rx_clk_3_int),
.phy_rx_rst(qsfp_1_rx_rst_3_int),
.phy_xgmii_rxd(qsfp_1_rxd_3_int),
.phy_xgmii_rxc(qsfp_1_rxc_3_int),
.phy_tx_bad_block(),
.phy_rx_error_count(),
.phy_rx_bad_block(),
.phy_rx_sequence_error(),
.phy_rx_block_lock(qsfp_1_rx_block_lock_3),
.phy_rx_high_ber(),
.phy_tx_prbs31_enable(),
.phy_rx_prbs31_enable()
);
assign front_led[0] = qsfp_0_rx_block_lock_0;
assign front_led[1] = qsfp_1_rx_block_lock_0;
fpga_core
core_inst (
/*
* Clock: 156.25 MHz
* Synchronous reset
*/
.clk(clk_156mhz_int),
.rst(rst_156mhz_int),
/*
* GPIO
*/
.user_led_g(user_led_g),
.user_led_r(user_led_r),
//.front_led(front_led),
.user_sw(user_sw_int),
/*
* Ethernet: QSFP28
*/
.qsfp_0_tx_clk_0(qsfp_0_tx_clk_0_int),
.qsfp_0_tx_rst_0(qsfp_0_tx_rst_0_int),
.qsfp_0_txd_0(qsfp_0_txd_0_int),
.qsfp_0_txc_0(qsfp_0_txc_0_int),
.qsfp_0_rx_clk_0(qsfp_0_rx_clk_0_int),
.qsfp_0_rx_rst_0(qsfp_0_rx_rst_0_int),
.qsfp_0_rxd_0(qsfp_0_rxd_0_int),
.qsfp_0_rxc_0(qsfp_0_rxc_0_int),
.qsfp_0_tx_clk_1(qsfp_0_tx_clk_1_int),
.qsfp_0_tx_rst_1(qsfp_0_tx_rst_1_int),
.qsfp_0_txd_1(qsfp_0_txd_1_int),
.qsfp_0_txc_1(qsfp_0_txc_1_int),
.qsfp_0_rx_clk_1(qsfp_0_rx_clk_1_int),
.qsfp_0_rx_rst_1(qsfp_0_rx_rst_1_int),
.qsfp_0_rxd_1(qsfp_0_rxd_1_int),
.qsfp_0_rxc_1(qsfp_0_rxc_1_int),
.qsfp_0_tx_clk_2(qsfp_0_tx_clk_2_int),
.qsfp_0_tx_rst_2(qsfp_0_tx_rst_2_int),
.qsfp_0_txd_2(qsfp_0_txd_2_int),
.qsfp_0_txc_2(qsfp_0_txc_2_int),
.qsfp_0_rx_clk_2(qsfp_0_rx_clk_2_int),
.qsfp_0_rx_rst_2(qsfp_0_rx_rst_2_int),
.qsfp_0_rxd_2(qsfp_0_rxd_2_int),
.qsfp_0_rxc_2(qsfp_0_rxc_2_int),
.qsfp_0_tx_clk_3(qsfp_0_tx_clk_3_int),
.qsfp_0_tx_rst_3(qsfp_0_tx_rst_3_int),
.qsfp_0_txd_3(qsfp_0_txd_3_int),
.qsfp_0_txc_3(qsfp_0_txc_3_int),
.qsfp_0_rx_clk_3(qsfp_0_rx_clk_3_int),
.qsfp_0_rx_rst_3(qsfp_0_rx_rst_3_int),
.qsfp_0_rxd_3(qsfp_0_rxd_3_int),
.qsfp_0_rxc_3(qsfp_0_rxc_3_int),
.qsfp_1_tx_clk_0(qsfp_1_tx_clk_0_int),
.qsfp_1_tx_rst_0(qsfp_1_tx_rst_0_int),
.qsfp_1_txd_0(qsfp_1_txd_0_int),
.qsfp_1_txc_0(qsfp_1_txc_0_int),
.qsfp_1_rx_clk_0(qsfp_1_rx_clk_0_int),
.qsfp_1_rx_rst_0(qsfp_1_rx_rst_0_int),
.qsfp_1_rxd_0(qsfp_1_rxd_0_int),
.qsfp_1_rxc_0(qsfp_1_rxc_0_int),
.qsfp_1_tx_clk_1(qsfp_1_tx_clk_1_int),
.qsfp_1_tx_rst_1(qsfp_1_tx_rst_1_int),
.qsfp_1_txd_1(qsfp_1_txd_1_int),
.qsfp_1_txc_1(qsfp_1_txc_1_int),
.qsfp_1_rx_clk_1(qsfp_1_rx_clk_1_int),
.qsfp_1_rx_rst_1(qsfp_1_rx_rst_1_int),
.qsfp_1_rxd_1(qsfp_1_rxd_1_int),
.qsfp_1_rxc_1(qsfp_1_rxc_1_int),
.qsfp_1_tx_clk_2(qsfp_1_tx_clk_2_int),
.qsfp_1_tx_rst_2(qsfp_1_tx_rst_2_int),
.qsfp_1_txd_2(qsfp_1_txd_2_int),
.qsfp_1_txc_2(qsfp_1_txc_2_int),
.qsfp_1_rx_clk_2(qsfp_1_rx_clk_2_int),
.qsfp_1_rx_rst_2(qsfp_1_rx_rst_2_int),
.qsfp_1_rxd_2(qsfp_1_rxd_2_int),
.qsfp_1_rxc_2(qsfp_1_rxc_2_int),
.qsfp_1_tx_clk_3(qsfp_1_tx_clk_3_int),
.qsfp_1_tx_rst_3(qsfp_1_tx_rst_3_int),
.qsfp_1_txd_3(qsfp_1_txd_3_int),
.qsfp_1_txc_3(qsfp_1_txc_3_int),
.qsfp_1_rx_clk_3(qsfp_1_rx_clk_3_int),
.qsfp_1_rx_rst_3(qsfp_1_rx_rst_3_int),
.qsfp_1_rxd_3(qsfp_1_rxd_3_int),
.qsfp_1_rxc_3(qsfp_1_rxc_3_int)
);
endmodule
`resetall

View File

@ -1,665 +0,0 @@
/*
Copyright (c) 2014-2021 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 1ns / 1ps
`default_nettype none
/*
* FPGA core logic
*/
module fpga_core #
(
parameter TARGET = "XILINX"
)
(
/*
* Clock: 156.25MHz
* Synchronous reset
*/
input wire clk,
input wire rst,
/*
* GPIO
*/
output wire [1:0] user_led_g,
output wire user_led_r,
output wire [1:0] front_led,
input wire [1:0] user_sw,
/*
* Ethernet: QSFP28
*/
input wire qsfp_0_tx_clk_0,
input wire qsfp_0_tx_rst_0,
output wire [63:0] qsfp_0_txd_0,
output wire [7:0] qsfp_0_txc_0,
input wire qsfp_0_rx_clk_0,
input wire qsfp_0_rx_rst_0,
input wire [63:0] qsfp_0_rxd_0,
input wire [7:0] qsfp_0_rxc_0,
input wire qsfp_0_tx_clk_1,
input wire qsfp_0_tx_rst_1,
output wire [63:0] qsfp_0_txd_1,
output wire [7:0] qsfp_0_txc_1,
input wire qsfp_0_rx_clk_1,
input wire qsfp_0_rx_rst_1,
input wire [63:0] qsfp_0_rxd_1,
input wire [7:0] qsfp_0_rxc_1,
input wire qsfp_0_tx_clk_2,
input wire qsfp_0_tx_rst_2,
output wire [63:0] qsfp_0_txd_2,
output wire [7:0] qsfp_0_txc_2,
input wire qsfp_0_rx_clk_2,
input wire qsfp_0_rx_rst_2,
input wire [63:0] qsfp_0_rxd_2,
input wire [7:0] qsfp_0_rxc_2,
input wire qsfp_0_tx_clk_3,
input wire qsfp_0_tx_rst_3,
output wire [63:0] qsfp_0_txd_3,
output wire [7:0] qsfp_0_txc_3,
input wire qsfp_0_rx_clk_3,
input wire qsfp_0_rx_rst_3,
input wire [63:0] qsfp_0_rxd_3,
input wire [7:0] qsfp_0_rxc_3,
input wire qsfp_1_tx_clk_0,
input wire qsfp_1_tx_rst_0,
output wire [63:0] qsfp_1_txd_0,
output wire [7:0] qsfp_1_txc_0,
input wire qsfp_1_rx_clk_0,
input wire qsfp_1_rx_rst_0,
input wire [63:0] qsfp_1_rxd_0,
input wire [7:0] qsfp_1_rxc_0,
input wire qsfp_1_tx_clk_1,
input wire qsfp_1_tx_rst_1,
output wire [63:0] qsfp_1_txd_1,
output wire [7:0] qsfp_1_txc_1,
input wire qsfp_1_rx_clk_1,
input wire qsfp_1_rx_rst_1,
input wire [63:0] qsfp_1_rxd_1,
input wire [7:0] qsfp_1_rxc_1,
input wire qsfp_1_tx_clk_2,
input wire qsfp_1_tx_rst_2,
output wire [63:0] qsfp_1_txd_2,
output wire [7:0] qsfp_1_txc_2,
input wire qsfp_1_rx_clk_2,
input wire qsfp_1_rx_rst_2,
input wire [63:0] qsfp_1_rxd_2,
input wire [7:0] qsfp_1_rxc_2,
input wire qsfp_1_tx_clk_3,
input wire qsfp_1_tx_rst_3,
output wire [63:0] qsfp_1_txd_3,
output wire [7:0] qsfp_1_txc_3,
input wire qsfp_1_rx_clk_3,
input wire qsfp_1_rx_rst_3,
input wire [63:0] qsfp_1_rxd_3,
input wire [7:0] qsfp_1_rxc_3
);
// AXI between MAC and Ethernet modules
wire [63:0] rx_axis_tdata;
wire [7:0] rx_axis_tkeep;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;
wire [63:0] tx_axis_tdata;
wire [7:0] tx_axis_tkeep;
wire tx_axis_tvalid;
wire tx_axis_tready;
wire tx_axis_tlast;
wire tx_axis_tuser;
// Ethernet frame between Ethernet modules and UDP stack
wire rx_eth_hdr_ready;
wire rx_eth_hdr_valid;
wire [47:0] rx_eth_dest_mac;
wire [47:0] rx_eth_src_mac;
wire [15:0] rx_eth_type;
wire [63:0] rx_eth_payload_axis_tdata;
wire [7:0] rx_eth_payload_axis_tkeep;
wire rx_eth_payload_axis_tvalid;
wire rx_eth_payload_axis_tready;
wire rx_eth_payload_axis_tlast;
wire rx_eth_payload_axis_tuser;
wire tx_eth_hdr_ready;
wire tx_eth_hdr_valid;
wire [47:0] tx_eth_dest_mac;
wire [47:0] tx_eth_src_mac;
wire [15:0] tx_eth_type;
wire [63:0] tx_eth_payload_axis_tdata;
wire [7:0] tx_eth_payload_axis_tkeep;
wire tx_eth_payload_axis_tvalid;
wire tx_eth_payload_axis_tready;
wire tx_eth_payload_axis_tlast;
wire tx_eth_payload_axis_tuser;
// IP frame connections
wire rx_ip_hdr_valid;
wire rx_ip_hdr_ready;
wire [47:0] rx_ip_eth_dest_mac;
wire [47:0] rx_ip_eth_src_mac;
wire [15:0] rx_ip_eth_type;
wire [3:0] rx_ip_version;
wire [3:0] rx_ip_ihl;
wire [5:0] rx_ip_dscp;
wire [1:0] rx_ip_ecn;
wire [15:0] rx_ip_length;
wire [15:0] rx_ip_identification;
wire [2:0] rx_ip_flags;
wire [12:0] rx_ip_fragment_offset;
wire [7:0] rx_ip_ttl;
wire [7:0] rx_ip_protocol;
wire [15:0] rx_ip_header_checksum;
wire [31:0] rx_ip_source_ip;
wire [31:0] rx_ip_dest_ip;
wire [63:0] rx_ip_payload_axis_tdata;
wire [7:0] rx_ip_payload_axis_tkeep;
wire rx_ip_payload_axis_tvalid;
wire rx_ip_payload_axis_tready;
wire rx_ip_payload_axis_tlast;
wire rx_ip_payload_axis_tuser;
wire tx_ip_hdr_valid;
wire tx_ip_hdr_ready;
wire [5:0] tx_ip_dscp;
wire [1:0] tx_ip_ecn;
wire [15:0] tx_ip_length;
wire [7:0] tx_ip_ttl;
wire [7:0] tx_ip_protocol;
wire [31:0] tx_ip_source_ip;
wire [31:0] tx_ip_dest_ip;
wire [63:0] tx_ip_payload_axis_tdata;
wire [7:0] tx_ip_payload_axis_tkeep;
wire tx_ip_payload_axis_tvalid;
wire tx_ip_payload_axis_tready;
wire tx_ip_payload_axis_tlast;
wire tx_ip_payload_axis_tuser;
// UDP frame connections
wire rx_udp_hdr_valid;
wire rx_udp_hdr_ready;
wire [47:0] rx_udp_eth_dest_mac;
wire [47:0] rx_udp_eth_src_mac;
wire [15:0] rx_udp_eth_type;
wire [3:0] rx_udp_ip_version;
wire [3:0] rx_udp_ip_ihl;
wire [5:0] rx_udp_ip_dscp;
wire [1:0] rx_udp_ip_ecn;
wire [15:0] rx_udp_ip_length;
wire [15:0] rx_udp_ip_identification;
wire [2:0] rx_udp_ip_flags;
wire [12:0] rx_udp_ip_fragment_offset;
wire [7:0] rx_udp_ip_ttl;
wire [7:0] rx_udp_ip_protocol;
wire [15:0] rx_udp_ip_header_checksum;
wire [31:0] rx_udp_ip_source_ip;
wire [31:0] rx_udp_ip_dest_ip;
wire [15:0] rx_udp_source_port;
wire [15:0] rx_udp_dest_port;
wire [15:0] rx_udp_length;
wire [15:0] rx_udp_checksum;
wire [63:0] rx_udp_payload_axis_tdata;
wire [7:0] rx_udp_payload_axis_tkeep;
wire rx_udp_payload_axis_tvalid;
wire rx_udp_payload_axis_tready;
wire rx_udp_payload_axis_tlast;
wire rx_udp_payload_axis_tuser;
wire tx_udp_hdr_valid;
wire tx_udp_hdr_ready;
wire [5:0] tx_udp_ip_dscp;
wire [1:0] tx_udp_ip_ecn;
wire [7:0] tx_udp_ip_ttl;
wire [31:0] tx_udp_ip_source_ip;
wire [31:0] tx_udp_ip_dest_ip;
wire [15:0] tx_udp_source_port;
wire [15:0] tx_udp_dest_port;
wire [15:0] tx_udp_length;
wire [15:0] tx_udp_checksum;
wire [63:0] tx_udp_payload_axis_tdata;
wire [7:0] tx_udp_payload_axis_tkeep;
wire tx_udp_payload_axis_tvalid;
wire tx_udp_payload_axis_tready;
wire tx_udp_payload_axis_tlast;
wire tx_udp_payload_axis_tuser;
wire [63:0] rx_fifo_udp_payload_axis_tdata;
wire [7:0] rx_fifo_udp_payload_axis_tkeep;
wire rx_fifo_udp_payload_axis_tvalid;
wire rx_fifo_udp_payload_axis_tready;
wire rx_fifo_udp_payload_axis_tlast;
wire rx_fifo_udp_payload_axis_tuser;
wire [63:0] tx_fifo_udp_payload_axis_tdata;
wire [7:0] tx_fifo_udp_payload_axis_tkeep;
wire tx_fifo_udp_payload_axis_tvalid;
wire tx_fifo_udp_payload_axis_tready;
wire tx_fifo_udp_payload_axis_tlast;
wire tx_fifo_udp_payload_axis_tuser;
// Configuration
wire [47:0] local_mac = 48'h02_00_00_00_00_00;
wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128};
wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
// IP ports not used
assign rx_ip_hdr_ready = 1;
assign rx_ip_payload_axis_tready = 1;
assign tx_ip_hdr_valid = 0;
assign tx_ip_dscp = 0;
assign tx_ip_ecn = 0;
assign tx_ip_length = 0;
assign tx_ip_ttl = 0;
assign tx_ip_protocol = 0;
assign tx_ip_source_ip = 0;
assign tx_ip_dest_ip = 0;
assign tx_ip_payload_axis_tdata = 0;
assign tx_ip_payload_axis_tkeep = 0;
assign tx_ip_payload_axis_tvalid = 0;
assign tx_ip_payload_axis_tlast = 0;
assign tx_ip_payload_axis_tuser = 0;
// Loop back UDP
wire match_cond = rx_udp_dest_port == 1234;
wire no_match = !match_cond;
reg match_cond_reg = 0;
reg no_match_reg = 0;
always @(posedge clk) begin
if (rst) begin
match_cond_reg <= 0;
no_match_reg <= 0;
end else begin
if (rx_udp_payload_axis_tvalid) begin
if ((!match_cond_reg && !no_match_reg) ||
(rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
match_cond_reg <= match_cond;
no_match_reg <= no_match;
end
end else begin
match_cond_reg <= 0;
no_match_reg <= 0;
end
end
end
assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
assign tx_udp_ip_dscp = 0;
assign tx_udp_ip_ecn = 0;
assign tx_udp_ip_ttl = 64;
assign tx_udp_ip_source_ip = local_ip;
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
assign tx_udp_source_port = rx_udp_dest_port;
assign tx_udp_dest_port = rx_udp_source_port;
assign tx_udp_length = rx_udp_length;
assign tx_udp_checksum = 0;
assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
assign tx_udp_payload_axis_tkeep = tx_fifo_udp_payload_axis_tkeep;
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;
assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
assign rx_fifo_udp_payload_axis_tkeep = rx_udp_payload_axis_tkeep;
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;
// Place first payload byte onto LEDs
reg valid_last = 0;
reg [7:0] led_reg = 0;
always @(posedge clk) begin
if (rst) begin
led_reg <= 0;
end else begin
valid_last <= tx_udp_payload_axis_tvalid;
if (tx_udp_payload_axis_tvalid && !valid_last) begin
led_reg <= tx_udp_payload_axis_tdata;
end
end
end
assign user_led_g = ~led_reg[1:0];
assign user_led_r = 1'b1;
assign front_led = 2'b00;
assign qsfp_0_txd_1 = 64'h0707070707070707;
assign qsfp_0_txc_1 = 8'hff;
assign qsfp_0_txd_2 = 64'h0707070707070707;
assign qsfp_0_txc_2 = 8'hff;
assign qsfp_0_txd_3 = 64'h0707070707070707;
assign qsfp_0_txc_3 = 8'hff;
assign qsfp_1_txd_0 = 64'h0707070707070707;
assign qsfp_1_txc_0 = 8'hff;
assign qsfp_1_txd_1 = 64'h0707070707070707;
assign qsfp_1_txc_1 = 8'hff;
assign qsfp_1_txd_2 = 64'h0707070707070707;
assign qsfp_1_txc_2 = 8'hff;
assign qsfp_1_txd_3 = 64'h0707070707070707;
assign qsfp_1_txc_3 = 8'hff;
eth_mac_10g_fifo #(
.ENABLE_PADDING(1),
.ENABLE_DIC(1),
.MIN_FRAME_LENGTH(64),
.TX_FIFO_DEPTH(4096),
.TX_FRAME_FIFO(1),
.RX_FIFO_DEPTH(4096),
.RX_FRAME_FIFO(1)
)
eth_mac_10g_fifo_inst (
.rx_clk(qsfp_0_rx_clk_0),
.rx_rst(qsfp_0_rx_rst_0),
.tx_clk(qsfp_0_tx_clk_0),
.tx_rst(qsfp_0_tx_rst_0),
.logic_clk(clk),
.logic_rst(rst),
.tx_axis_tdata(tx_axis_tdata),
.tx_axis_tkeep(tx_axis_tkeep),
.tx_axis_tvalid(tx_axis_tvalid),
.tx_axis_tready(tx_axis_tready),
.tx_axis_tlast(tx_axis_tlast),
.tx_axis_tuser(tx_axis_tuser),
.rx_axis_tdata(rx_axis_tdata),
.rx_axis_tkeep(rx_axis_tkeep),
.rx_axis_tvalid(rx_axis_tvalid),
.rx_axis_tready(rx_axis_tready),
.rx_axis_tlast(rx_axis_tlast),
.rx_axis_tuser(rx_axis_tuser),
.xgmii_rxd(qsfp_0_rxd_0),
.xgmii_rxc(qsfp_0_rxc_0),
.xgmii_txd(qsfp_0_txd_0),
.xgmii_txc(qsfp_0_txc_0),
.tx_fifo_overflow(),
.tx_fifo_bad_frame(),
.tx_fifo_good_frame(),
.rx_error_bad_frame(),
.rx_error_bad_fcs(),
.rx_fifo_overflow(),
.rx_fifo_bad_frame(),
.rx_fifo_good_frame(),
.ifg_delay(8'd12)
);
eth_axis_rx #(
.DATA_WIDTH(64)
)
eth_axis_rx_inst (
.clk(clk),
.rst(rst),
// AXI input
.s_axis_tdata(rx_axis_tdata),
.s_axis_tkeep(rx_axis_tkeep),
.s_axis_tvalid(rx_axis_tvalid),
.s_axis_tready(rx_axis_tready),
.s_axis_tlast(rx_axis_tlast),
.s_axis_tuser(rx_axis_tuser),
// Ethernet frame output
.m_eth_hdr_valid(rx_eth_hdr_valid),
.m_eth_hdr_ready(rx_eth_hdr_ready),
.m_eth_dest_mac(rx_eth_dest_mac),
.m_eth_src_mac(rx_eth_src_mac),
.m_eth_type(rx_eth_type),
.m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
.m_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
.m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
.m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
.m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
.m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
// Status signals
.busy(),
.error_header_early_termination()
);
eth_axis_tx #(
.DATA_WIDTH(64)
)
eth_axis_tx_inst (
.clk(clk),
.rst(rst),
// Ethernet frame input
.s_eth_hdr_valid(tx_eth_hdr_valid),
.s_eth_hdr_ready(tx_eth_hdr_ready),
.s_eth_dest_mac(tx_eth_dest_mac),
.s_eth_src_mac(tx_eth_src_mac),
.s_eth_type(tx_eth_type),
.s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
.s_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
.s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
.s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
.s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
.s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
// AXI output
.m_axis_tdata(tx_axis_tdata),
.m_axis_tkeep(tx_axis_tkeep),
.m_axis_tvalid(tx_axis_tvalid),
.m_axis_tready(tx_axis_tready),
.m_axis_tlast(tx_axis_tlast),
.m_axis_tuser(tx_axis_tuser),
// Status signals
.busy()
);
udp_complete_64
udp_complete_inst (
.clk(clk),
.rst(rst),
// Ethernet frame input
.s_eth_hdr_valid(rx_eth_hdr_valid),
.s_eth_hdr_ready(rx_eth_hdr_ready),
.s_eth_dest_mac(rx_eth_dest_mac),
.s_eth_src_mac(rx_eth_src_mac),
.s_eth_type(rx_eth_type),
.s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
.s_eth_payload_axis_tkeep(rx_eth_payload_axis_tkeep),
.s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
.s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
.s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
.s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
// Ethernet frame output
.m_eth_hdr_valid(tx_eth_hdr_valid),
.m_eth_hdr_ready(tx_eth_hdr_ready),
.m_eth_dest_mac(tx_eth_dest_mac),
.m_eth_src_mac(tx_eth_src_mac),
.m_eth_type(tx_eth_type),
.m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
.m_eth_payload_axis_tkeep(tx_eth_payload_axis_tkeep),
.m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
.m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
.m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
.m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
// IP frame input
.s_ip_hdr_valid(tx_ip_hdr_valid),
.s_ip_hdr_ready(tx_ip_hdr_ready),
.s_ip_dscp(tx_ip_dscp),
.s_ip_ecn(tx_ip_ecn),
.s_ip_length(tx_ip_length),
.s_ip_ttl(tx_ip_ttl),
.s_ip_protocol(tx_ip_protocol),
.s_ip_source_ip(tx_ip_source_ip),
.s_ip_dest_ip(tx_ip_dest_ip),
.s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
.s_ip_payload_axis_tkeep(tx_ip_payload_axis_tkeep),
.s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
.s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
.s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
.s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
// IP frame output
.m_ip_hdr_valid(rx_ip_hdr_valid),
.m_ip_hdr_ready(rx_ip_hdr_ready),
.m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
.m_ip_eth_src_mac(rx_ip_eth_src_mac),
.m_ip_eth_type(rx_ip_eth_type),
.m_ip_version(rx_ip_version),
.m_ip_ihl(rx_ip_ihl),
.m_ip_dscp(rx_ip_dscp),
.m_ip_ecn(rx_ip_ecn),
.m_ip_length(rx_ip_length),
.m_ip_identification(rx_ip_identification),
.m_ip_flags(rx_ip_flags),
.m_ip_fragment_offset(rx_ip_fragment_offset),
.m_ip_ttl(rx_ip_ttl),
.m_ip_protocol(rx_ip_protocol),
.m_ip_header_checksum(rx_ip_header_checksum),
.m_ip_source_ip(rx_ip_source_ip),
.m_ip_dest_ip(rx_ip_dest_ip),
.m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
.m_ip_payload_axis_tkeep(rx_ip_payload_axis_tkeep),
.m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
.m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
.m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
.m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
// UDP frame input
.s_udp_hdr_valid(tx_udp_hdr_valid),
.s_udp_hdr_ready(tx_udp_hdr_ready),
.s_udp_ip_dscp(tx_udp_ip_dscp),
.s_udp_ip_ecn(tx_udp_ip_ecn),
.s_udp_ip_ttl(tx_udp_ip_ttl),
.s_udp_ip_source_ip(tx_udp_ip_source_ip),
.s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
.s_udp_source_port(tx_udp_source_port),
.s_udp_dest_port(tx_udp_dest_port),
.s_udp_length(tx_udp_length),
.s_udp_checksum(tx_udp_checksum),
.s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
.s_udp_payload_axis_tkeep(tx_udp_payload_axis_tkeep),
.s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
.s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
.s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
.s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
// UDP frame output
.m_udp_hdr_valid(rx_udp_hdr_valid),
.m_udp_hdr_ready(rx_udp_hdr_ready),
.m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
.m_udp_eth_src_mac(rx_udp_eth_src_mac),
.m_udp_eth_type(rx_udp_eth_type),
.m_udp_ip_version(rx_udp_ip_version),
.m_udp_ip_ihl(rx_udp_ip_ihl),
.m_udp_ip_dscp(rx_udp_ip_dscp),
.m_udp_ip_ecn(rx_udp_ip_ecn),
.m_udp_ip_length(rx_udp_ip_length),
.m_udp_ip_identification(rx_udp_ip_identification),
.m_udp_ip_flags(rx_udp_ip_flags),
.m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
.m_udp_ip_ttl(rx_udp_ip_ttl),
.m_udp_ip_protocol(rx_udp_ip_protocol),
.m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
.m_udp_ip_source_ip(rx_udp_ip_source_ip),
.m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
.m_udp_source_port(rx_udp_source_port),
.m_udp_dest_port(rx_udp_dest_port),
.m_udp_length(rx_udp_length),
.m_udp_checksum(rx_udp_checksum),
.m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
.m_udp_payload_axis_tkeep(rx_udp_payload_axis_tkeep),
.m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
.m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
.m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
.m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
// Status signals
.ip_rx_busy(),
.ip_tx_busy(),
.udp_rx_busy(),
.udp_tx_busy(),
.ip_rx_error_header_early_termination(),
.ip_rx_error_payload_early_termination(),
.ip_rx_error_invalid_header(),
.ip_rx_error_invalid_checksum(),
.ip_tx_error_payload_early_termination(),
.ip_tx_error_arp_failed(),
.udp_rx_error_header_early_termination(),
.udp_rx_error_payload_early_termination(),
.udp_tx_error_payload_early_termination(),
// Configuration
.local_mac(local_mac),
.local_ip(local_ip),
.gateway_ip(gateway_ip),
.subnet_mask(subnet_mask),
.clear_arp_cache(1'b0)
);
axis_fifo #(
.DEPTH(8192),
.DATA_WIDTH(64),
.KEEP_ENABLE(1),
.KEEP_WIDTH(8),
.ID_ENABLE(0),
.DEST_ENABLE(0),
.USER_ENABLE(1),
.USER_WIDTH(1),
.FRAME_FIFO(0)
)
udp_payload_fifo (
.clk(clk),
.rst(rst),
// AXI input
.s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
.s_axis_tkeep(rx_fifo_udp_payload_axis_tkeep),
.s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
.s_axis_tready(rx_fifo_udp_payload_axis_tready),
.s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
.s_axis_tid(0),
.s_axis_tdest(0),
.s_axis_tuser(rx_fifo_udp_payload_axis_tuser),
// AXI output
.m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
.m_axis_tkeep(tx_fifo_udp_payload_axis_tkeep),
.m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
.m_axis_tready(tx_fifo_udp_payload_axis_tready),
.m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
.m_axis_tid(),
.m_axis_tdest(),
.m_axis_tuser(tx_fifo_udp_payload_axis_tuser),
// Status
.status_overflow(),
.status_bad_frame(),
.status_good_frame()
);
endmodule
`resetall

View File

@ -1,62 +0,0 @@
/*
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

@ -1,95 +0,0 @@
# Copyright (c) 2020 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.
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 += ../../lib/eth/rtl/eth_mac_10g_fifo.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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A := value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
iverilog_dump.v:
echo 'module iverilog_dump();' > $@
echo 'initial begin' >> $@
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
echo 'end' >> $@
echo 'endmodule' >> $@
clean::
@rm -rf iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -1,289 +0,0 @@
"""
Copyright (c) 2020 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.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.start_soon(Clock(dut.clk, 6.4, units="ns").start())
# Ethernet
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_0, 6.4, units="ns").start())
self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_0, 6.4, units="ns").start())
self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_1, 6.4, units="ns").start())
self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_1, 6.4, units="ns").start())
self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_2, 6.4, units="ns").start())
self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_2, 6.4, units="ns").start())
self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_0_rx_clk_3, 6.4, units="ns").start())
self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_0_tx_clk_3, 6.4, units="ns").start())
self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_0, 6.4, units="ns").start())
self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_0, 6.4, units="ns").start())
self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_1, 6.4, units="ns").start())
self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_1, 6.4, units="ns").start())
self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_2, 6.4, units="ns").start())
self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_2, 6.4, units="ns").start())
self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2)
cocotb.start_soon(Clock(dut.qsfp_1_rx_clk_3, 6.4, units="ns").start())
self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3)
cocotb.start_soon(Clock(dut.qsfp_1_tx_clk_3, 6.4, units="ns").start())
self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3)
dut.user_sw.setimmediatevalue(0)
async def init(self):
self.dut.rst.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0)
self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0)
self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst.value = 1
self.dut.qsfp_0_rx_rst_0.value = 1
self.dut.qsfp_0_tx_rst_0.value = 1
self.dut.qsfp_0_rx_rst_1.value = 1
self.dut.qsfp_0_tx_rst_1.value = 1
self.dut.qsfp_0_rx_rst_2.value = 1
self.dut.qsfp_0_tx_rst_2.value = 1
self.dut.qsfp_0_rx_rst_3.value = 1
self.dut.qsfp_0_tx_rst_3.value = 1
self.dut.qsfp_1_rx_rst_0.value = 1
self.dut.qsfp_1_tx_rst_0.value = 1
self.dut.qsfp_1_rx_rst_1.value = 1
self.dut.qsfp_1_tx_rst_1.value = 1
self.dut.qsfp_1_rx_rst_2.value = 1
self.dut.qsfp_1_tx_rst_2.value = 1
self.dut.qsfp_1_rx_rst_3.value = 1
self.dut.qsfp_1_tx_rst_3.value = 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst.value = 0
self.dut.qsfp_0_rx_rst_0.value = 0
self.dut.qsfp_0_tx_rst_0.value = 0
self.dut.qsfp_0_rx_rst_1.value = 0
self.dut.qsfp_0_tx_rst_1.value = 0
self.dut.qsfp_0_rx_rst_2.value = 0
self.dut.qsfp_0_tx_rst_2.value = 0
self.dut.qsfp_0_rx_rst_3.value = 0
self.dut.qsfp_0_tx_rst_3.value = 0
self.dut.qsfp_1_rx_rst_0.value = 0
self.dut.qsfp_1_tx_rst_0.value = 0
self.dut.qsfp_1_rx_rst_1.value = 0
self.dut.qsfp_1_tx_rst_1.value = 0
self.dut.qsfp_1_rx_rst_2.value = 0
self.dut.qsfp_1_tx_rst_2.value = 0
self.dut.qsfp_1_rx_rst_3.value = 0
self.dut.qsfp_1_tx_rst_3.value = 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp_0_0_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp_0_0_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# 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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(eth_rtl_dir, "eth_mac_10g_fifo.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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
)

View File

@ -58,6 +58,9 @@ XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
# IP
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit

View File

@ -0,0 +1,50 @@
# Copyright (c) 2023 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.
# Transceiver configuration
set eth_xcvr_freerun_freq {125}
set eth_xcvr_line_rate {25.78125}
set eth_xcvr_sec_line_rate {0}
set eth_xcvr_refclk_freq {161.1328125}
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_rx_eq_mode {DFE}
set xcvr_config [dict create]
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
if {$eth_xcvr_sec_line_rate != 0} {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
} else {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
}
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]

View File

@ -58,6 +58,9 @@ XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl
# IP
IP_TCL_FILES += ip/eth_xcvr_gt.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(FPGA_TOP).bit

View File

@ -0,0 +1,50 @@
# Copyright (c) 2023 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.
# Transceiver configuration
set eth_xcvr_freerun_freq {125}
set eth_xcvr_line_rate {10.3125}
set eth_xcvr_sec_line_rate {0}
set eth_xcvr_refclk_freq {161.1328125}
set eth_xcvr_qpll_fracn [expr {int(fmod($eth_xcvr_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_sec_qpll_fracn [expr {int(fmod($eth_xcvr_sec_line_rate*1000/2 / $eth_xcvr_refclk_freq, 1)*pow(2, 24))}]
set eth_xcvr_rx_eq_mode {DFE}
set xcvr_config [dict create]
dict set xcvr_config CONFIG.TX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.TX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.TX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_LINE_RATE $eth_xcvr_line_rate
dict set xcvr_config CONFIG.RX_QPLL_FRACN_NUMERATOR $eth_xcvr_qpll_fracn
dict set xcvr_config CONFIG.RX_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
dict set xcvr_config CONFIG.RX_EQ_MODE $eth_xcvr_rx_eq_mode
if {$eth_xcvr_sec_line_rate != 0} {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE true
dict set xcvr_config CONFIG.SECONDARY_QPLL_FRACN_NUMERATOR $eth_xcvr_sec_qpll_fracn
dict set xcvr_config CONFIG.SECONDARY_QPLL_LINE_RATE $eth_xcvr_sec_line_rate
dict set xcvr_config CONFIG.SECONDARY_QPLL_REFCLK_FREQUENCY $eth_xcvr_refclk_freq
} else {
dict set xcvr_config CONFIG.SECONDARY_QPLL_ENABLE false
}
dict set xcvr_config CONFIG.FREERUN_FREQUENCY $eth_xcvr_freerun_freq
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_full]
set_property -dict $xcvr_config [get_ips eth_xcvr_gt_channel]