diff --git a/fpga/lib/eth/README.md b/fpga/lib/eth/README.md index 27a4b72e5..28f7246fd 100644 --- a/fpga/lib/eth/README.md +++ b/fpga/lib/eth/README.md @@ -42,15 +42,19 @@ following boards: * Exablaze ExaNIC X10 (Xilinx Kintex UltraScale XCKU035) * Exablaze ExaNIC X25 (Xilinx Kintex UltraScale+ XCKU3P) * HiTech Global HTG-V6HXT-100GIG-565 (Xilinx Virtex 6 XC6VHX565T) +* Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P) * Xilinx KC705 (Xilinx Kintex 7 XC7K325T) * Xilinx ML605 (Xilinx Virtex 6 XC6VLX240T) * NetFPGA SUME (Xilinx Virtex 7 XC7V690T) * Digilent Nexys Video (Xilinx Artix 7 XC7XC7A200T) * Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50) +* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200) +* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250) * Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280) * Xilinx VCU108 (Xilinx Virtex UltraScale XCVU095) * Xilinx VCU118 (Xilinx Virtex UltraScale+ XCVU9P) * Xilinx VCU1525 (Xilinx Virtex UltraScale+ XCVU9P) +* Xilinx ZCU102 (Xilinx Zynq UltraScale+ XCZU9EG) * Xilinx ZCU106 (Xilinx Zynq UltraScale+ XCZU7EV) ## Documentation diff --git a/fpga/lib/eth/example/AU200/fpga_10g/Makefile b/fpga/lib/eth/example/AU200/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# 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 diff --git a/fpga/lib/eth/example/AU200/fpga_10g/README.md b/fpga/lib/eth/example/AU200/fpga_10g/README.md new file mode 100644 index 000000000..24decdba6 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/README.md @@ -0,0 +1,26 @@ +# Verilog Ethernet Alveo U200 Example Design + +## Introduction + +This example design targets the Xilinx Alveo U200 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. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcu200-fsgd2104-2-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the Alveo U200 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. + + diff --git a/fpga/lib/eth/example/AU200/fpga_10g/common/vivado.mk b/fpga/lib/eth/example/AU200/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..ee83637e0 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/common/vivado.mk @@ -0,0 +1,123 @@ +################################################################### +# +# 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: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean: + -rm -rf *.log *.jou *.cache *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: 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) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/eth/example/AU200/fpga_10g/fpga.xdc b/fpga/lib/eth/example/AU200/fpga_10g/fpga.xdc new file mode 100644 index 000000000..33046e6df --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/fpga.xdc @@ -0,0 +1,215 @@ +# XDC constraints for the Xilinx Alveo U200 board +# part: xcu200-fsgd2104-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.SPI_OPCODE 8'h6B [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design] + +# System clocks +# 300 MHz (DDR 0) +#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p] +#set_property -dict {LOC AY38 IOSTANDARD LVDS} [get_ports clk_300mhz_0_n] +#create_clock -period 3.333 -name clk_300mhz_0 [get_ports clk_300mhz_0_p] + +# 300 MHz (DDR 1) +#set_property -dict {LOC AW20 IOSTANDARD LVDS} [get_ports clk_300mhz_1_p] +#set_property -dict {LOC AW19 IOSTANDARD LVDS} [get_ports clk_300mhz_1_n] +#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] + +# 300 MHz (DDR 2) +#set_property -dict {LOC F32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_p] +#set_property -dict {LOC E32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_n] +#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] + +# 300 MHz (DDR 3) +#set_property -dict {LOC J16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_p] +#set_property -dict {LOC H16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_n] +#create_clock -period 3.333 -name clk_300mhz_3 [get_ports clk_300mhz_3_p] + +# SI570 user clock +#set_property -dict {LOC AU19 IOSTANDARD LVDS} [get_ports clk_user_p] +#set_property -dict {LOC AV19 IOSTANDARD LVDS} [get_ports clk_user_n] +#create_clock -period 6.400 -name clk_user [get_ports clk_user_p] + +# LEDs +set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] + +# Reset button +set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset] + +# DIP switches +set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_txd] +set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_rxd] + +# QSFP28 Interfaces +set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12 +set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12 +#set_property -dict {LOC M11 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U14.4 via U43.13 +#set_property -dict {LOC M10 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U14.5 via U43.14 +set_property -dict {LOC K11 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U9.18 +#set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17 +set_property -dict {LOC BE16 IOSTANDARD LVCMOS12} [get_ports qsfp0_modsell] +set_property -dict {LOC BE17 IOSTANDARD LVCMOS12} [get_ports qsfp0_resetl] +set_property -dict {LOC BE20 IOSTANDARD LVCMOS12} [get_ports qsfp0_modprsl] +set_property -dict {LOC BE21 IOSTANDARD LVCMOS12} [get_ports qsfp0_intl] +set_property -dict {LOC BD18 IOSTANDARD LVCMOS12} [get_ports qsfp0_lpmode] +set_property -dict {LOC AT22 IOSTANDARD LVCMOS12} [get_ports qsfp0_refclk_reset] +set_property -dict {LOC AT20 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[0]}] +set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}] + +# 156.25 MHz MGT reference clock (from SI570) +#create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports qsfp0_mgt_refclk_0_p] + +# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01) +#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p] + +# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10) +create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p] + +set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC T11 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U14.4 via U43.15 +#set_property -dict {LOC T10 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U14.5 via U43.16 +#set_property -dict {LOC P11 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U12.18 +#set_property -dict {LOC P10 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U12.17 +set_property -dict {LOC AY20 IOSTANDARD LVCMOS12} [get_ports qsfp1_modsell] +set_property -dict {LOC BC18 IOSTANDARD LVCMOS12} [get_ports qsfp1_resetl] +set_property -dict {LOC BC19 IOSTANDARD LVCMOS12} [get_ports qsfp1_modprsl] +set_property -dict {LOC AV21 IOSTANDARD LVCMOS12} [get_ports qsfp1_intl] +set_property -dict {LOC AV22 IOSTANDARD LVCMOS12} [get_ports qsfp1_lpmode] +set_property -dict {LOC AR21 IOSTANDARD LVCMOS12} [get_ports qsfp1_refclk_reset] +set_property -dict {LOC AR22 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[0]}] +set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}] + +# 156.25 MHz MGT reference clock (from SI570) +#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] + +# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01) +#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p] + +# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10) +#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p] + +# I2C interface +#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset] +set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda] + +# PCIe Interface +#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8 +#set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AM11 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_226 +#set_property -dict {LOC AM10 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_226 +#set_property -dict {LOC BD21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_p] + + diff --git a/fpga/lib/eth/example/AU200/fpga_10g/fpga/Makefile b/fpga/lib/eth/example/AU200/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..413e36bc4 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/fpga/Makefile @@ -0,0 +1,72 @@ + +# FPGA settings +FPGA_PART = xcu200-fsgd2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/sync_reset.tcl + +# IP +IP_TCL_FILES = ip/gtwizard_ultrascale_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + diff --git a/fpga/lib/eth/example/AU200/fpga_10g/ip/gtwizard_ultrascale_0.tcl b/fpga/lib/eth/example/AU200/fpga_10g/ip/gtwizard_ultrascale_0.tcl new file mode 100644 index 000000000..73e63d46f --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/ip/gtwizard_ultrascale_0.tcl @@ -0,0 +1,21 @@ + +create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name gtwizard_ultrascale_0 + +set_property -dict [list CONFIG.preset {GTY-10GBASE-R}] [get_ips gtwizard_ultrascale_0] + +set_property -dict [list \ + CONFIG.CHANNEL_ENABLE {X1Y51 X1Y50 X1Y49 X1Y48 X1Y47 X1Y46 X1Y45 X1Y44} \ + CONFIG.TX_MASTER_CHANNEL {X1Y48} \ + CONFIG.RX_MASTER_CHANNEL {X1Y48} \ + CONFIG.TX_LINE_RATE {10.3125} \ + CONFIG.TX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.TX_USER_DATA_WIDTH {64} \ + CONFIG.TX_INT_DATA_WIDTH {64} \ + CONFIG.RX_LINE_RATE {10.3125} \ + CONFIG.RX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.RX_USER_DATA_WIDTH {64} \ + CONFIG.RX_INT_DATA_WIDTH {64} \ + CONFIG.RX_REFCLK_SOURCE {X1Y51 clk1 X1Y50 clk1 X1Y49 clk1 X1Y48 clk1 X1Y47 clk1+1 X1Y46 clk1+1 X1Y45 clk1+1 X1Y44 clk1+1} \ + CONFIG.TX_REFCLK_SOURCE {X1Y51 clk1 X1Y50 clk1 X1Y49 clk1 X1Y48 clk1 X1Y47 clk1+1 X1Y46 clk1+1 X1Y45 clk1+1 X1Y44 clk1+1} \ + CONFIG.FREERUN_FREQUENCY {125} \ +] [get_ips gtwizard_ultrascale_0] diff --git a/fpga/lib/eth/example/AU200/fpga_10g/lib/eth b/fpga/lib/eth/example/AU200/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/rtl/debounce_switch.v b/fpga/lib/eth/example/AU200/fpga_10g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga.v b/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..5a5a66c0e --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga.v @@ -0,0 +1,986 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Reset: Push button, active low + */ + input wire reset, + + /* + * GPIO + */ + input wire [3:0] sw, + output wire [2:0] led, + + /* + * I2C for board management + */ + inout wire i2c_scl, + inout wire i2c_sda, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp0_tx1_p, + output wire qsfp0_tx1_n, + input wire qsfp0_rx1_p, + input wire qsfp0_rx1_n, + output wire qsfp0_tx2_p, + output wire qsfp0_tx2_n, + input wire qsfp0_rx2_p, + input wire qsfp0_rx2_n, + output wire qsfp0_tx3_p, + output wire qsfp0_tx3_n, + input wire qsfp0_rx3_p, + input wire qsfp0_rx3_n, + output wire qsfp0_tx4_p, + output wire qsfp0_tx4_n, + input wire qsfp0_rx4_p, + input wire qsfp0_rx4_n, + // input wire qsfp0_mgt_refclk_0_p, + // input wire qsfp0_mgt_refclk_0_n, + input wire qsfp0_mgt_refclk_1_p, + input wire qsfp0_mgt_refclk_1_n, + output wire qsfp0_modsell, + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + output wire qsfp0_refclk_reset, + output wire [1:0] qsfp0_fs, + + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + // input wire qsfp1_mgt_refclk_0_p, + // input wire qsfp1_mgt_refclk_0_n, + // input wire qsfp1_mgt_refclk_1_p, + // input wire qsfp1_mgt_refclk_1_n, + output wire qsfp1_modsell, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + output wire qsfp1_refclk_reset, + output wire [1:0] qsfp1_fs, + + /* + * UART: 500000 bps, 8N1 + */ + output wire uart_rxd, + input wire uart_txd +); + +// Clock and reset + +wire cfgmclk_int; + +wire clk_161mhz_ref_int; + +// 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; +wire mmcm_locked; +wire mmcm_clkfb; + +// MMCM instance +// 161.13 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 64, D = 11 sets Fvco = 937.5 MHz (in range) +// Divide by 7.5 to get output frequency of 125 MHz +MMCME4_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(7.5), + .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(64), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(11), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(6.206), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_161mhz_ref_int), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .out(rst_125mhz_int) +); + +// GPIO +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(4), + .N(4), + .RATE(156000) +) +debounce_switch_inst ( + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + .in({sw}), + .out({sw_int}) +); + +wire uart_txd_int; + +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_156mhz_int), + .in({uart_txd}), + .out({uart_txd_int}) +); + +// SI570 I2C +wire i2c_scl_i; +wire i2c_scl_o = 1'b1; +wire i2c_scl_t = 1'b1; +wire i2c_sda_i; +wire i2c_sda_o = 1'b1; +wire i2c_sda_t = 1'b1; + +assign i2c_scl_i = i2c_scl; +assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; +assign i2c_sda_i = i2c_sda; +assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; + +// startupe3 instance +wire cfgmclk; + +STARTUPE3 +startupe3_inst ( + .CFGCLK(), + .CFGMCLK(cfgmclk), + .DI(4'd0), + .DO(), + .DTS(1'b1), + .EOS(), + .FCSBO(1'b0), + .FCSBTS(1'b1), + .GSR(1'b0), + .GTS(1'b0), + .KEYCLEARB(1'b1), + .PACK(1'b0), + .PREQ(), + .USRCCLKO(1'b0), + .USRCCLKTS(1'b1), + .USRDONEO(1'b0), + .USRDONETS(1'b1) +); + +BUFG +cfgmclk_bufg_inst ( + .I(cfgmclk), + .O(cfgmclk_int) +); + +// configure SI5335 clock generators +reg qsfp_refclk_reset_reg = 1'b1; +reg sys_reset_reg = 1'b1; + +reg [9:0] reset_timer_reg = 0; + +assign mmcm_rst = sys_reset_reg; + +always @(posedge cfgmclk_int) begin + if (&reset_timer_reg) begin + if (qsfp_refclk_reset_reg) begin + qsfp_refclk_reset_reg <= 1'b0; + reset_timer_reg <= 0; + end else begin + qsfp_refclk_reset_reg <= 1'b0; + sys_reset_reg <= 1'b0; + end + end else begin + reset_timer_reg <= reset_timer_reg + 1; + end + + if (!reset) begin + qsfp_refclk_reset_reg <= 1'b1; + sys_reset_reg <= 1'b1; + reset_timer_reg <= 0; + end +end + +// XGMII 10G PHY +assign qsfp0_modsell = 1'b0; +assign qsfp0_resetl = 1'b1; +assign qsfp0_lpmode = 1'b0; +assign qsfp0_refclk_reset = qsfp_refclk_reset_reg; +assign qsfp0_fs = 2'b10; + +wire qsfp0_tx_clk_1_int; +wire qsfp0_tx_rst_1_int; +wire [63:0] qsfp0_txd_1_int; +wire [7:0] qsfp0_txc_1_int; +wire qsfp0_rx_clk_1_int; +wire qsfp0_rx_rst_1_int; +wire [63:0] qsfp0_rxd_1_int; +wire [7:0] qsfp0_rxc_1_int; +wire qsfp0_tx_clk_2_int; +wire qsfp0_tx_rst_2_int; +wire [63:0] qsfp0_txd_2_int; +wire [7:0] qsfp0_txc_2_int; +wire qsfp0_rx_clk_2_int; +wire qsfp0_rx_rst_2_int; +wire [63:0] qsfp0_rxd_2_int; +wire [7:0] qsfp0_rxc_2_int; +wire qsfp0_tx_clk_3_int; +wire qsfp0_tx_rst_3_int; +wire [63:0] qsfp0_txd_3_int; +wire [7:0] qsfp0_txc_3_int; +wire qsfp0_rx_clk_3_int; +wire qsfp0_rx_rst_3_int; +wire [63:0] qsfp0_rxd_3_int; +wire [7:0] qsfp0_rxc_3_int; +wire qsfp0_tx_clk_4_int; +wire qsfp0_tx_rst_4_int; +wire [63:0] qsfp0_txd_4_int; +wire [7:0] qsfp0_txc_4_int; +wire qsfp0_rx_clk_4_int; +wire qsfp0_rx_rst_4_int; +wire [63:0] qsfp0_rxd_4_int; +wire [7:0] qsfp0_rxc_4_int; + +assign qsfp1_modsell = 1'b0; +assign qsfp1_resetl = 1'b1; +assign qsfp1_lpmode = 1'b0; +assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; +assign qsfp1_fs = 2'b10; + +wire qsfp1_tx_clk_1_int; +wire qsfp1_tx_rst_1_int; +wire [63:0] qsfp1_txd_1_int; +wire [7:0] qsfp1_txc_1_int; +wire qsfp1_rx_clk_1_int; +wire qsfp1_rx_rst_1_int; +wire [63:0] qsfp1_rxd_1_int; +wire [7:0] qsfp1_rxc_1_int; +wire qsfp1_tx_clk_2_int; +wire qsfp1_tx_rst_2_int; +wire [63:0] qsfp1_txd_2_int; +wire [7:0] qsfp1_txc_2_int; +wire qsfp1_rx_clk_2_int; +wire qsfp1_rx_rst_2_int; +wire [63:0] qsfp1_rxd_2_int; +wire [7:0] qsfp1_rxc_2_int; +wire qsfp1_tx_clk_3_int; +wire qsfp1_tx_rst_3_int; +wire [63:0] qsfp1_txd_3_int; +wire [7:0] qsfp1_txc_3_int; +wire qsfp1_rx_clk_3_int; +wire qsfp1_rx_rst_3_int; +wire [63:0] qsfp1_rxd_3_int; +wire [7:0] qsfp1_rxc_3_int; +wire qsfp1_tx_clk_4_int; +wire qsfp1_tx_rst_4_int; +wire [63:0] qsfp1_txd_4_int; +wire [7:0] qsfp1_txc_4_int; +wire qsfp1_rx_clk_4_int; +wire qsfp1_rx_rst_4_int; +wire [63:0] qsfp1_rxd_4_int; +wire [7:0] qsfp1_rxc_4_int; + +wire qsfp0_rx_block_lock_1; +wire qsfp0_rx_block_lock_2; +wire qsfp0_rx_block_lock_3; +wire qsfp0_rx_block_lock_4; + +wire qsfp1_rx_block_lock_1; +wire qsfp1_rx_block_lock_2; +wire qsfp1_rx_block_lock_3; +wire qsfp1_rx_block_lock_4; + +wire [7:0] qsfp_gtpowergood; + +wire qsfp0_mgt_refclk_1; +wire qsfp0_mgt_refclk_1_int; +wire qsfp0_mgt_refclk_1_bufg; + +assign clk_161mhz_ref_int = qsfp0_mgt_refclk_1_bufg; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_qsfp0_mgt_refclk_1_inst ( + .I (qsfp0_mgt_refclk_1_p), + .IB (qsfp0_mgt_refclk_1_n), + .CEB (1'b0), + .O (qsfp0_mgt_refclk_1), + .ODIV2 (qsfp0_mgt_refclk_1_int) +); + +BUFG_GT bufg_gt_refclk_inst ( + .CE (&qsfp_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp0_mgt_refclk_1_int), + .O (qsfp0_mgt_refclk_1_bufg) +); + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .out(rst_156mhz_int) +); + +wire [5:0] qsfp0_gt_txheader_1; +wire [63:0] qsfp0_gt_txdata_1; +wire qsfp0_gt_rxgearboxslip_1; +wire [5:0] qsfp0_gt_rxheader_1; +wire [1:0] qsfp0_gt_rxheadervalid_1; +wire [63:0] qsfp0_gt_rxdata_1; +wire [1:0] qsfp0_gt_rxdatavalid_1; + +wire [5:0] qsfp0_gt_txheader_2; +wire [63:0] qsfp0_gt_txdata_2; +wire qsfp0_gt_rxgearboxslip_2; +wire [5:0] qsfp0_gt_rxheader_2; +wire [1:0] qsfp0_gt_rxheadervalid_2; +wire [63:0] qsfp0_gt_rxdata_2; +wire [1:0] qsfp0_gt_rxdatavalid_2; + +wire [5:0] qsfp0_gt_txheader_3; +wire [63:0] qsfp0_gt_txdata_3; +wire qsfp0_gt_rxgearboxslip_3; +wire [5:0] qsfp0_gt_rxheader_3; +wire [1:0] qsfp0_gt_rxheadervalid_3; +wire [63:0] qsfp0_gt_rxdata_3; +wire [1:0] qsfp0_gt_rxdatavalid_3; + +wire [5:0] qsfp0_gt_txheader_4; +wire [63:0] qsfp0_gt_txdata_4; +wire qsfp0_gt_rxgearboxslip_4; +wire [5:0] qsfp0_gt_rxheader_4; +wire [1:0] qsfp0_gt_rxheadervalid_4; +wire [63:0] qsfp0_gt_rxdata_4; +wire [1:0] qsfp0_gt_rxdatavalid_4; + +wire [5:0] qsfp1_gt_txheader_1; +wire [63:0] qsfp1_gt_txdata_1; +wire qsfp1_gt_rxgearboxslip_1; +wire [5:0] qsfp1_gt_rxheader_1; +wire [1:0] qsfp1_gt_rxheadervalid_1; +wire [63:0] qsfp1_gt_rxdata_1; +wire [1:0] qsfp1_gt_rxdatavalid_1; + +wire [5:0] qsfp1_gt_txheader_2; +wire [63:0] qsfp1_gt_txdata_2; +wire qsfp1_gt_rxgearboxslip_2; +wire [5:0] qsfp1_gt_rxheader_2; +wire [1:0] qsfp1_gt_rxheadervalid_2; +wire [63:0] qsfp1_gt_rxdata_2; +wire [1:0] qsfp1_gt_rxdatavalid_2; + +wire [5:0] qsfp1_gt_txheader_3; +wire [63:0] qsfp1_gt_txdata_3; +wire qsfp1_gt_rxgearboxslip_3; +wire [5:0] qsfp1_gt_rxheader_3; +wire [1:0] qsfp1_gt_rxheadervalid_3; +wire [63:0] qsfp1_gt_rxdata_3; +wire [1:0] qsfp1_gt_rxdatavalid_3; + +wire [5:0] qsfp1_gt_txheader_4; +wire [63:0] qsfp1_gt_txdata_4; +wire qsfp1_gt_rxgearboxslip_4; +wire [5:0] qsfp1_gt_rxheader_4; +wire [1:0] qsfp1_gt_rxheadervalid_4; +wire [63:0] qsfp1_gt_rxdata_4; +wire [1:0] qsfp1_gt_rxdatavalid_4; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({2{qsfp0_mgt_refclk_1}}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp0_rx4_n, qsfp0_rx3_n, qsfp0_rx2_n, qsfp0_rx1_n, qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), + .gtyrxp_in({qsfp0_rx4_p, qsfp0_rx3_p, qsfp0_rx2_p, qsfp0_rx1_p, qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .gtwiz_userdata_tx_in({qsfp0_gt_txdata_4, qsfp0_gt_txdata_3, qsfp0_gt_txdata_2, qsfp0_gt_txdata_1, qsfp1_gt_txdata_4, qsfp1_gt_txdata_3, qsfp1_gt_txdata_2, qsfp1_gt_txdata_1}), + .txheader_in({qsfp0_gt_txheader_4, qsfp0_gt_txheader_3, qsfp0_gt_txheader_2, qsfp0_gt_txheader_1, qsfp1_gt_txheader_4, qsfp1_gt_txheader_3, qsfp1_gt_txheader_2, qsfp1_gt_txheader_1}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out(qsfp_gtpowergood), + + .gtytxn_out({qsfp0_tx4_n, qsfp0_tx3_n, qsfp0_tx2_n, qsfp0_tx1_n, qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), + .gtytxp_out({qsfp0_tx4_p, qsfp0_tx3_p, qsfp0_tx2_p, qsfp0_tx1_p, qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), + + .rxgearboxslip_in({qsfp0_gt_rxgearboxslip_4, qsfp0_gt_rxgearboxslip_3, qsfp0_gt_rxgearboxslip_2, qsfp0_gt_rxgearboxslip_1, qsfp1_gt_rxgearboxslip_4, qsfp1_gt_rxgearboxslip_3, qsfp1_gt_rxgearboxslip_2, qsfp1_gt_rxgearboxslip_1}), + .gtwiz_userdata_rx_out({qsfp0_gt_rxdata_4, qsfp0_gt_rxdata_3, qsfp0_gt_rxdata_2, qsfp0_gt_rxdata_1, qsfp1_gt_rxdata_4, qsfp1_gt_rxdata_3, qsfp1_gt_rxdata_2, qsfp1_gt_rxdata_1}), + .rxdatavalid_out({qsfp0_gt_rxdatavalid_4, qsfp0_gt_rxdatavalid_3, qsfp0_gt_rxdatavalid_2, qsfp0_gt_rxdatavalid_1, qsfp1_gt_rxdatavalid_4, qsfp1_gt_rxdatavalid_3, qsfp1_gt_rxdatavalid_2, qsfp1_gt_rxdatavalid_1}), + .rxheader_out({qsfp0_gt_rxheader_4, qsfp0_gt_rxheader_3, qsfp0_gt_rxheader_2, qsfp0_gt_rxheader_1, qsfp1_gt_rxheader_4, qsfp1_gt_rxheader_3, qsfp1_gt_rxheader_2, qsfp1_gt_rxheader_1}), + .rxheadervalid_out({qsfp0_gt_rxheadervalid_4, qsfp0_gt_rxheadervalid_3, qsfp0_gt_rxheadervalid_2, qsfp0_gt_rxheadervalid_1, qsfp1_gt_rxheadervalid_4, qsfp1_gt_rxheadervalid_3, qsfp1_gt_rxheadervalid_2, qsfp1_gt_rxheadervalid_1}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp0_tx_clk_1_int = clk_156mhz_int; +assign qsfp0_tx_rst_1_int = rst_156mhz_int; + +assign qsfp0_rx_clk_1_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_1_reset_sync_inst ( + .clk(qsfp0_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_1_inst ( + .tx_clk(qsfp0_tx_clk_1_int), + .tx_rst(qsfp0_tx_rst_1_int), + .rx_clk(qsfp0_rx_clk_1_int), + .rx_rst(qsfp0_rx_rst_1_int), + .xgmii_txd(qsfp0_txd_1_int), + .xgmii_txc(qsfp0_txc_1_int), + .xgmii_rxd(qsfp0_rxd_1_int), + .xgmii_rxc(qsfp0_rxc_1_int), + .serdes_tx_data(qsfp0_gt_txdata_1), + .serdes_tx_hdr(qsfp0_gt_txheader_1), + .serdes_rx_data(qsfp0_gt_rxdata_1), + .serdes_rx_hdr(qsfp0_gt_rxheader_1), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_1), + .rx_block_lock(qsfp0_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp0_tx_clk_2_int = clk_156mhz_int; +assign qsfp0_tx_rst_2_int = rst_156mhz_int; + +assign qsfp0_rx_clk_2_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_2_reset_sync_inst ( + .clk(qsfp0_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_2_inst ( + .tx_clk(qsfp0_tx_clk_2_int), + .tx_rst(qsfp0_tx_rst_2_int), + .rx_clk(qsfp0_rx_clk_2_int), + .rx_rst(qsfp0_rx_rst_2_int), + .xgmii_txd(qsfp0_txd_2_int), + .xgmii_txc(qsfp0_txc_2_int), + .xgmii_rxd(qsfp0_rxd_2_int), + .xgmii_rxc(qsfp0_rxc_2_int), + .serdes_tx_data(qsfp0_gt_txdata_2), + .serdes_tx_hdr(qsfp0_gt_txheader_2), + .serdes_rx_data(qsfp0_gt_rxdata_2), + .serdes_rx_hdr(qsfp0_gt_rxheader_2), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_2), + .rx_block_lock(qsfp0_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp0_tx_clk_3_int = clk_156mhz_int; +assign qsfp0_tx_rst_3_int = rst_156mhz_int; + +assign qsfp0_rx_clk_3_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_3_reset_sync_inst ( + .clk(qsfp0_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_3_inst ( + .tx_clk(qsfp0_tx_clk_3_int), + .tx_rst(qsfp0_tx_rst_3_int), + .rx_clk(qsfp0_rx_clk_3_int), + .rx_rst(qsfp0_rx_rst_3_int), + .xgmii_txd(qsfp0_txd_3_int), + .xgmii_txc(qsfp0_txc_3_int), + .xgmii_rxd(qsfp0_rxd_3_int), + .xgmii_rxc(qsfp0_rxc_3_int), + .serdes_tx_data(qsfp0_gt_txdata_3), + .serdes_tx_hdr(qsfp0_gt_txheader_3), + .serdes_rx_data(qsfp0_gt_rxdata_3), + .serdes_rx_hdr(qsfp0_gt_rxheader_3), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_3), + .rx_block_lock(qsfp0_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp0_tx_clk_4_int = clk_156mhz_int; +assign qsfp0_tx_rst_4_int = rst_156mhz_int; + +assign qsfp0_rx_clk_4_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_4_reset_sync_inst ( + .clk(qsfp0_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_4_inst ( + .tx_clk(qsfp0_tx_clk_4_int), + .tx_rst(qsfp0_tx_rst_4_int), + .rx_clk(qsfp0_rx_clk_4_int), + .rx_rst(qsfp0_rx_rst_4_int), + .xgmii_txd(qsfp0_txd_4_int), + .xgmii_txc(qsfp0_txc_4_int), + .xgmii_rxd(qsfp0_rxd_4_int), + .xgmii_rxc(qsfp0_rxc_4_int), + .serdes_tx_data(qsfp0_gt_txdata_4), + .serdes_tx_hdr(qsfp0_gt_txheader_4), + .serdes_rx_data(qsfp0_gt_rxdata_4), + .serdes_rx_hdr(qsfp0_gt_rxheader_4), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_4), + .rx_block_lock(qsfp0_rx_block_lock_4), + .rx_high_ber() +); + +assign qsfp1_tx_clk_1_int = clk_156mhz_int; +assign qsfp1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp1_rx_clk_1_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_1_reset_sync_inst ( + .clk(qsfp1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_1_inst ( + .tx_clk(qsfp1_tx_clk_1_int), + .tx_rst(qsfp1_tx_rst_1_int), + .rx_clk(qsfp1_rx_clk_1_int), + .rx_rst(qsfp1_rx_rst_1_int), + .xgmii_txd(qsfp1_txd_1_int), + .xgmii_txc(qsfp1_txc_1_int), + .xgmii_rxd(qsfp1_rxd_1_int), + .xgmii_rxc(qsfp1_rxc_1_int), + .serdes_tx_data(qsfp1_gt_txdata_1), + .serdes_tx_hdr(qsfp1_gt_txheader_1), + .serdes_rx_data(qsfp1_gt_rxdata_1), + .serdes_rx_hdr(qsfp1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp1_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp1_tx_clk_2_int = clk_156mhz_int; +assign qsfp1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp1_rx_clk_2_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_2_reset_sync_inst ( + .clk(qsfp1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_2_inst ( + .tx_clk(qsfp1_tx_clk_2_int), + .tx_rst(qsfp1_tx_rst_2_int), + .rx_clk(qsfp1_rx_clk_2_int), + .rx_rst(qsfp1_rx_rst_2_int), + .xgmii_txd(qsfp1_txd_2_int), + .xgmii_txc(qsfp1_txc_2_int), + .xgmii_rxd(qsfp1_rxd_2_int), + .xgmii_rxc(qsfp1_rxc_2_int), + .serdes_tx_data(qsfp1_gt_txdata_2), + .serdes_tx_hdr(qsfp1_gt_txheader_2), + .serdes_rx_data(qsfp1_gt_rxdata_2), + .serdes_rx_hdr(qsfp1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp1_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp1_tx_clk_3_int = clk_156mhz_int; +assign qsfp1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp1_rx_clk_3_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_3_reset_sync_inst ( + .clk(qsfp1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_3_inst ( + .tx_clk(qsfp1_tx_clk_3_int), + .tx_rst(qsfp1_tx_rst_3_int), + .rx_clk(qsfp1_rx_clk_3_int), + .rx_rst(qsfp1_rx_rst_3_int), + .xgmii_txd(qsfp1_txd_3_int), + .xgmii_txc(qsfp1_txc_3_int), + .xgmii_rxd(qsfp1_rxd_3_int), + .xgmii_rxc(qsfp1_rxc_3_int), + .serdes_tx_data(qsfp1_gt_txdata_3), + .serdes_tx_hdr(qsfp1_gt_txheader_3), + .serdes_rx_data(qsfp1_gt_rxdata_3), + .serdes_rx_hdr(qsfp1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp1_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp1_tx_clk_4_int = clk_156mhz_int; +assign qsfp1_tx_rst_4_int = rst_156mhz_int; + +assign qsfp1_rx_clk_4_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_4_reset_sync_inst ( + .clk(qsfp1_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_4_inst ( + .tx_clk(qsfp1_tx_clk_4_int), + .tx_rst(qsfp1_tx_rst_4_int), + .rx_clk(qsfp1_rx_clk_4_int), + .rx_rst(qsfp1_rx_rst_4_int), + .xgmii_txd(qsfp1_txd_4_int), + .xgmii_txc(qsfp1_txc_4_int), + .xgmii_rxd(qsfp1_rxd_4_int), + .xgmii_rxc(qsfp1_rxc_4_int), + .serdes_tx_data(qsfp1_gt_txdata_4), + .serdes_tx_hdr(qsfp1_gt_txheader_4), + .serdes_rx_data(qsfp1_gt_rxdata_4), + .serdes_rx_hdr(qsfp1_gt_rxheader_4), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_4), + .rx_block_lock(qsfp1_rx_block_lock_4), + .rx_high_ber() +); + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .sw(sw_int), + .led(led), + /* + * Ethernet: QSFP28 + */ + .qsfp0_tx_clk_1(qsfp0_tx_clk_1_int), + .qsfp0_tx_rst_1(qsfp0_tx_rst_1_int), + .qsfp0_txd_1(qsfp0_txd_1_int), + .qsfp0_txc_1(qsfp0_txc_1_int), + .qsfp0_rx_clk_1(qsfp0_rx_clk_1_int), + .qsfp0_rx_rst_1(qsfp0_rx_rst_1_int), + .qsfp0_rxd_1(qsfp0_rxd_1_int), + .qsfp0_rxc_1(qsfp0_rxc_1_int), + .qsfp0_tx_clk_2(qsfp0_tx_clk_2_int), + .qsfp0_tx_rst_2(qsfp0_tx_rst_2_int), + .qsfp0_txd_2(qsfp0_txd_2_int), + .qsfp0_txc_2(qsfp0_txc_2_int), + .qsfp0_rx_clk_2(qsfp0_rx_clk_2_int), + .qsfp0_rx_rst_2(qsfp0_rx_rst_2_int), + .qsfp0_rxd_2(qsfp0_rxd_2_int), + .qsfp0_rxc_2(qsfp0_rxc_2_int), + .qsfp0_tx_clk_3(qsfp0_tx_clk_3_int), + .qsfp0_tx_rst_3(qsfp0_tx_rst_3_int), + .qsfp0_txd_3(qsfp0_txd_3_int), + .qsfp0_txc_3(qsfp0_txc_3_int), + .qsfp0_rx_clk_3(qsfp0_rx_clk_3_int), + .qsfp0_rx_rst_3(qsfp0_rx_rst_3_int), + .qsfp0_rxd_3(qsfp0_rxd_3_int), + .qsfp0_rxc_3(qsfp0_rxc_3_int), + .qsfp0_tx_clk_4(qsfp0_tx_clk_4_int), + .qsfp0_tx_rst_4(qsfp0_tx_rst_4_int), + .qsfp0_txd_4(qsfp0_txd_4_int), + .qsfp0_txc_4(qsfp0_txc_4_int), + .qsfp0_rx_clk_4(qsfp0_rx_clk_4_int), + .qsfp0_rx_rst_4(qsfp0_rx_rst_4_int), + .qsfp0_rxd_4(qsfp0_rxd_4_int), + .qsfp0_rxc_4(qsfp0_rxc_4_int), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), + .qsfp1_txd_1(qsfp1_txd_1_int), + .qsfp1_txc_1(qsfp1_txc_1_int), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), + .qsfp1_rxd_1(qsfp1_rxd_1_int), + .qsfp1_rxc_1(qsfp1_rxc_1_int), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), + .qsfp1_txd_2(qsfp1_txd_2_int), + .qsfp1_txc_2(qsfp1_txc_2_int), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), + .qsfp1_rxd_2(qsfp1_rxd_2_int), + .qsfp1_rxc_2(qsfp1_rxc_2_int), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), + .qsfp1_txd_3(qsfp1_txd_3_int), + .qsfp1_txc_3(qsfp1_txc_3_int), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), + .qsfp1_rxd_3(qsfp1_rxd_3_int), + .qsfp1_rxc_3(qsfp1_rxc_3_int), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), + .qsfp1_txd_4(qsfp1_txd_4_int), + .qsfp1_txc_4(qsfp1_txc_4_int), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), + .qsfp1_rxd_4(qsfp1_rxd_4_int), + .qsfp1_rxc_4(qsfp1_rxc_4_int), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd), + .uart_txd(uart_txd_int) +); + +endmodule diff --git a/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga_core.v b/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..70039a58b --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,664 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire [3:0] sw, + output wire [2:0] led, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp0_tx_clk_1, + input wire qsfp0_tx_rst_1, + output wire [63:0] qsfp0_txd_1, + output wire [7:0] qsfp0_txc_1, + input wire qsfp0_rx_clk_1, + input wire qsfp0_rx_rst_1, + input wire [63:0] qsfp0_rxd_1, + input wire [7:0] qsfp0_rxc_1, + input wire qsfp0_tx_clk_2, + input wire qsfp0_tx_rst_2, + output wire [63:0] qsfp0_txd_2, + output wire [7:0] qsfp0_txc_2, + input wire qsfp0_rx_clk_2, + input wire qsfp0_rx_rst_2, + input wire [63:0] qsfp0_rxd_2, + input wire [7:0] qsfp0_rxc_2, + input wire qsfp0_tx_clk_3, + input wire qsfp0_tx_rst_3, + output wire [63:0] qsfp0_txd_3, + output wire [7:0] qsfp0_txc_3, + input wire qsfp0_rx_clk_3, + input wire qsfp0_rx_rst_3, + input wire [63:0] qsfp0_rxd_3, + input wire [7:0] qsfp0_rxc_3, + input wire qsfp0_tx_clk_4, + input wire qsfp0_tx_rst_4, + output wire [63:0] qsfp0_txd_4, + output wire [7:0] qsfp0_txc_4, + input wire qsfp0_rx_clk_4, + input wire qsfp0_rx_rst_4, + input wire [63:0] qsfp0_rxd_4, + input wire [7:0] qsfp0_rxc_4, + input wire qsfp1_tx_clk_1, + input wire qsfp1_tx_rst_1, + output wire [63:0] qsfp1_txd_1, + output wire [7:0] qsfp1_txc_1, + input wire qsfp1_rx_clk_1, + input wire qsfp1_rx_rst_1, + input wire [63:0] qsfp1_rxd_1, + input wire [7:0] qsfp1_rxc_1, + input wire qsfp1_tx_clk_2, + input wire qsfp1_tx_rst_2, + output wire [63:0] qsfp1_txd_2, + output wire [7:0] qsfp1_txc_2, + input wire qsfp1_rx_clk_2, + input wire qsfp1_rx_rst_2, + input wire [63:0] qsfp1_rxd_2, + input wire [7:0] qsfp1_rxc_2, + input wire qsfp1_tx_clk_3, + input wire qsfp1_tx_rst_3, + output wire [63:0] qsfp1_txd_3, + output wire [7:0] qsfp1_txc_3, + input wire qsfp1_rx_clk_3, + input wire qsfp1_rx_rst_3, + input wire [63:0] qsfp1_rxd_3, + input wire [7:0] qsfp1_rxc_3, + input wire qsfp1_tx_clk_4, + input wire qsfp1_tx_rst_4, + output wire [63:0] qsfp1_txd_4, + output wire [7:0] qsfp1_txc_4, + input wire qsfp1_rx_clk_4, + input wire qsfp1_rx_rst_4, + input wire [63:0] qsfp1_rxd_4, + input wire [7:0] qsfp1_rxc_4, + + /* + * UART: 115200 bps, 8N1 + */ + output wire uart_rxd, + input wire uart_txd +); + +// 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 led = sw; +assign led = led_reg; + +assign qsfp0_txd_2 = 64'h0707070707070707; +assign qsfp0_txc_2 = 8'hff; +assign qsfp0_txd_3 = 64'h0707070707070707; +assign qsfp0_txc_3 = 8'hff; +assign qsfp0_txd_4 = 64'h0707070707070707; +assign qsfp0_txc_4 = 8'hff; + +assign qsfp1_txd_1 = 64'h0707070707070707; +assign qsfp1_txc_1 = 8'hff; +assign qsfp1_txd_2 = 64'h0707070707070707; +assign qsfp1_txc_2 = 8'hff; +assign qsfp1_txd_3 = 64'h0707070707070707; +assign qsfp1_txc_3 = 8'hff; +assign qsfp1_txd_4 = 64'h0707070707070707; +assign qsfp1_txc_4 = 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(qsfp0_rx_clk_1), + .rx_rst(qsfp0_rx_rst_1), + .tx_clk(qsfp0_tx_clk_1), + .tx_rst(qsfp0_tx_rst_1), + .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(qsfp0_rxd_1), + .xgmii_rxc(qsfp0_rxc_1), + .xgmii_txd(qsfp0_txd_1), + .xgmii_txc(qsfp0_txc_1), + + .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 diff --git a/fpga/lib/eth/example/AU200/fpga_10g/rtl/sync_signal.v b/fpga/lib/eth/example/AU200/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/arp_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/axis_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/eth_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/ip_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..b2a0e316a --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,465 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-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. + +""" + +from myhdl import * +import os + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sw = Signal(intbv(0)[4:]) + qsfp0_tx_clk_1 = Signal(bool(0)) + qsfp0_tx_rst_1 = Signal(bool(0)) + qsfp0_rx_clk_1 = Signal(bool(0)) + qsfp0_rx_rst_1 = Signal(bool(0)) + qsfp0_rxd_1 = Signal(intbv(0)[64:]) + qsfp0_rxc_1 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_2 = Signal(bool(0)) + qsfp0_tx_rst_2 = Signal(bool(0)) + qsfp0_rx_clk_2 = Signal(bool(0)) + qsfp0_rx_rst_2 = Signal(bool(0)) + qsfp0_rxd_2 = Signal(intbv(0)[64:]) + qsfp0_rxc_2 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_3 = Signal(bool(0)) + qsfp0_tx_rst_3 = Signal(bool(0)) + qsfp0_rx_clk_3 = Signal(bool(0)) + qsfp0_rx_rst_3 = Signal(bool(0)) + qsfp0_rxd_3 = Signal(intbv(0)[64:]) + qsfp0_rxc_3 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_4 = Signal(bool(0)) + qsfp0_tx_rst_4 = Signal(bool(0)) + qsfp0_rx_clk_4 = Signal(bool(0)) + qsfp0_rx_rst_4 = Signal(bool(0)) + qsfp0_rxd_4 = Signal(intbv(0)[64:]) + qsfp0_rxc_4 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_1 = Signal(bool(0)) + qsfp1_tx_rst_1 = Signal(bool(0)) + qsfp1_rx_clk_1 = Signal(bool(0)) + qsfp1_rx_rst_1 = Signal(bool(0)) + qsfp1_rxd_1 = Signal(intbv(0)[64:]) + qsfp1_rxc_1 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_2 = Signal(bool(0)) + qsfp1_tx_rst_2 = Signal(bool(0)) + qsfp1_rx_clk_2 = Signal(bool(0)) + qsfp1_rx_rst_2 = Signal(bool(0)) + qsfp1_rxd_2 = Signal(intbv(0)[64:]) + qsfp1_rxc_2 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_3 = Signal(bool(0)) + qsfp1_tx_rst_3 = Signal(bool(0)) + qsfp1_rx_clk_3 = Signal(bool(0)) + qsfp1_rx_rst_3 = Signal(bool(0)) + qsfp1_rxd_3 = Signal(intbv(0)[64:]) + qsfp1_rxc_3 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_4 = Signal(bool(0)) + qsfp1_tx_rst_4 = Signal(bool(0)) + qsfp1_rx_clk_4 = Signal(bool(0)) + qsfp1_rx_rst_4 = Signal(bool(0)) + qsfp1_rxd_4 = Signal(intbv(0)[64:]) + qsfp1_rxc_4 = Signal(intbv(0)[8:]) + uart_txd = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[3:]) + qsfp0_txd_1 = Signal(intbv(0)[64:]) + qsfp0_txc_1 = Signal(intbv(0)[8:]) + qsfp0_txd_2 = Signal(intbv(0)[64:]) + qsfp0_txc_2 = Signal(intbv(0)[8:]) + qsfp0_txd_3 = Signal(intbv(0)[64:]) + qsfp0_txc_3 = Signal(intbv(0)[8:]) + qsfp0_txd_4 = Signal(intbv(0)[64:]) + qsfp0_txc_4 = Signal(intbv(0)[8:]) + qsfp1_txd_1 = Signal(intbv(0)[64:]) + qsfp1_txc_1 = Signal(intbv(0)[8:]) + qsfp1_txd_2 = Signal(intbv(0)[64:]) + qsfp1_txc_2 = Signal(intbv(0)[8:]) + qsfp1_txd_3 = Signal(intbv(0)[64:]) + qsfp1_txc_3 = Signal(intbv(0)[8:]) + qsfp1_txd_4 = Signal(intbv(0)[64:]) + qsfp1_txc_4 = Signal(intbv(0)[8:]) + uart_rxd = Signal(bool(0)) + + # sources and sinks + qsfp0_1_source = xgmii_ep.XGMIISource() + qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') + + qsfp0_1_sink = xgmii_ep.XGMIISink() + qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') + + qsfp0_2_source = xgmii_ep.XGMIISource() + qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') + + qsfp0_2_sink = xgmii_ep.XGMIISink() + qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') + + qsfp0_3_source = xgmii_ep.XGMIISource() + qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') + + qsfp0_3_sink = xgmii_ep.XGMIISink() + qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') + + qsfp0_4_source = xgmii_ep.XGMIISource() + qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') + + qsfp0_4_sink = xgmii_ep.XGMIISink() + qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') + + qsfp1_1_source = xgmii_ep.XGMIISource() + qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + + qsfp1_1_sink = xgmii_ep.XGMIISink() + qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + + qsfp1_2_source = xgmii_ep.XGMIISource() + qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + + qsfp1_2_sink = xgmii_ep.XGMIISink() + qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + + qsfp1_3_source = xgmii_ep.XGMIISource() + qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + + qsfp1_3_sink = xgmii_ep.XGMIISink() + qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + + qsfp1_4_source = xgmii_ep.XGMIISource() + qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + + qsfp1_4_sink = xgmii_ep.XGMIISink() + qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + sw=sw, + led=led, + + qsfp0_tx_clk_1=qsfp0_tx_clk_1, + qsfp0_tx_rst_1=qsfp0_tx_rst_1, + qsfp0_txd_1=qsfp0_txd_1, + qsfp0_txc_1=qsfp0_txc_1, + qsfp0_rx_clk_1=qsfp0_rx_clk_1, + qsfp0_rx_rst_1=qsfp0_rx_rst_1, + qsfp0_rxd_1=qsfp0_rxd_1, + qsfp0_rxc_1=qsfp0_rxc_1, + qsfp0_tx_clk_2=qsfp0_tx_clk_2, + qsfp0_tx_rst_2=qsfp0_tx_rst_2, + qsfp0_txd_2=qsfp0_txd_2, + qsfp0_txc_2=qsfp0_txc_2, + qsfp0_rx_clk_2=qsfp0_rx_clk_2, + qsfp0_rx_rst_2=qsfp0_rx_rst_2, + qsfp0_rxd_2=qsfp0_rxd_2, + qsfp0_rxc_2=qsfp0_rxc_2, + qsfp0_tx_clk_3=qsfp0_tx_clk_3, + qsfp0_tx_rst_3=qsfp0_tx_rst_3, + qsfp0_txd_3=qsfp0_txd_3, + qsfp0_txc_3=qsfp0_txc_3, + qsfp0_rx_clk_3=qsfp0_rx_clk_3, + qsfp0_rx_rst_3=qsfp0_rx_rst_3, + qsfp0_rxd_3=qsfp0_rxd_3, + qsfp0_rxc_3=qsfp0_rxc_3, + qsfp0_tx_clk_4=qsfp0_tx_clk_4, + qsfp0_tx_rst_4=qsfp0_tx_rst_4, + qsfp0_txd_4=qsfp0_txd_4, + qsfp0_txc_4=qsfp0_txc_4, + qsfp0_rx_clk_4=qsfp0_rx_clk_4, + qsfp0_rx_rst_4=qsfp0_rx_rst_4, + qsfp0_rxd_4=qsfp0_rxd_4, + qsfp0_rxc_4=qsfp0_rxc_4, + qsfp1_tx_clk_1=qsfp1_tx_clk_1, + qsfp1_tx_rst_1=qsfp1_tx_rst_1, + qsfp1_txd_1=qsfp1_txd_1, + qsfp1_txc_1=qsfp1_txc_1, + qsfp1_rx_clk_1=qsfp1_rx_clk_1, + qsfp1_rx_rst_1=qsfp1_rx_rst_1, + qsfp1_rxd_1=qsfp1_rxd_1, + qsfp1_rxc_1=qsfp1_rxc_1, + qsfp1_tx_clk_2=qsfp1_tx_clk_2, + qsfp1_tx_rst_2=qsfp1_tx_rst_2, + qsfp1_txd_2=qsfp1_txd_2, + qsfp1_txc_2=qsfp1_txc_2, + qsfp1_rx_clk_2=qsfp1_rx_clk_2, + qsfp1_rx_rst_2=qsfp1_rx_rst_2, + qsfp1_rxd_2=qsfp1_rxd_2, + qsfp1_rxc_2=qsfp1_rxc_2, + qsfp1_tx_clk_3=qsfp1_tx_clk_3, + qsfp1_tx_rst_3=qsfp1_tx_rst_3, + qsfp1_txd_3=qsfp1_txd_3, + qsfp1_txc_3=qsfp1_txc_3, + qsfp1_rx_clk_3=qsfp1_rx_clk_3, + qsfp1_rx_rst_3=qsfp1_rx_rst_3, + qsfp1_rxd_3=qsfp1_rxd_3, + qsfp1_rxc_3=qsfp1_rxc_3, + qsfp1_tx_clk_4=qsfp1_tx_clk_4, + qsfp1_tx_rst_4=qsfp1_tx_rst_4, + qsfp1_txd_4=qsfp1_txd_4, + qsfp1_txc_4=qsfp1_txc_4, + qsfp1_rx_clk_4=qsfp1_rx_clk_4, + qsfp1_rx_rst_4=qsfp1_rx_rst_4, + qsfp1_rxd_4=qsfp1_rxd_4, + qsfp1_rxc_4=qsfp1_rxc_4, + + uart_rxd=uart_rxd, + uart_txd=uart_txd + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 + qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 + qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 + qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 + qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 + qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 + qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 + qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 + qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 + qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 + qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 + qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 + qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 + qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 + qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 + qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp0_tx_rst_1.next = 1 + qsfp0_rx_rst_1.next = 1 + qsfp0_tx_rst_2.next = 1 + qsfp0_rx_rst_2.next = 1 + qsfp0_tx_rst_3.next = 1 + qsfp0_rx_rst_3.next = 1 + qsfp0_tx_rst_4.next = 1 + qsfp0_rx_rst_4.next = 1 + qsfp1_tx_rst_1.next = 1 + qsfp1_rx_rst_1.next = 1 + qsfp1_tx_rst_2.next = 1 + qsfp1_rx_rst_2.next = 1 + qsfp1_tx_rst_3.next = 1 + qsfp1_rx_rst_3.next = 1 + qsfp1_tx_rst_4.next = 1 + qsfp1_rx_rst_4.next = 1 + yield clk.posedge + rst.next = 0 + qsfp0_tx_rst_1.next = 0 + qsfp0_rx_rst_1.next = 0 + qsfp0_tx_rst_2.next = 0 + qsfp0_rx_rst_2.next = 0 + qsfp0_tx_rst_3.next = 0 + qsfp0_rx_rst_3.next = 0 + qsfp0_tx_rst_4.next = 0 + qsfp0_rx_rst_4.next = 0 + qsfp1_tx_rst_1.next = 0 + qsfp1_rx_rst_1.next = 0 + qsfp1_tx_rst_2.next = 0 + qsfp1_rx_rst_2.next = 0 + qsfp1_tx_rst_3.next = 0 + qsfp1_rx_rst_3.next = 0 + qsfp1_tx_rst_4.next = 0 + qsfp1_rx_rst_4.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp0_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp0_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp0_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp0_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp0_1_source.empty() + assert qsfp0_1_sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.v b/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..fddb81323 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016-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 + +`timescale 1ns / 1ps + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [3:0] sw = 0; +reg qsfp0_tx_clk_1 = 0; +reg qsfp0_tx_rst_1 = 0; +reg qsfp0_rx_clk_1 = 0; +reg qsfp0_rx_rst_1 = 0; +reg [63:0] qsfp0_rxd_1 = 0; +reg [7:0] qsfp0_rxc_1 = 0; +reg qsfp0_tx_clk_2 = 0; +reg qsfp0_tx_rst_2 = 0; +reg qsfp0_rx_clk_2 = 0; +reg qsfp0_rx_rst_2 = 0; +reg [63:0] qsfp0_rxd_2 = 0; +reg [7:0] qsfp0_rxc_2 = 0; +reg qsfp0_tx_clk_3 = 0; +reg qsfp0_tx_rst_3 = 0; +reg qsfp0_rx_clk_3 = 0; +reg qsfp0_rx_rst_3 = 0; +reg [63:0] qsfp0_rxd_3 = 0; +reg [7:0] qsfp0_rxc_3 = 0; +reg qsfp0_tx_clk_4 = 0; +reg qsfp0_tx_rst_4 = 0; +reg qsfp0_rx_clk_4 = 0; +reg qsfp0_rx_rst_4 = 0; +reg [63:0] qsfp0_rxd_4 = 0; +reg [7:0] qsfp0_rxc_4 = 0; +reg qsfp1_tx_clk_1 = 0; +reg qsfp1_tx_rst_1 = 0; +reg qsfp1_rx_clk_1 = 0; +reg qsfp1_rx_rst_1 = 0; +reg [63:0] qsfp1_rxd_1 = 0; +reg [7:0] qsfp1_rxc_1 = 0; +reg qsfp1_tx_clk_2 = 0; +reg qsfp1_tx_rst_2 = 0; +reg qsfp1_rx_clk_2 = 0; +reg qsfp1_rx_rst_2 = 0; +reg [63:0] qsfp1_rxd_2 = 0; +reg [7:0] qsfp1_rxc_2 = 0; +reg qsfp1_tx_clk_3 = 0; +reg qsfp1_tx_rst_3 = 0; +reg qsfp1_rx_clk_3 = 0; +reg qsfp1_rx_rst_3 = 0; +reg [63:0] qsfp1_rxd_3 = 0; +reg [7:0] qsfp1_rxc_3 = 0; +reg qsfp1_tx_clk_4 = 0; +reg qsfp1_tx_rst_4 = 0; +reg qsfp1_rx_clk_4 = 0; +reg qsfp1_rx_rst_4 = 0; +reg [63:0] qsfp1_rxd_4 = 0; +reg [7:0] qsfp1_rxc_4 = 0; +reg uart_txd = 0; + +// Outputs +wire [2:0] led; +wire [63:0] qsfp0_txd_1; +wire [7:0] qsfp0_txc_1; +wire [63:0] qsfp0_txd_2; +wire [7:0] qsfp0_txc_2; +wire [63:0] qsfp0_txd_3; +wire [7:0] qsfp0_txc_3; +wire [63:0] qsfp0_txd_4; +wire [7:0] qsfp0_txc_4; +wire [63:0] qsfp1_txd_1; +wire [7:0] qsfp1_txc_1; +wire [63:0] qsfp1_txd_2; +wire [7:0] qsfp1_txc_2; +wire [63:0] qsfp1_txd_3; +wire [7:0] qsfp1_txc_3; +wire [63:0] qsfp1_txd_4; +wire [7:0] qsfp1_txc_4; +wire uart_rxd; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + sw, + qsfp0_tx_clk_1, + qsfp0_tx_rst_1, + qsfp0_rx_clk_1, + qsfp0_rx_rst_1, + qsfp0_rxd_1, + qsfp0_rxc_1, + qsfp0_tx_clk_2, + qsfp0_tx_rst_2, + qsfp0_rx_clk_2, + qsfp0_rx_rst_2, + qsfp0_rxd_2, + qsfp0_rxc_2, + qsfp0_tx_clk_3, + qsfp0_tx_rst_3, + qsfp0_rx_clk_3, + qsfp0_rx_rst_3, + qsfp0_rxd_3, + qsfp0_rxc_3, + qsfp0_tx_clk_4, + qsfp0_tx_rst_4, + qsfp0_rx_clk_4, + qsfp0_rx_rst_4, + qsfp0_rxd_4, + qsfp0_rxc_4, + qsfp1_tx_clk_1, + qsfp1_tx_rst_1, + qsfp1_rx_clk_1, + qsfp1_rx_rst_1, + qsfp1_rxd_1, + qsfp1_rxc_1, + qsfp1_tx_clk_2, + qsfp1_tx_rst_2, + qsfp1_rx_clk_2, + qsfp1_rx_rst_2, + qsfp1_rxd_2, + qsfp1_rxc_2, + qsfp1_tx_clk_3, + qsfp1_tx_rst_3, + qsfp1_rx_clk_3, + qsfp1_rx_rst_3, + qsfp1_rxd_3, + qsfp1_rxc_3, + qsfp1_tx_clk_4, + qsfp1_tx_rst_4, + qsfp1_rx_clk_4, + qsfp1_rx_rst_4, + qsfp1_rxd_4, + qsfp1_rxc_4, + uart_txd + ); + $to_myhdl( + led, + qsfp0_txd_1, + qsfp0_txc_1, + qsfp0_txd_2, + qsfp0_txc_2, + qsfp0_txd_3, + qsfp0_txc_3, + qsfp0_txd_4, + qsfp0_txc_4, + qsfp1_txd_1, + qsfp1_txc_1, + qsfp1_txd_2, + qsfp1_txc_2, + qsfp1_txd_3, + qsfp1_txc_3, + qsfp1_txd_4, + qsfp1_txc_4, + uart_rxd + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sw(sw), + .led(led), + .qsfp0_tx_clk_1(qsfp0_tx_clk_1), + .qsfp0_tx_rst_1(qsfp0_tx_rst_1), + .qsfp0_txd_1(qsfp0_txd_1), + .qsfp0_txc_1(qsfp0_txc_1), + .qsfp0_rx_clk_1(qsfp0_rx_clk_1), + .qsfp0_rx_rst_1(qsfp0_rx_rst_1), + .qsfp0_rxd_1(qsfp0_rxd_1), + .qsfp0_rxc_1(qsfp0_rxc_1), + .qsfp0_tx_clk_2(qsfp0_tx_clk_2), + .qsfp0_tx_rst_2(qsfp0_tx_rst_2), + .qsfp0_txd_2(qsfp0_txd_2), + .qsfp0_txc_2(qsfp0_txc_2), + .qsfp0_rx_clk_2(qsfp0_rx_clk_2), + .qsfp0_rx_rst_2(qsfp0_rx_rst_2), + .qsfp0_rxd_2(qsfp0_rxd_2), + .qsfp0_rxc_2(qsfp0_rxc_2), + .qsfp0_tx_clk_3(qsfp0_tx_clk_3), + .qsfp0_tx_rst_3(qsfp0_tx_rst_3), + .qsfp0_txd_3(qsfp0_txd_3), + .qsfp0_txc_3(qsfp0_txc_3), + .qsfp0_rx_clk_3(qsfp0_rx_clk_3), + .qsfp0_rx_rst_3(qsfp0_rx_rst_3), + .qsfp0_rxd_3(qsfp0_rxd_3), + .qsfp0_rxc_3(qsfp0_rxc_3), + .qsfp0_tx_clk_4(qsfp0_tx_clk_4), + .qsfp0_tx_rst_4(qsfp0_tx_rst_4), + .qsfp0_txd_4(qsfp0_txd_4), + .qsfp0_txc_4(qsfp0_txc_4), + .qsfp0_rx_clk_4(qsfp0_rx_clk_4), + .qsfp0_rx_rst_4(qsfp0_rx_rst_4), + .qsfp0_rxd_4(qsfp0_rxd_4), + .qsfp0_rxc_4(qsfp0_rxc_4), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1), + .qsfp1_txd_1(qsfp1_txd_1), + .qsfp1_txc_1(qsfp1_txc_1), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1), + .qsfp1_rxd_1(qsfp1_rxd_1), + .qsfp1_rxc_1(qsfp1_rxc_1), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2), + .qsfp1_txd_2(qsfp1_txd_2), + .qsfp1_txc_2(qsfp1_txc_2), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2), + .qsfp1_rxd_2(qsfp1_rxd_2), + .qsfp1_rxc_2(qsfp1_rxc_2), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3), + .qsfp1_txd_3(qsfp1_txd_3), + .qsfp1_txc_3(qsfp1_txc_3), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3), + .qsfp1_rxd_3(qsfp1_rxd_3), + .qsfp1_rxc_3(qsfp1_rxc_3), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4), + .qsfp1_txd_4(qsfp1_txd_4), + .qsfp1_txc_4(qsfp1_txc_4), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4), + .qsfp1_rxd_4(qsfp1_rxd_4), + .qsfp1_rxc_4(qsfp1_rxc_4), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) +); + +endmodule diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/udp_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU200/fpga_10g/tb/xgmii_ep.py b/fpga/lib/eth/example/AU200/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/fpga/lib/eth/example/AU200/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/Makefile b/fpga/lib/eth/example/AU250/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# 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 diff --git a/fpga/lib/eth/example/AU250/fpga_10g/README.md b/fpga/lib/eth/example/AU250/fpga_10g/README.md new file mode 100644 index 000000000..a901cd901 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/README.md @@ -0,0 +1,26 @@ +# Verilog Ethernet Alveo U250 Example Design + +## Introduction + +This example design targets the Xilinx Alveo U250 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. The design also enables the gigabit Ethernet interface for +testing with a QSFP loopback adapter. + +FPGA: xcu250-figd2104-2-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the Alveo U250 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. + + diff --git a/fpga/lib/eth/example/AU250/fpga_10g/common/vivado.mk b/fpga/lib/eth/example/AU250/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..ee83637e0 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/common/vivado.mk @@ -0,0 +1,123 @@ +################################################################### +# +# 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: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean: + -rm -rf *.log *.jou *.cache *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: 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) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/eth/example/AU250/fpga_10g/fpga.xdc b/fpga/lib/eth/example/AU250/fpga_10g/fpga.xdc new file mode 100644 index 000000000..764edac1b --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/fpga.xdc @@ -0,0 +1,215 @@ +# XDC constraints for the Xilinx Alveo U250 board +# part: xcu250-figd2104-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.SPI_OPCODE 8'h6B [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design] + +# System clocks +# 300 MHz (DDR 0) +#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p] +#set_property -dict {LOC AY38 IOSTANDARD LVDS} [get_ports clk_300mhz_0_n] +#create_clock -period 3.333 -name clk_300mhz_0 [get_ports clk_300mhz_0_p] + +# 300 MHz (DDR 1) +#set_property -dict {LOC AW20 IOSTANDARD LVDS} [get_ports clk_300mhz_1_p] +#set_property -dict {LOC AW19 IOSTANDARD LVDS} [get_ports clk_300mhz_1_n] +#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p] + +# 300 MHz (DDR 2) +#set_property -dict {LOC F32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_p] +#set_property -dict {LOC E32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_n] +#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] + +# 300 MHz (DDR 3) +#set_property -dict {LOC J16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_p] +#set_property -dict {LOC H16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_n] +#create_clock -period 3.333 -name clk_300mhz_3 [get_ports clk_300mhz_3_p] + +# SI570 user clock +#set_property -dict {LOC AU19 IOSTANDARD LVDS} [get_ports clk_user_p] +#set_property -dict {LOC AV19 IOSTANDARD LVDS} [get_ports clk_user_n] +#create_clock -period 6.400 -name clk_user [get_ports clk_user_p] + +# LEDs +set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] + +# Reset button +set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset] + +# DIP switches +set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] +set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] +set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] +set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] + +# UART +set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_txd] +set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_rxd] + +# QSFP28 Interfaces +set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11 +#set_property -dict {LOC M11 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U14.4 via U43.13 +#set_property -dict {LOC M10 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U14.5 via U43.14 +set_property -dict {LOC K11 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U9.18 +#set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17 +set_property -dict {LOC BE16 IOSTANDARD LVCMOS12} [get_ports qsfp0_modsell] +set_property -dict {LOC BE17 IOSTANDARD LVCMOS12} [get_ports qsfp0_resetl] +set_property -dict {LOC BE20 IOSTANDARD LVCMOS12} [get_ports qsfp0_modprsl] +set_property -dict {LOC BE21 IOSTANDARD LVCMOS12} [get_ports qsfp0_intl] +set_property -dict {LOC BD18 IOSTANDARD LVCMOS12} [get_ports qsfp0_lpmode] +set_property -dict {LOC AT22 IOSTANDARD LVCMOS12} [get_ports qsfp0_refclk_reset] +set_property -dict {LOC AT20 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[0]}] +set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}] + +# 156.25 MHz MGT reference clock (from SI570) +#create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports qsfp0_mgt_refclk_0_p] + +# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01) +#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p] + +# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10) +create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p] + +set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10 +set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10 +#set_property -dict {LOC T11 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U14.4 via U43.15 +#set_property -dict {LOC T10 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U14.5 via U43.16 +#set_property -dict {LOC P11 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U12.18 +#set_property -dict {LOC P10 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U12.17 +set_property -dict {LOC AY20 IOSTANDARD LVCMOS12} [get_ports qsfp1_modsell] +set_property -dict {LOC BC18 IOSTANDARD LVCMOS12} [get_ports qsfp1_resetl] +set_property -dict {LOC BC19 IOSTANDARD LVCMOS12} [get_ports qsfp1_modprsl] +set_property -dict {LOC AV21 IOSTANDARD LVCMOS12} [get_ports qsfp1_intl] +set_property -dict {LOC AV22 IOSTANDARD LVCMOS12} [get_ports qsfp1_lpmode] +set_property -dict {LOC AR21 IOSTANDARD LVCMOS12} [get_ports qsfp1_refclk_reset] +set_property -dict {LOC AR22 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[0]}] +set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}] + +# 156.25 MHz MGT reference clock (from SI570) +#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p] + +# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01) +#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p] + +# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10) +#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p] + +# I2C interface +#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset] +set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl] +set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda] + +# PCIe Interface +#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7 +#set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6 +#set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5 +#set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4 +#set_property -dict {LOC AM11 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_226 +#set_property -dict {LOC AM10 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_226 +#set_property -dict {LOC BD21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_p] + + diff --git a/fpga/lib/eth/example/AU250/fpga_10g/fpga/Makefile b/fpga/lib/eth/example/AU250/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..51f3d722c --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/fpga/Makefile @@ -0,0 +1,72 @@ + +# FPGA settings +FPGA_PART = xcu250-figd2104-2-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_register.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/sync_reset.tcl + +# IP +IP_TCL_FILES = ip/gtwizard_ultrascale_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + diff --git a/fpga/lib/eth/example/AU250/fpga_10g/ip/gtwizard_ultrascale_0.tcl b/fpga/lib/eth/example/AU250/fpga_10g/ip/gtwizard_ultrascale_0.tcl new file mode 100644 index 000000000..15ed206ac --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/ip/gtwizard_ultrascale_0.tcl @@ -0,0 +1,21 @@ + +create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name gtwizard_ultrascale_0 + +set_property -dict [list CONFIG.preset {GTY-10GBASE-R}] [get_ips gtwizard_ultrascale_0] + +set_property -dict [list \ + CONFIG.CHANNEL_ENABLE {X1Y47 X1Y46 X1Y45 X1Y44 X1Y43 X1Y42 X1Y41 X1Y40} \ + CONFIG.TX_MASTER_CHANNEL {X1Y44} \ + CONFIG.RX_MASTER_CHANNEL {X1Y44} \ + CONFIG.TX_LINE_RATE {10.3125} \ + CONFIG.TX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.TX_USER_DATA_WIDTH {64} \ + CONFIG.TX_INT_DATA_WIDTH {64} \ + CONFIG.RX_LINE_RATE {10.3125} \ + CONFIG.RX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.RX_USER_DATA_WIDTH {64} \ + CONFIG.RX_INT_DATA_WIDTH {64} \ + CONFIG.RX_REFCLK_SOURCE {X1Y47 clk1 X1Y46 clk1 X1Y45 clk1 X1Y44 clk1 X1Y43 clk1+1 X1Y42 clk1+1 X1Y41 clk1+1 X1Y40 clk1+1} \ + CONFIG.TX_REFCLK_SOURCE {X1Y47 clk1 X1Y46 clk1 X1Y45 clk1 X1Y44 clk1 X1Y43 clk1+1 X1Y42 clk1+1 X1Y41 clk1+1 X1Y40 clk1+1} \ + CONFIG.FREERUN_FREQUENCY {125} \ +] [get_ips gtwizard_ultrascale_0] diff --git a/fpga/lib/eth/example/AU250/fpga_10g/lib/eth b/fpga/lib/eth/example/AU250/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/rtl/debounce_switch.v b/fpga/lib/eth/example/AU250/fpga_10g/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga.v b/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..5a5a66c0e --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga.v @@ -0,0 +1,986 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Reset: Push button, active low + */ + input wire reset, + + /* + * GPIO + */ + input wire [3:0] sw, + output wire [2:0] led, + + /* + * I2C for board management + */ + inout wire i2c_scl, + inout wire i2c_sda, + + /* + * Ethernet: QSFP28 + */ + output wire qsfp0_tx1_p, + output wire qsfp0_tx1_n, + input wire qsfp0_rx1_p, + input wire qsfp0_rx1_n, + output wire qsfp0_tx2_p, + output wire qsfp0_tx2_n, + input wire qsfp0_rx2_p, + input wire qsfp0_rx2_n, + output wire qsfp0_tx3_p, + output wire qsfp0_tx3_n, + input wire qsfp0_rx3_p, + input wire qsfp0_rx3_n, + output wire qsfp0_tx4_p, + output wire qsfp0_tx4_n, + input wire qsfp0_rx4_p, + input wire qsfp0_rx4_n, + // input wire qsfp0_mgt_refclk_0_p, + // input wire qsfp0_mgt_refclk_0_n, + input wire qsfp0_mgt_refclk_1_p, + input wire qsfp0_mgt_refclk_1_n, + output wire qsfp0_modsell, + output wire qsfp0_resetl, + input wire qsfp0_modprsl, + input wire qsfp0_intl, + output wire qsfp0_lpmode, + output wire qsfp0_refclk_reset, + output wire [1:0] qsfp0_fs, + + output wire qsfp1_tx1_p, + output wire qsfp1_tx1_n, + input wire qsfp1_rx1_p, + input wire qsfp1_rx1_n, + output wire qsfp1_tx2_p, + output wire qsfp1_tx2_n, + input wire qsfp1_rx2_p, + input wire qsfp1_rx2_n, + output wire qsfp1_tx3_p, + output wire qsfp1_tx3_n, + input wire qsfp1_rx3_p, + input wire qsfp1_rx3_n, + output wire qsfp1_tx4_p, + output wire qsfp1_tx4_n, + input wire qsfp1_rx4_p, + input wire qsfp1_rx4_n, + // input wire qsfp1_mgt_refclk_0_p, + // input wire qsfp1_mgt_refclk_0_n, + // input wire qsfp1_mgt_refclk_1_p, + // input wire qsfp1_mgt_refclk_1_n, + output wire qsfp1_modsell, + output wire qsfp1_resetl, + input wire qsfp1_modprsl, + input wire qsfp1_intl, + output wire qsfp1_lpmode, + output wire qsfp1_refclk_reset, + output wire [1:0] qsfp1_fs, + + /* + * UART: 500000 bps, 8N1 + */ + output wire uart_rxd, + input wire uart_txd +); + +// Clock and reset + +wire cfgmclk_int; + +wire clk_161mhz_ref_int; + +// 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; +wire mmcm_locked; +wire mmcm_clkfb; + +// MMCM instance +// 161.13 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 64, D = 11 sets Fvco = 937.5 MHz (in range) +// Divide by 7.5 to get output frequency of 125 MHz +MMCME4_BASE #( + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE_F(7.5), + .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(64), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(11), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(6.206), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_161mhz_ref_int), + .CLKFBIN(mmcm_clkfb), + .RST(mmcm_rst), + .PWRDWN(1'b0), + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .out(rst_125mhz_int) +); + +// GPIO +wire [3:0] sw_int; + +debounce_switch #( + .WIDTH(4), + .N(4), + .RATE(156000) +) +debounce_switch_inst ( + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + .in({sw}), + .out({sw_int}) +); + +wire uart_txd_int; + +sync_signal #( + .WIDTH(1), + .N(2) +) +sync_signal_inst ( + .clk(clk_156mhz_int), + .in({uart_txd}), + .out({uart_txd_int}) +); + +// SI570 I2C +wire i2c_scl_i; +wire i2c_scl_o = 1'b1; +wire i2c_scl_t = 1'b1; +wire i2c_sda_i; +wire i2c_sda_o = 1'b1; +wire i2c_sda_t = 1'b1; + +assign i2c_scl_i = i2c_scl; +assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o; +assign i2c_sda_i = i2c_sda; +assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o; + +// startupe3 instance +wire cfgmclk; + +STARTUPE3 +startupe3_inst ( + .CFGCLK(), + .CFGMCLK(cfgmclk), + .DI(4'd0), + .DO(), + .DTS(1'b1), + .EOS(), + .FCSBO(1'b0), + .FCSBTS(1'b1), + .GSR(1'b0), + .GTS(1'b0), + .KEYCLEARB(1'b1), + .PACK(1'b0), + .PREQ(), + .USRCCLKO(1'b0), + .USRCCLKTS(1'b1), + .USRDONEO(1'b0), + .USRDONETS(1'b1) +); + +BUFG +cfgmclk_bufg_inst ( + .I(cfgmclk), + .O(cfgmclk_int) +); + +// configure SI5335 clock generators +reg qsfp_refclk_reset_reg = 1'b1; +reg sys_reset_reg = 1'b1; + +reg [9:0] reset_timer_reg = 0; + +assign mmcm_rst = sys_reset_reg; + +always @(posedge cfgmclk_int) begin + if (&reset_timer_reg) begin + if (qsfp_refclk_reset_reg) begin + qsfp_refclk_reset_reg <= 1'b0; + reset_timer_reg <= 0; + end else begin + qsfp_refclk_reset_reg <= 1'b0; + sys_reset_reg <= 1'b0; + end + end else begin + reset_timer_reg <= reset_timer_reg + 1; + end + + if (!reset) begin + qsfp_refclk_reset_reg <= 1'b1; + sys_reset_reg <= 1'b1; + reset_timer_reg <= 0; + end +end + +// XGMII 10G PHY +assign qsfp0_modsell = 1'b0; +assign qsfp0_resetl = 1'b1; +assign qsfp0_lpmode = 1'b0; +assign qsfp0_refclk_reset = qsfp_refclk_reset_reg; +assign qsfp0_fs = 2'b10; + +wire qsfp0_tx_clk_1_int; +wire qsfp0_tx_rst_1_int; +wire [63:0] qsfp0_txd_1_int; +wire [7:0] qsfp0_txc_1_int; +wire qsfp0_rx_clk_1_int; +wire qsfp0_rx_rst_1_int; +wire [63:0] qsfp0_rxd_1_int; +wire [7:0] qsfp0_rxc_1_int; +wire qsfp0_tx_clk_2_int; +wire qsfp0_tx_rst_2_int; +wire [63:0] qsfp0_txd_2_int; +wire [7:0] qsfp0_txc_2_int; +wire qsfp0_rx_clk_2_int; +wire qsfp0_rx_rst_2_int; +wire [63:0] qsfp0_rxd_2_int; +wire [7:0] qsfp0_rxc_2_int; +wire qsfp0_tx_clk_3_int; +wire qsfp0_tx_rst_3_int; +wire [63:0] qsfp0_txd_3_int; +wire [7:0] qsfp0_txc_3_int; +wire qsfp0_rx_clk_3_int; +wire qsfp0_rx_rst_3_int; +wire [63:0] qsfp0_rxd_3_int; +wire [7:0] qsfp0_rxc_3_int; +wire qsfp0_tx_clk_4_int; +wire qsfp0_tx_rst_4_int; +wire [63:0] qsfp0_txd_4_int; +wire [7:0] qsfp0_txc_4_int; +wire qsfp0_rx_clk_4_int; +wire qsfp0_rx_rst_4_int; +wire [63:0] qsfp0_rxd_4_int; +wire [7:0] qsfp0_rxc_4_int; + +assign qsfp1_modsell = 1'b0; +assign qsfp1_resetl = 1'b1; +assign qsfp1_lpmode = 1'b0; +assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; +assign qsfp1_fs = 2'b10; + +wire qsfp1_tx_clk_1_int; +wire qsfp1_tx_rst_1_int; +wire [63:0] qsfp1_txd_1_int; +wire [7:0] qsfp1_txc_1_int; +wire qsfp1_rx_clk_1_int; +wire qsfp1_rx_rst_1_int; +wire [63:0] qsfp1_rxd_1_int; +wire [7:0] qsfp1_rxc_1_int; +wire qsfp1_tx_clk_2_int; +wire qsfp1_tx_rst_2_int; +wire [63:0] qsfp1_txd_2_int; +wire [7:0] qsfp1_txc_2_int; +wire qsfp1_rx_clk_2_int; +wire qsfp1_rx_rst_2_int; +wire [63:0] qsfp1_rxd_2_int; +wire [7:0] qsfp1_rxc_2_int; +wire qsfp1_tx_clk_3_int; +wire qsfp1_tx_rst_3_int; +wire [63:0] qsfp1_txd_3_int; +wire [7:0] qsfp1_txc_3_int; +wire qsfp1_rx_clk_3_int; +wire qsfp1_rx_rst_3_int; +wire [63:0] qsfp1_rxd_3_int; +wire [7:0] qsfp1_rxc_3_int; +wire qsfp1_tx_clk_4_int; +wire qsfp1_tx_rst_4_int; +wire [63:0] qsfp1_txd_4_int; +wire [7:0] qsfp1_txc_4_int; +wire qsfp1_rx_clk_4_int; +wire qsfp1_rx_rst_4_int; +wire [63:0] qsfp1_rxd_4_int; +wire [7:0] qsfp1_rxc_4_int; + +wire qsfp0_rx_block_lock_1; +wire qsfp0_rx_block_lock_2; +wire qsfp0_rx_block_lock_3; +wire qsfp0_rx_block_lock_4; + +wire qsfp1_rx_block_lock_1; +wire qsfp1_rx_block_lock_2; +wire qsfp1_rx_block_lock_3; +wire qsfp1_rx_block_lock_4; + +wire [7:0] qsfp_gtpowergood; + +wire qsfp0_mgt_refclk_1; +wire qsfp0_mgt_refclk_1_int; +wire qsfp0_mgt_refclk_1_bufg; + +assign clk_161mhz_ref_int = qsfp0_mgt_refclk_1_bufg; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_qsfp0_mgt_refclk_1_inst ( + .I (qsfp0_mgt_refclk_1_p), + .IB (qsfp0_mgt_refclk_1_n), + .CEB (1'b0), + .O (qsfp0_mgt_refclk_1), + .ODIV2 (qsfp0_mgt_refclk_1_int) +); + +BUFG_GT bufg_gt_refclk_inst ( + .CE (&qsfp_gtpowergood), + .CEMASK (1'b1), + .CLR (1'b0), + .CLRMASK (1'b1), + .DIV (3'd0), + .I (qsfp0_mgt_refclk_1_int), + .O (qsfp0_mgt_refclk_1_bufg) +); + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .out(rst_156mhz_int) +); + +wire [5:0] qsfp0_gt_txheader_1; +wire [63:0] qsfp0_gt_txdata_1; +wire qsfp0_gt_rxgearboxslip_1; +wire [5:0] qsfp0_gt_rxheader_1; +wire [1:0] qsfp0_gt_rxheadervalid_1; +wire [63:0] qsfp0_gt_rxdata_1; +wire [1:0] qsfp0_gt_rxdatavalid_1; + +wire [5:0] qsfp0_gt_txheader_2; +wire [63:0] qsfp0_gt_txdata_2; +wire qsfp0_gt_rxgearboxslip_2; +wire [5:0] qsfp0_gt_rxheader_2; +wire [1:0] qsfp0_gt_rxheadervalid_2; +wire [63:0] qsfp0_gt_rxdata_2; +wire [1:0] qsfp0_gt_rxdatavalid_2; + +wire [5:0] qsfp0_gt_txheader_3; +wire [63:0] qsfp0_gt_txdata_3; +wire qsfp0_gt_rxgearboxslip_3; +wire [5:0] qsfp0_gt_rxheader_3; +wire [1:0] qsfp0_gt_rxheadervalid_3; +wire [63:0] qsfp0_gt_rxdata_3; +wire [1:0] qsfp0_gt_rxdatavalid_3; + +wire [5:0] qsfp0_gt_txheader_4; +wire [63:0] qsfp0_gt_txdata_4; +wire qsfp0_gt_rxgearboxslip_4; +wire [5:0] qsfp0_gt_rxheader_4; +wire [1:0] qsfp0_gt_rxheadervalid_4; +wire [63:0] qsfp0_gt_rxdata_4; +wire [1:0] qsfp0_gt_rxdatavalid_4; + +wire [5:0] qsfp1_gt_txheader_1; +wire [63:0] qsfp1_gt_txdata_1; +wire qsfp1_gt_rxgearboxslip_1; +wire [5:0] qsfp1_gt_rxheader_1; +wire [1:0] qsfp1_gt_rxheadervalid_1; +wire [63:0] qsfp1_gt_rxdata_1; +wire [1:0] qsfp1_gt_rxdatavalid_1; + +wire [5:0] qsfp1_gt_txheader_2; +wire [63:0] qsfp1_gt_txdata_2; +wire qsfp1_gt_rxgearboxslip_2; +wire [5:0] qsfp1_gt_rxheader_2; +wire [1:0] qsfp1_gt_rxheadervalid_2; +wire [63:0] qsfp1_gt_rxdata_2; +wire [1:0] qsfp1_gt_rxdatavalid_2; + +wire [5:0] qsfp1_gt_txheader_3; +wire [63:0] qsfp1_gt_txdata_3; +wire qsfp1_gt_rxgearboxslip_3; +wire [5:0] qsfp1_gt_rxheader_3; +wire [1:0] qsfp1_gt_rxheadervalid_3; +wire [63:0] qsfp1_gt_rxdata_3; +wire [1:0] qsfp1_gt_rxdatavalid_3; + +wire [5:0] qsfp1_gt_txheader_4; +wire [63:0] qsfp1_gt_txdata_4; +wire qsfp1_gt_rxgearboxslip_4; +wire [5:0] qsfp1_gt_rxheader_4; +wire [1:0] qsfp1_gt_rxheadervalid_4; +wire [63:0] qsfp1_gt_rxdata_4; +wire [1:0] qsfp1_gt_rxdatavalid_4; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({2{qsfp0_mgt_refclk_1}}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp0_rx4_n, qsfp0_rx3_n, qsfp0_rx2_n, qsfp0_rx1_n, qsfp1_rx4_n, qsfp1_rx3_n, qsfp1_rx2_n, qsfp1_rx1_n}), + .gtyrxp_in({qsfp0_rx4_p, qsfp0_rx3_p, qsfp0_rx2_p, qsfp0_rx1_p, qsfp1_rx4_p, qsfp1_rx3_p, qsfp1_rx2_p, qsfp1_rx1_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .gtwiz_userdata_tx_in({qsfp0_gt_txdata_4, qsfp0_gt_txdata_3, qsfp0_gt_txdata_2, qsfp0_gt_txdata_1, qsfp1_gt_txdata_4, qsfp1_gt_txdata_3, qsfp1_gt_txdata_2, qsfp1_gt_txdata_1}), + .txheader_in({qsfp0_gt_txheader_4, qsfp0_gt_txheader_3, qsfp0_gt_txheader_2, qsfp0_gt_txheader_1, qsfp1_gt_txheader_4, qsfp1_gt_txheader_3, qsfp1_gt_txheader_2, qsfp1_gt_txheader_1}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out(qsfp_gtpowergood), + + .gtytxn_out({qsfp0_tx4_n, qsfp0_tx3_n, qsfp0_tx2_n, qsfp0_tx1_n, qsfp1_tx4_n, qsfp1_tx3_n, qsfp1_tx2_n, qsfp1_tx1_n}), + .gtytxp_out({qsfp0_tx4_p, qsfp0_tx3_p, qsfp0_tx2_p, qsfp0_tx1_p, qsfp1_tx4_p, qsfp1_tx3_p, qsfp1_tx2_p, qsfp1_tx1_p}), + + .rxgearboxslip_in({qsfp0_gt_rxgearboxslip_4, qsfp0_gt_rxgearboxslip_3, qsfp0_gt_rxgearboxslip_2, qsfp0_gt_rxgearboxslip_1, qsfp1_gt_rxgearboxslip_4, qsfp1_gt_rxgearboxslip_3, qsfp1_gt_rxgearboxslip_2, qsfp1_gt_rxgearboxslip_1}), + .gtwiz_userdata_rx_out({qsfp0_gt_rxdata_4, qsfp0_gt_rxdata_3, qsfp0_gt_rxdata_2, qsfp0_gt_rxdata_1, qsfp1_gt_rxdata_4, qsfp1_gt_rxdata_3, qsfp1_gt_rxdata_2, qsfp1_gt_rxdata_1}), + .rxdatavalid_out({qsfp0_gt_rxdatavalid_4, qsfp0_gt_rxdatavalid_3, qsfp0_gt_rxdatavalid_2, qsfp0_gt_rxdatavalid_1, qsfp1_gt_rxdatavalid_4, qsfp1_gt_rxdatavalid_3, qsfp1_gt_rxdatavalid_2, qsfp1_gt_rxdatavalid_1}), + .rxheader_out({qsfp0_gt_rxheader_4, qsfp0_gt_rxheader_3, qsfp0_gt_rxheader_2, qsfp0_gt_rxheader_1, qsfp1_gt_rxheader_4, qsfp1_gt_rxheader_3, qsfp1_gt_rxheader_2, qsfp1_gt_rxheader_1}), + .rxheadervalid_out({qsfp0_gt_rxheadervalid_4, qsfp0_gt_rxheadervalid_3, qsfp0_gt_rxheadervalid_2, qsfp0_gt_rxheadervalid_1, qsfp1_gt_rxheadervalid_4, qsfp1_gt_rxheadervalid_3, qsfp1_gt_rxheadervalid_2, qsfp1_gt_rxheadervalid_1}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp0_tx_clk_1_int = clk_156mhz_int; +assign qsfp0_tx_rst_1_int = rst_156mhz_int; + +assign qsfp0_rx_clk_1_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_1_reset_sync_inst ( + .clk(qsfp0_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_1_inst ( + .tx_clk(qsfp0_tx_clk_1_int), + .tx_rst(qsfp0_tx_rst_1_int), + .rx_clk(qsfp0_rx_clk_1_int), + .rx_rst(qsfp0_rx_rst_1_int), + .xgmii_txd(qsfp0_txd_1_int), + .xgmii_txc(qsfp0_txc_1_int), + .xgmii_rxd(qsfp0_rxd_1_int), + .xgmii_rxc(qsfp0_rxc_1_int), + .serdes_tx_data(qsfp0_gt_txdata_1), + .serdes_tx_hdr(qsfp0_gt_txheader_1), + .serdes_rx_data(qsfp0_gt_rxdata_1), + .serdes_rx_hdr(qsfp0_gt_rxheader_1), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_1), + .rx_block_lock(qsfp0_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp0_tx_clk_2_int = clk_156mhz_int; +assign qsfp0_tx_rst_2_int = rst_156mhz_int; + +assign qsfp0_rx_clk_2_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_2_reset_sync_inst ( + .clk(qsfp0_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_2_inst ( + .tx_clk(qsfp0_tx_clk_2_int), + .tx_rst(qsfp0_tx_rst_2_int), + .rx_clk(qsfp0_rx_clk_2_int), + .rx_rst(qsfp0_rx_rst_2_int), + .xgmii_txd(qsfp0_txd_2_int), + .xgmii_txc(qsfp0_txc_2_int), + .xgmii_rxd(qsfp0_rxd_2_int), + .xgmii_rxc(qsfp0_rxc_2_int), + .serdes_tx_data(qsfp0_gt_txdata_2), + .serdes_tx_hdr(qsfp0_gt_txheader_2), + .serdes_rx_data(qsfp0_gt_rxdata_2), + .serdes_rx_hdr(qsfp0_gt_rxheader_2), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_2), + .rx_block_lock(qsfp0_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp0_tx_clk_3_int = clk_156mhz_int; +assign qsfp0_tx_rst_3_int = rst_156mhz_int; + +assign qsfp0_rx_clk_3_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_3_reset_sync_inst ( + .clk(qsfp0_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_3_inst ( + .tx_clk(qsfp0_tx_clk_3_int), + .tx_rst(qsfp0_tx_rst_3_int), + .rx_clk(qsfp0_rx_clk_3_int), + .rx_rst(qsfp0_rx_rst_3_int), + .xgmii_txd(qsfp0_txd_3_int), + .xgmii_txc(qsfp0_txc_3_int), + .xgmii_rxd(qsfp0_rxd_3_int), + .xgmii_rxc(qsfp0_rxc_3_int), + .serdes_tx_data(qsfp0_gt_txdata_3), + .serdes_tx_hdr(qsfp0_gt_txheader_3), + .serdes_rx_data(qsfp0_gt_rxdata_3), + .serdes_rx_hdr(qsfp0_gt_rxheader_3), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_3), + .rx_block_lock(qsfp0_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp0_tx_clk_4_int = clk_156mhz_int; +assign qsfp0_tx_rst_4_int = rst_156mhz_int; + +assign qsfp0_rx_clk_4_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp0_rx_rst_4_reset_sync_inst ( + .clk(qsfp0_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .out(qsfp0_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp0_phy_4_inst ( + .tx_clk(qsfp0_tx_clk_4_int), + .tx_rst(qsfp0_tx_rst_4_int), + .rx_clk(qsfp0_rx_clk_4_int), + .rx_rst(qsfp0_rx_rst_4_int), + .xgmii_txd(qsfp0_txd_4_int), + .xgmii_txc(qsfp0_txc_4_int), + .xgmii_rxd(qsfp0_rxd_4_int), + .xgmii_rxc(qsfp0_rxc_4_int), + .serdes_tx_data(qsfp0_gt_txdata_4), + .serdes_tx_hdr(qsfp0_gt_txheader_4), + .serdes_rx_data(qsfp0_gt_rxdata_4), + .serdes_rx_hdr(qsfp0_gt_rxheader_4), + .serdes_rx_bitslip(qsfp0_gt_rxgearboxslip_4), + .rx_block_lock(qsfp0_rx_block_lock_4), + .rx_high_ber() +); + +assign qsfp1_tx_clk_1_int = clk_156mhz_int; +assign qsfp1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp1_rx_clk_1_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_1_reset_sync_inst ( + .clk(qsfp1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_1_inst ( + .tx_clk(qsfp1_tx_clk_1_int), + .tx_rst(qsfp1_tx_rst_1_int), + .rx_clk(qsfp1_rx_clk_1_int), + .rx_rst(qsfp1_rx_rst_1_int), + .xgmii_txd(qsfp1_txd_1_int), + .xgmii_txc(qsfp1_txc_1_int), + .xgmii_rxd(qsfp1_rxd_1_int), + .xgmii_rxc(qsfp1_rxc_1_int), + .serdes_tx_data(qsfp1_gt_txdata_1), + .serdes_tx_hdr(qsfp1_gt_txheader_1), + .serdes_rx_data(qsfp1_gt_rxdata_1), + .serdes_rx_hdr(qsfp1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp1_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp1_tx_clk_2_int = clk_156mhz_int; +assign qsfp1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp1_rx_clk_2_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_2_reset_sync_inst ( + .clk(qsfp1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_2_inst ( + .tx_clk(qsfp1_tx_clk_2_int), + .tx_rst(qsfp1_tx_rst_2_int), + .rx_clk(qsfp1_rx_clk_2_int), + .rx_rst(qsfp1_rx_rst_2_int), + .xgmii_txd(qsfp1_txd_2_int), + .xgmii_txc(qsfp1_txc_2_int), + .xgmii_rxd(qsfp1_rxd_2_int), + .xgmii_rxc(qsfp1_rxc_2_int), + .serdes_tx_data(qsfp1_gt_txdata_2), + .serdes_tx_hdr(qsfp1_gt_txheader_2), + .serdes_rx_data(qsfp1_gt_rxdata_2), + .serdes_rx_hdr(qsfp1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp1_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp1_tx_clk_3_int = clk_156mhz_int; +assign qsfp1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp1_rx_clk_3_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_3_reset_sync_inst ( + .clk(qsfp1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_3_inst ( + .tx_clk(qsfp1_tx_clk_3_int), + .tx_rst(qsfp1_tx_rst_3_int), + .rx_clk(qsfp1_rx_clk_3_int), + .rx_rst(qsfp1_rx_rst_3_int), + .xgmii_txd(qsfp1_txd_3_int), + .xgmii_txc(qsfp1_txc_3_int), + .xgmii_rxd(qsfp1_rxd_3_int), + .xgmii_rxc(qsfp1_rxc_3_int), + .serdes_tx_data(qsfp1_gt_txdata_3), + .serdes_tx_hdr(qsfp1_gt_txheader_3), + .serdes_rx_data(qsfp1_gt_rxdata_3), + .serdes_rx_hdr(qsfp1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp1_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp1_tx_clk_4_int = clk_156mhz_int; +assign qsfp1_tx_rst_4_int = rst_156mhz_int; + +assign qsfp1_rx_clk_4_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp1_rx_rst_4_reset_sync_inst ( + .clk(qsfp1_rx_clk_4_int), + .rst(~gt_reset_rx_done), + .out(qsfp1_rx_rst_4_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp1_phy_4_inst ( + .tx_clk(qsfp1_tx_clk_4_int), + .tx_rst(qsfp1_tx_rst_4_int), + .rx_clk(qsfp1_rx_clk_4_int), + .rx_rst(qsfp1_rx_rst_4_int), + .xgmii_txd(qsfp1_txd_4_int), + .xgmii_txc(qsfp1_txc_4_int), + .xgmii_rxd(qsfp1_rxd_4_int), + .xgmii_rxc(qsfp1_rxc_4_int), + .serdes_tx_data(qsfp1_gt_txdata_4), + .serdes_tx_hdr(qsfp1_gt_txheader_4), + .serdes_rx_data(qsfp1_gt_rxdata_4), + .serdes_rx_hdr(qsfp1_gt_rxheader_4), + .serdes_rx_bitslip(qsfp1_gt_rxgearboxslip_4), + .rx_block_lock(qsfp1_rx_block_lock_4), + .rx_high_ber() +); + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .sw(sw_int), + .led(led), + /* + * Ethernet: QSFP28 + */ + .qsfp0_tx_clk_1(qsfp0_tx_clk_1_int), + .qsfp0_tx_rst_1(qsfp0_tx_rst_1_int), + .qsfp0_txd_1(qsfp0_txd_1_int), + .qsfp0_txc_1(qsfp0_txc_1_int), + .qsfp0_rx_clk_1(qsfp0_rx_clk_1_int), + .qsfp0_rx_rst_1(qsfp0_rx_rst_1_int), + .qsfp0_rxd_1(qsfp0_rxd_1_int), + .qsfp0_rxc_1(qsfp0_rxc_1_int), + .qsfp0_tx_clk_2(qsfp0_tx_clk_2_int), + .qsfp0_tx_rst_2(qsfp0_tx_rst_2_int), + .qsfp0_txd_2(qsfp0_txd_2_int), + .qsfp0_txc_2(qsfp0_txc_2_int), + .qsfp0_rx_clk_2(qsfp0_rx_clk_2_int), + .qsfp0_rx_rst_2(qsfp0_rx_rst_2_int), + .qsfp0_rxd_2(qsfp0_rxd_2_int), + .qsfp0_rxc_2(qsfp0_rxc_2_int), + .qsfp0_tx_clk_3(qsfp0_tx_clk_3_int), + .qsfp0_tx_rst_3(qsfp0_tx_rst_3_int), + .qsfp0_txd_3(qsfp0_txd_3_int), + .qsfp0_txc_3(qsfp0_txc_3_int), + .qsfp0_rx_clk_3(qsfp0_rx_clk_3_int), + .qsfp0_rx_rst_3(qsfp0_rx_rst_3_int), + .qsfp0_rxd_3(qsfp0_rxd_3_int), + .qsfp0_rxc_3(qsfp0_rxc_3_int), + .qsfp0_tx_clk_4(qsfp0_tx_clk_4_int), + .qsfp0_tx_rst_4(qsfp0_tx_rst_4_int), + .qsfp0_txd_4(qsfp0_txd_4_int), + .qsfp0_txc_4(qsfp0_txc_4_int), + .qsfp0_rx_clk_4(qsfp0_rx_clk_4_int), + .qsfp0_rx_rst_4(qsfp0_rx_rst_4_int), + .qsfp0_rxd_4(qsfp0_rxd_4_int), + .qsfp0_rxc_4(qsfp0_rxc_4_int), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), + .qsfp1_txd_1(qsfp1_txd_1_int), + .qsfp1_txc_1(qsfp1_txc_1_int), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), + .qsfp1_rxd_1(qsfp1_rxd_1_int), + .qsfp1_rxc_1(qsfp1_rxc_1_int), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), + .qsfp1_txd_2(qsfp1_txd_2_int), + .qsfp1_txc_2(qsfp1_txc_2_int), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), + .qsfp1_rxd_2(qsfp1_rxd_2_int), + .qsfp1_rxc_2(qsfp1_rxc_2_int), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), + .qsfp1_txd_3(qsfp1_txd_3_int), + .qsfp1_txc_3(qsfp1_txc_3_int), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), + .qsfp1_rxd_3(qsfp1_rxd_3_int), + .qsfp1_rxc_3(qsfp1_rxc_3_int), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), + .qsfp1_txd_4(qsfp1_txd_4_int), + .qsfp1_txc_4(qsfp1_txc_4_int), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), + .qsfp1_rxd_4(qsfp1_rxd_4_int), + .qsfp1_rxc_4(qsfp1_rxc_4_int), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd), + .uart_txd(uart_txd_int) +); + +endmodule diff --git a/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga_core.v b/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..70039a58b --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,664 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire [3:0] sw, + output wire [2:0] led, + + /* + * Ethernet: QSFP28 + */ + input wire qsfp0_tx_clk_1, + input wire qsfp0_tx_rst_1, + output wire [63:0] qsfp0_txd_1, + output wire [7:0] qsfp0_txc_1, + input wire qsfp0_rx_clk_1, + input wire qsfp0_rx_rst_1, + input wire [63:0] qsfp0_rxd_1, + input wire [7:0] qsfp0_rxc_1, + input wire qsfp0_tx_clk_2, + input wire qsfp0_tx_rst_2, + output wire [63:0] qsfp0_txd_2, + output wire [7:0] qsfp0_txc_2, + input wire qsfp0_rx_clk_2, + input wire qsfp0_rx_rst_2, + input wire [63:0] qsfp0_rxd_2, + input wire [7:0] qsfp0_rxc_2, + input wire qsfp0_tx_clk_3, + input wire qsfp0_tx_rst_3, + output wire [63:0] qsfp0_txd_3, + output wire [7:0] qsfp0_txc_3, + input wire qsfp0_rx_clk_3, + input wire qsfp0_rx_rst_3, + input wire [63:0] qsfp0_rxd_3, + input wire [7:0] qsfp0_rxc_3, + input wire qsfp0_tx_clk_4, + input wire qsfp0_tx_rst_4, + output wire [63:0] qsfp0_txd_4, + output wire [7:0] qsfp0_txc_4, + input wire qsfp0_rx_clk_4, + input wire qsfp0_rx_rst_4, + input wire [63:0] qsfp0_rxd_4, + input wire [7:0] qsfp0_rxc_4, + input wire qsfp1_tx_clk_1, + input wire qsfp1_tx_rst_1, + output wire [63:0] qsfp1_txd_1, + output wire [7:0] qsfp1_txc_1, + input wire qsfp1_rx_clk_1, + input wire qsfp1_rx_rst_1, + input wire [63:0] qsfp1_rxd_1, + input wire [7:0] qsfp1_rxc_1, + input wire qsfp1_tx_clk_2, + input wire qsfp1_tx_rst_2, + output wire [63:0] qsfp1_txd_2, + output wire [7:0] qsfp1_txc_2, + input wire qsfp1_rx_clk_2, + input wire qsfp1_rx_rst_2, + input wire [63:0] qsfp1_rxd_2, + input wire [7:0] qsfp1_rxc_2, + input wire qsfp1_tx_clk_3, + input wire qsfp1_tx_rst_3, + output wire [63:0] qsfp1_txd_3, + output wire [7:0] qsfp1_txc_3, + input wire qsfp1_rx_clk_3, + input wire qsfp1_rx_rst_3, + input wire [63:0] qsfp1_rxd_3, + input wire [7:0] qsfp1_rxc_3, + input wire qsfp1_tx_clk_4, + input wire qsfp1_tx_rst_4, + output wire [63:0] qsfp1_txd_4, + output wire [7:0] qsfp1_txc_4, + input wire qsfp1_rx_clk_4, + input wire qsfp1_rx_rst_4, + input wire [63:0] qsfp1_rxd_4, + input wire [7:0] qsfp1_rxc_4, + + /* + * UART: 115200 bps, 8N1 + */ + output wire uart_rxd, + input wire uart_txd +); + +// 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 led = sw; +assign led = led_reg; + +assign qsfp0_txd_2 = 64'h0707070707070707; +assign qsfp0_txc_2 = 8'hff; +assign qsfp0_txd_3 = 64'h0707070707070707; +assign qsfp0_txc_3 = 8'hff; +assign qsfp0_txd_4 = 64'h0707070707070707; +assign qsfp0_txc_4 = 8'hff; + +assign qsfp1_txd_1 = 64'h0707070707070707; +assign qsfp1_txc_1 = 8'hff; +assign qsfp1_txd_2 = 64'h0707070707070707; +assign qsfp1_txc_2 = 8'hff; +assign qsfp1_txd_3 = 64'h0707070707070707; +assign qsfp1_txc_3 = 8'hff; +assign qsfp1_txd_4 = 64'h0707070707070707; +assign qsfp1_txc_4 = 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(qsfp0_rx_clk_1), + .rx_rst(qsfp0_rx_rst_1), + .tx_clk(qsfp0_tx_clk_1), + .tx_rst(qsfp0_tx_rst_1), + .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(qsfp0_rxd_1), + .xgmii_rxc(qsfp0_rxc_1), + .xgmii_txd(qsfp0_txd_1), + .xgmii_txc(qsfp0_txc_1), + + .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 diff --git a/fpga/lib/eth/example/AU250/fpga_10g/rtl/sync_signal.v b/fpga/lib/eth/example/AU250/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/arp_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/axis_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/eth_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/ip_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..b2a0e316a --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,465 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-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. + +""" + +from myhdl import * +import os + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sw = Signal(intbv(0)[4:]) + qsfp0_tx_clk_1 = Signal(bool(0)) + qsfp0_tx_rst_1 = Signal(bool(0)) + qsfp0_rx_clk_1 = Signal(bool(0)) + qsfp0_rx_rst_1 = Signal(bool(0)) + qsfp0_rxd_1 = Signal(intbv(0)[64:]) + qsfp0_rxc_1 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_2 = Signal(bool(0)) + qsfp0_tx_rst_2 = Signal(bool(0)) + qsfp0_rx_clk_2 = Signal(bool(0)) + qsfp0_rx_rst_2 = Signal(bool(0)) + qsfp0_rxd_2 = Signal(intbv(0)[64:]) + qsfp0_rxc_2 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_3 = Signal(bool(0)) + qsfp0_tx_rst_3 = Signal(bool(0)) + qsfp0_rx_clk_3 = Signal(bool(0)) + qsfp0_rx_rst_3 = Signal(bool(0)) + qsfp0_rxd_3 = Signal(intbv(0)[64:]) + qsfp0_rxc_3 = Signal(intbv(0)[8:]) + qsfp0_tx_clk_4 = Signal(bool(0)) + qsfp0_tx_rst_4 = Signal(bool(0)) + qsfp0_rx_clk_4 = Signal(bool(0)) + qsfp0_rx_rst_4 = Signal(bool(0)) + qsfp0_rxd_4 = Signal(intbv(0)[64:]) + qsfp0_rxc_4 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_1 = Signal(bool(0)) + qsfp1_tx_rst_1 = Signal(bool(0)) + qsfp1_rx_clk_1 = Signal(bool(0)) + qsfp1_rx_rst_1 = Signal(bool(0)) + qsfp1_rxd_1 = Signal(intbv(0)[64:]) + qsfp1_rxc_1 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_2 = Signal(bool(0)) + qsfp1_tx_rst_2 = Signal(bool(0)) + qsfp1_rx_clk_2 = Signal(bool(0)) + qsfp1_rx_rst_2 = Signal(bool(0)) + qsfp1_rxd_2 = Signal(intbv(0)[64:]) + qsfp1_rxc_2 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_3 = Signal(bool(0)) + qsfp1_tx_rst_3 = Signal(bool(0)) + qsfp1_rx_clk_3 = Signal(bool(0)) + qsfp1_rx_rst_3 = Signal(bool(0)) + qsfp1_rxd_3 = Signal(intbv(0)[64:]) + qsfp1_rxc_3 = Signal(intbv(0)[8:]) + qsfp1_tx_clk_4 = Signal(bool(0)) + qsfp1_tx_rst_4 = Signal(bool(0)) + qsfp1_rx_clk_4 = Signal(bool(0)) + qsfp1_rx_rst_4 = Signal(bool(0)) + qsfp1_rxd_4 = Signal(intbv(0)[64:]) + qsfp1_rxc_4 = Signal(intbv(0)[8:]) + uart_txd = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[3:]) + qsfp0_txd_1 = Signal(intbv(0)[64:]) + qsfp0_txc_1 = Signal(intbv(0)[8:]) + qsfp0_txd_2 = Signal(intbv(0)[64:]) + qsfp0_txc_2 = Signal(intbv(0)[8:]) + qsfp0_txd_3 = Signal(intbv(0)[64:]) + qsfp0_txc_3 = Signal(intbv(0)[8:]) + qsfp0_txd_4 = Signal(intbv(0)[64:]) + qsfp0_txc_4 = Signal(intbv(0)[8:]) + qsfp1_txd_1 = Signal(intbv(0)[64:]) + qsfp1_txc_1 = Signal(intbv(0)[8:]) + qsfp1_txd_2 = Signal(intbv(0)[64:]) + qsfp1_txc_2 = Signal(intbv(0)[8:]) + qsfp1_txd_3 = Signal(intbv(0)[64:]) + qsfp1_txc_3 = Signal(intbv(0)[8:]) + qsfp1_txd_4 = Signal(intbv(0)[64:]) + qsfp1_txc_4 = Signal(intbv(0)[8:]) + uart_rxd = Signal(bool(0)) + + # sources and sinks + qsfp0_1_source = xgmii_ep.XGMIISource() + qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') + + qsfp0_1_sink = xgmii_ep.XGMIISink() + qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') + + qsfp0_2_source = xgmii_ep.XGMIISource() + qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') + + qsfp0_2_sink = xgmii_ep.XGMIISink() + qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') + + qsfp0_3_source = xgmii_ep.XGMIISource() + qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') + + qsfp0_3_sink = xgmii_ep.XGMIISink() + qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') + + qsfp0_4_source = xgmii_ep.XGMIISource() + qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') + + qsfp0_4_sink = xgmii_ep.XGMIISink() + qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') + + qsfp1_1_source = xgmii_ep.XGMIISource() + qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') + + qsfp1_1_sink = xgmii_ep.XGMIISink() + qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') + + qsfp1_2_source = xgmii_ep.XGMIISource() + qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') + + qsfp1_2_sink = xgmii_ep.XGMIISink() + qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') + + qsfp1_3_source = xgmii_ep.XGMIISource() + qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') + + qsfp1_3_sink = xgmii_ep.XGMIISink() + qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') + + qsfp1_4_source = xgmii_ep.XGMIISource() + qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') + + qsfp1_4_sink = xgmii_ep.XGMIISink() + qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + sw=sw, + led=led, + + qsfp0_tx_clk_1=qsfp0_tx_clk_1, + qsfp0_tx_rst_1=qsfp0_tx_rst_1, + qsfp0_txd_1=qsfp0_txd_1, + qsfp0_txc_1=qsfp0_txc_1, + qsfp0_rx_clk_1=qsfp0_rx_clk_1, + qsfp0_rx_rst_1=qsfp0_rx_rst_1, + qsfp0_rxd_1=qsfp0_rxd_1, + qsfp0_rxc_1=qsfp0_rxc_1, + qsfp0_tx_clk_2=qsfp0_tx_clk_2, + qsfp0_tx_rst_2=qsfp0_tx_rst_2, + qsfp0_txd_2=qsfp0_txd_2, + qsfp0_txc_2=qsfp0_txc_2, + qsfp0_rx_clk_2=qsfp0_rx_clk_2, + qsfp0_rx_rst_2=qsfp0_rx_rst_2, + qsfp0_rxd_2=qsfp0_rxd_2, + qsfp0_rxc_2=qsfp0_rxc_2, + qsfp0_tx_clk_3=qsfp0_tx_clk_3, + qsfp0_tx_rst_3=qsfp0_tx_rst_3, + qsfp0_txd_3=qsfp0_txd_3, + qsfp0_txc_3=qsfp0_txc_3, + qsfp0_rx_clk_3=qsfp0_rx_clk_3, + qsfp0_rx_rst_3=qsfp0_rx_rst_3, + qsfp0_rxd_3=qsfp0_rxd_3, + qsfp0_rxc_3=qsfp0_rxc_3, + qsfp0_tx_clk_4=qsfp0_tx_clk_4, + qsfp0_tx_rst_4=qsfp0_tx_rst_4, + qsfp0_txd_4=qsfp0_txd_4, + qsfp0_txc_4=qsfp0_txc_4, + qsfp0_rx_clk_4=qsfp0_rx_clk_4, + qsfp0_rx_rst_4=qsfp0_rx_rst_4, + qsfp0_rxd_4=qsfp0_rxd_4, + qsfp0_rxc_4=qsfp0_rxc_4, + qsfp1_tx_clk_1=qsfp1_tx_clk_1, + qsfp1_tx_rst_1=qsfp1_tx_rst_1, + qsfp1_txd_1=qsfp1_txd_1, + qsfp1_txc_1=qsfp1_txc_1, + qsfp1_rx_clk_1=qsfp1_rx_clk_1, + qsfp1_rx_rst_1=qsfp1_rx_rst_1, + qsfp1_rxd_1=qsfp1_rxd_1, + qsfp1_rxc_1=qsfp1_rxc_1, + qsfp1_tx_clk_2=qsfp1_tx_clk_2, + qsfp1_tx_rst_2=qsfp1_tx_rst_2, + qsfp1_txd_2=qsfp1_txd_2, + qsfp1_txc_2=qsfp1_txc_2, + qsfp1_rx_clk_2=qsfp1_rx_clk_2, + qsfp1_rx_rst_2=qsfp1_rx_rst_2, + qsfp1_rxd_2=qsfp1_rxd_2, + qsfp1_rxc_2=qsfp1_rxc_2, + qsfp1_tx_clk_3=qsfp1_tx_clk_3, + qsfp1_tx_rst_3=qsfp1_tx_rst_3, + qsfp1_txd_3=qsfp1_txd_3, + qsfp1_txc_3=qsfp1_txc_3, + qsfp1_rx_clk_3=qsfp1_rx_clk_3, + qsfp1_rx_rst_3=qsfp1_rx_rst_3, + qsfp1_rxd_3=qsfp1_rxd_3, + qsfp1_rxc_3=qsfp1_rxc_3, + qsfp1_tx_clk_4=qsfp1_tx_clk_4, + qsfp1_tx_rst_4=qsfp1_tx_rst_4, + qsfp1_txd_4=qsfp1_txd_4, + qsfp1_txc_4=qsfp1_txc_4, + qsfp1_rx_clk_4=qsfp1_rx_clk_4, + qsfp1_rx_rst_4=qsfp1_rx_rst_4, + qsfp1_rxd_4=qsfp1_rxd_4, + qsfp1_rxc_4=qsfp1_rxc_4, + + uart_rxd=uart_rxd, + uart_txd=uart_txd + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 + qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 + qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 + qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 + qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 + qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 + qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 + qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 + qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 + qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 + qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 + qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 + qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 + qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 + qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 + qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp0_tx_rst_1.next = 1 + qsfp0_rx_rst_1.next = 1 + qsfp0_tx_rst_2.next = 1 + qsfp0_rx_rst_2.next = 1 + qsfp0_tx_rst_3.next = 1 + qsfp0_rx_rst_3.next = 1 + qsfp0_tx_rst_4.next = 1 + qsfp0_rx_rst_4.next = 1 + qsfp1_tx_rst_1.next = 1 + qsfp1_rx_rst_1.next = 1 + qsfp1_tx_rst_2.next = 1 + qsfp1_rx_rst_2.next = 1 + qsfp1_tx_rst_3.next = 1 + qsfp1_rx_rst_3.next = 1 + qsfp1_tx_rst_4.next = 1 + qsfp1_rx_rst_4.next = 1 + yield clk.posedge + rst.next = 0 + qsfp0_tx_rst_1.next = 0 + qsfp0_rx_rst_1.next = 0 + qsfp0_tx_rst_2.next = 0 + qsfp0_rx_rst_2.next = 0 + qsfp0_tx_rst_3.next = 0 + qsfp0_rx_rst_3.next = 0 + qsfp0_tx_rst_4.next = 0 + qsfp0_rx_rst_4.next = 0 + qsfp1_tx_rst_1.next = 0 + qsfp1_rx_rst_1.next = 0 + qsfp1_tx_rst_2.next = 0 + qsfp1_rx_rst_2.next = 0 + qsfp1_tx_rst_3.next = 0 + qsfp1_rx_rst_3.next = 0 + qsfp1_tx_rst_4.next = 0 + qsfp1_rx_rst_4.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp0_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp0_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp0_1_sink.empty(): + yield clk.posedge + + rx_frame = qsfp0_1_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp0_1_source.empty() + assert qsfp0_1_sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.v b/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..fddb81323 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016-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 + +`timescale 1ns / 1ps + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg [3:0] sw = 0; +reg qsfp0_tx_clk_1 = 0; +reg qsfp0_tx_rst_1 = 0; +reg qsfp0_rx_clk_1 = 0; +reg qsfp0_rx_rst_1 = 0; +reg [63:0] qsfp0_rxd_1 = 0; +reg [7:0] qsfp0_rxc_1 = 0; +reg qsfp0_tx_clk_2 = 0; +reg qsfp0_tx_rst_2 = 0; +reg qsfp0_rx_clk_2 = 0; +reg qsfp0_rx_rst_2 = 0; +reg [63:0] qsfp0_rxd_2 = 0; +reg [7:0] qsfp0_rxc_2 = 0; +reg qsfp0_tx_clk_3 = 0; +reg qsfp0_tx_rst_3 = 0; +reg qsfp0_rx_clk_3 = 0; +reg qsfp0_rx_rst_3 = 0; +reg [63:0] qsfp0_rxd_3 = 0; +reg [7:0] qsfp0_rxc_3 = 0; +reg qsfp0_tx_clk_4 = 0; +reg qsfp0_tx_rst_4 = 0; +reg qsfp0_rx_clk_4 = 0; +reg qsfp0_rx_rst_4 = 0; +reg [63:0] qsfp0_rxd_4 = 0; +reg [7:0] qsfp0_rxc_4 = 0; +reg qsfp1_tx_clk_1 = 0; +reg qsfp1_tx_rst_1 = 0; +reg qsfp1_rx_clk_1 = 0; +reg qsfp1_rx_rst_1 = 0; +reg [63:0] qsfp1_rxd_1 = 0; +reg [7:0] qsfp1_rxc_1 = 0; +reg qsfp1_tx_clk_2 = 0; +reg qsfp1_tx_rst_2 = 0; +reg qsfp1_rx_clk_2 = 0; +reg qsfp1_rx_rst_2 = 0; +reg [63:0] qsfp1_rxd_2 = 0; +reg [7:0] qsfp1_rxc_2 = 0; +reg qsfp1_tx_clk_3 = 0; +reg qsfp1_tx_rst_3 = 0; +reg qsfp1_rx_clk_3 = 0; +reg qsfp1_rx_rst_3 = 0; +reg [63:0] qsfp1_rxd_3 = 0; +reg [7:0] qsfp1_rxc_3 = 0; +reg qsfp1_tx_clk_4 = 0; +reg qsfp1_tx_rst_4 = 0; +reg qsfp1_rx_clk_4 = 0; +reg qsfp1_rx_rst_4 = 0; +reg [63:0] qsfp1_rxd_4 = 0; +reg [7:0] qsfp1_rxc_4 = 0; +reg uart_txd = 0; + +// Outputs +wire [2:0] led; +wire [63:0] qsfp0_txd_1; +wire [7:0] qsfp0_txc_1; +wire [63:0] qsfp0_txd_2; +wire [7:0] qsfp0_txc_2; +wire [63:0] qsfp0_txd_3; +wire [7:0] qsfp0_txc_3; +wire [63:0] qsfp0_txd_4; +wire [7:0] qsfp0_txc_4; +wire [63:0] qsfp1_txd_1; +wire [7:0] qsfp1_txc_1; +wire [63:0] qsfp1_txd_2; +wire [7:0] qsfp1_txc_2; +wire [63:0] qsfp1_txd_3; +wire [7:0] qsfp1_txc_3; +wire [63:0] qsfp1_txd_4; +wire [7:0] qsfp1_txc_4; +wire uart_rxd; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + sw, + qsfp0_tx_clk_1, + qsfp0_tx_rst_1, + qsfp0_rx_clk_1, + qsfp0_rx_rst_1, + qsfp0_rxd_1, + qsfp0_rxc_1, + qsfp0_tx_clk_2, + qsfp0_tx_rst_2, + qsfp0_rx_clk_2, + qsfp0_rx_rst_2, + qsfp0_rxd_2, + qsfp0_rxc_2, + qsfp0_tx_clk_3, + qsfp0_tx_rst_3, + qsfp0_rx_clk_3, + qsfp0_rx_rst_3, + qsfp0_rxd_3, + qsfp0_rxc_3, + qsfp0_tx_clk_4, + qsfp0_tx_rst_4, + qsfp0_rx_clk_4, + qsfp0_rx_rst_4, + qsfp0_rxd_4, + qsfp0_rxc_4, + qsfp1_tx_clk_1, + qsfp1_tx_rst_1, + qsfp1_rx_clk_1, + qsfp1_rx_rst_1, + qsfp1_rxd_1, + qsfp1_rxc_1, + qsfp1_tx_clk_2, + qsfp1_tx_rst_2, + qsfp1_rx_clk_2, + qsfp1_rx_rst_2, + qsfp1_rxd_2, + qsfp1_rxc_2, + qsfp1_tx_clk_3, + qsfp1_tx_rst_3, + qsfp1_rx_clk_3, + qsfp1_rx_rst_3, + qsfp1_rxd_3, + qsfp1_rxc_3, + qsfp1_tx_clk_4, + qsfp1_tx_rst_4, + qsfp1_rx_clk_4, + qsfp1_rx_rst_4, + qsfp1_rxd_4, + qsfp1_rxc_4, + uart_txd + ); + $to_myhdl( + led, + qsfp0_txd_1, + qsfp0_txc_1, + qsfp0_txd_2, + qsfp0_txc_2, + qsfp0_txd_3, + qsfp0_txc_3, + qsfp0_txd_4, + qsfp0_txc_4, + qsfp1_txd_1, + qsfp1_txc_1, + qsfp1_txd_2, + qsfp1_txc_2, + qsfp1_txd_3, + qsfp1_txc_3, + qsfp1_txd_4, + qsfp1_txc_4, + uart_rxd + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sw(sw), + .led(led), + .qsfp0_tx_clk_1(qsfp0_tx_clk_1), + .qsfp0_tx_rst_1(qsfp0_tx_rst_1), + .qsfp0_txd_1(qsfp0_txd_1), + .qsfp0_txc_1(qsfp0_txc_1), + .qsfp0_rx_clk_1(qsfp0_rx_clk_1), + .qsfp0_rx_rst_1(qsfp0_rx_rst_1), + .qsfp0_rxd_1(qsfp0_rxd_1), + .qsfp0_rxc_1(qsfp0_rxc_1), + .qsfp0_tx_clk_2(qsfp0_tx_clk_2), + .qsfp0_tx_rst_2(qsfp0_tx_rst_2), + .qsfp0_txd_2(qsfp0_txd_2), + .qsfp0_txc_2(qsfp0_txc_2), + .qsfp0_rx_clk_2(qsfp0_rx_clk_2), + .qsfp0_rx_rst_2(qsfp0_rx_rst_2), + .qsfp0_rxd_2(qsfp0_rxd_2), + .qsfp0_rxc_2(qsfp0_rxc_2), + .qsfp0_tx_clk_3(qsfp0_tx_clk_3), + .qsfp0_tx_rst_3(qsfp0_tx_rst_3), + .qsfp0_txd_3(qsfp0_txd_3), + .qsfp0_txc_3(qsfp0_txc_3), + .qsfp0_rx_clk_3(qsfp0_rx_clk_3), + .qsfp0_rx_rst_3(qsfp0_rx_rst_3), + .qsfp0_rxd_3(qsfp0_rxd_3), + .qsfp0_rxc_3(qsfp0_rxc_3), + .qsfp0_tx_clk_4(qsfp0_tx_clk_4), + .qsfp0_tx_rst_4(qsfp0_tx_rst_4), + .qsfp0_txd_4(qsfp0_txd_4), + .qsfp0_txc_4(qsfp0_txc_4), + .qsfp0_rx_clk_4(qsfp0_rx_clk_4), + .qsfp0_rx_rst_4(qsfp0_rx_rst_4), + .qsfp0_rxd_4(qsfp0_rxd_4), + .qsfp0_rxc_4(qsfp0_rxc_4), + .qsfp1_tx_clk_1(qsfp1_tx_clk_1), + .qsfp1_tx_rst_1(qsfp1_tx_rst_1), + .qsfp1_txd_1(qsfp1_txd_1), + .qsfp1_txc_1(qsfp1_txc_1), + .qsfp1_rx_clk_1(qsfp1_rx_clk_1), + .qsfp1_rx_rst_1(qsfp1_rx_rst_1), + .qsfp1_rxd_1(qsfp1_rxd_1), + .qsfp1_rxc_1(qsfp1_rxc_1), + .qsfp1_tx_clk_2(qsfp1_tx_clk_2), + .qsfp1_tx_rst_2(qsfp1_tx_rst_2), + .qsfp1_txd_2(qsfp1_txd_2), + .qsfp1_txc_2(qsfp1_txc_2), + .qsfp1_rx_clk_2(qsfp1_rx_clk_2), + .qsfp1_rx_rst_2(qsfp1_rx_rst_2), + .qsfp1_rxd_2(qsfp1_rxd_2), + .qsfp1_rxc_2(qsfp1_rxc_2), + .qsfp1_tx_clk_3(qsfp1_tx_clk_3), + .qsfp1_tx_rst_3(qsfp1_tx_rst_3), + .qsfp1_txd_3(qsfp1_txd_3), + .qsfp1_txc_3(qsfp1_txc_3), + .qsfp1_rx_clk_3(qsfp1_rx_clk_3), + .qsfp1_rx_rst_3(qsfp1_rx_rst_3), + .qsfp1_rxd_3(qsfp1_rxd_3), + .qsfp1_rxc_3(qsfp1_rxc_3), + .qsfp1_tx_clk_4(qsfp1_tx_clk_4), + .qsfp1_tx_rst_4(qsfp1_tx_rst_4), + .qsfp1_txd_4(qsfp1_txd_4), + .qsfp1_txc_4(qsfp1_txc_4), + .qsfp1_rx_clk_4(qsfp1_rx_clk_4), + .qsfp1_rx_rst_4(qsfp1_rx_rst_4), + .qsfp1_rxd_4(qsfp1_rxd_4), + .qsfp1_rxc_4(qsfp1_rxc_4), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) +); + +endmodule diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/udp_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/AU250/fpga_10g/tb/xgmii_ep.py b/fpga/lib/eth/example/AU250/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/fpga/lib/eth/example/AU250/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/VCU1525/fpga_10g/README.md b/fpga/lib/eth/example/VCU1525/fpga_10g/README.md index 42db4adea..c482a9c88 100644 --- a/fpga/lib/eth/example/VCU1525/fpga_10g/README.md +++ b/fpga/lib/eth/example/VCU1525/fpga_10g/README.md @@ -6,8 +6,7 @@ This example design targets the Xilinx VCU1525 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. The design also enables the gigabit Ethernet interface for -testing with a QSFP loopback adapter. +to ARP requests. FPGA: xcvu9p-fsgd2104-2L-e PHY: 10G BASE-R PHY IP core and internal GTY transceiver diff --git a/fpga/lib/eth/example/ZCU102/fpga/Makefile b/fpga/lib/eth/example/ZCU102/fpga/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/Makefile @@ -0,0 +1,25 @@ +# 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 diff --git a/fpga/lib/eth/example/ZCU102/fpga/README.md b/fpga/lib/eth/example/ZCU102/fpga/README.md new file mode 100644 index 000000000..a6d10d5fb --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet ZCU102 Example Design + +## Introduction + +This example design targets the Xilinx ZCU102 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: xczu9eg-ffvb1156-2-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the ZCU102 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. + + diff --git a/fpga/lib/eth/example/ZCU102/fpga/common/vivado.mk b/fpga/lib/eth/example/ZCU102/fpga/common/vivado.mk new file mode 100644 index 000000000..ee83637e0 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/common/vivado.mk @@ -0,0 +1,123 @@ +################################################################### +# +# 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: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean: + -rm -rf *.log *.jou *.cache *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: 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) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/eth/example/ZCU102/fpga/fpga.xdc b/fpga/lib/eth/example/ZCU102/fpga/fpga.xdc new file mode 100644 index 000000000..3c10bd43b --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/fpga.xdc @@ -0,0 +1,86 @@ +# XDC constraints for the Xilinx ZCU102 board +# part: xczu9eg-ffvb1156-2-e + +# General configuration +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] + +# System clocks +# 125 MHz +set_property -dict {LOC G21 IOSTANDARD LVDS_25} [get_ports clk_125mhz_p] +set_property -dict {LOC F21 IOSTANDARD LVDS_25} [get_ports clk_125mhz_n] +create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] + +# LEDs +set_property -dict {LOC AG14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[0]}] +set_property -dict {LOC AF13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[1]}] +set_property -dict {LOC AE13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[2]}] +set_property -dict {LOC AJ14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[3]}] +set_property -dict {LOC AJ15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[4]}] +set_property -dict {LOC AH13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[5]}] +set_property -dict {LOC AH14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[6]}] +set_property -dict {LOC AL12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {led[7]}] + +# Reset button +set_property -dict {LOC AM13 IOSTANDARD LVCMOS33} [get_ports reset] + +# Push buttons +set_property -dict {LOC AG15 IOSTANDARD LVCMOS33} [get_ports btnu] +set_property -dict {LOC AF15 IOSTANDARD LVCMOS33} [get_ports btnl] +set_property -dict {LOC AE15 IOSTANDARD LVCMOS33} [get_ports btnd] +set_property -dict {LOC AE14 IOSTANDARD LVCMOS33} [get_ports btnr] +set_property -dict {LOC AG13 IOSTANDARD LVCMOS33} [get_ports btnc] + +# DIP switches +set_property -dict {LOC AN14 IOSTANDARD LVCMOS33} [get_ports {sw[0]}] +set_property -dict {LOC AP14 IOSTANDARD LVCMOS33} [get_ports {sw[1]}] +set_property -dict {LOC AM14 IOSTANDARD LVCMOS33} [get_ports {sw[2]}] +set_property -dict {LOC AN13 IOSTANDARD LVCMOS33} [get_ports {sw[3]}] +set_property -dict {LOC AN12 IOSTANDARD LVCMOS33} [get_ports {sw[4]}] +set_property -dict {LOC AP12 IOSTANDARD LVCMOS33} [get_ports {sw[5]}] +set_property -dict {LOC AL13 IOSTANDARD LVCMOS33} [get_ports {sw[6]}] +set_property -dict {LOC AK13 IOSTANDARD LVCMOS33} [get_ports {sw[7]}] + +# UART +set_property -dict {LOC F13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports uart_txd] +set_property -dict {LOC E13 IOSTANDARD LVCMOS33} [get_ports uart_rxd] +set_property -dict {LOC D12 IOSTANDARD LVCMOS33} [get_ports uart_rts] +set_property -dict {LOC E12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports uart_cts] + +# I2C interfaces +#set_property -dict {LOC J10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports i2c0_scl] +#set_property -dict {LOC J11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports i2c0_sda] +#set_property -dict {LOC K20 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports i2c1_scl] +#set_property -dict {LOC L20 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports i2c1_sda] + +# SFP+ Interface +set_property -dict {LOC D2 } [get_ports sfp0_rx_p] ;# MGTHRXP0_230 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC D1 } [get_ports sfp0_rx_n] ;# MGTHRXN0_230 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC E4 } [get_ports sfp0_tx_p] ;# MGTHTXP0_230 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC E3 } [get_ports sfp0_tx_n] ;# MGTHTXN0_230 GTHE4_CHANNEL_X1Y12 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC C4 } [get_ports sfp1_rx_p] ;# MGTHRXP1_230 GTHE4_CHANNEL_X1Y13 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC C3 } [get_ports sfp1_rx_n] ;# MGTHRXN1_230 GTHE4_CHANNEL_X1Y13 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC D6 } [get_ports sfp1_tx_p] ;# MGTHTXP1_230 GTHE4_CHANNEL_X1Y13 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC D5 } [get_ports sfp1_tx_n] ;# MGTHTXN1_230 GTHE4_CHANNEL_X1Y13 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC B2 } [get_ports sfp2_rx_p] ;# MGTHRXP2_230 GTHE4_CHANNEL_X1Y14 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC B1 } [get_ports sfp2_rx_n] ;# MGTHRXN2_230 GTHE4_CHANNEL_X1Y14 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC B6 } [get_ports sfp2_tx_p] ;# MGTHTXP2_230 GTHE4_CHANNEL_X1Y14 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC B5 } [get_ports sfp2_tx_n] ;# MGTHTXN2_230 GTHE4_CHANNEL_X1Y14 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC A4 } [get_ports sfp3_rx_p] ;# MGTHRXP3_230 GTHE4_CHANNEL_X1Y15 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC A3 } [get_ports sfp3_rx_n] ;# MGTHRXN3_230 GTHE4_CHANNEL_X1Y15 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC A8 } [get_ports sfp3_tx_p] ;# MGTHTXP3_230 GTHE4_CHANNEL_X1Y15 / GTHE4_COMMON_X1Y3 +#set_property -dict {LOC A7 } [get_ports sfp3_tx_n] ;# MGTHTXN3_230 GTHE4_CHANNEL_X1Y15 / GTHE4_COMMON_X1Y3 +set_property -dict {LOC C8 } [get_ports sfp_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U56 SI570 via U51 SI53340 +set_property -dict {LOC C7 } [get_ports sfp_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U56 SI570 via U51 SI53340 +#set_property -dict {LOC B10 } [get_ports sfp_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U20 CKOUT2 SI5328 +#set_property -dict {LOC B9 } [get_ports sfp_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U20 CKOUT2 SI5328 +#set_property -dict {LOC R10 IOSTANDARD LVDS} [get_ports sfp_recclk_p] ;# to U20 CKIN1 SI5328 +#set_property -dict {LOC R9 IOSTANDARD LVDS} [get_ports sfp_recclk_n] ;# to U20 CKIN1 SI5328 +set_property -dict {LOC A12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp0_tx_disable_b] +set_property -dict {LOC A13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp1_tx_disable_b] +set_property -dict {LOC B13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp2_tx_disable_b] +set_property -dict {LOC C13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports sfp3_tx_disable_b] + +# 156.25 MHz MGT reference clock +create_clock -period 6.400 -name sfp_mgt_refclk_0 [get_ports sfp_mgt_refclk_0_p] + + diff --git a/fpga/lib/eth/example/ZCU102/fpga/fpga/Makefile b/fpga/lib/eth/example/ZCU102/fpga/fpga/Makefile new file mode 100644 index 000000000..7e68dca2b --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/fpga/Makefile @@ -0,0 +1,71 @@ + +# FPGA settings +FPGA_PART = xczu9eg-ffvb1156-2-e +FPGA_TOP = fpga +FPGA_ARCH = zynquplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/sync_reset.tcl + +# IP +IP_TCL_FILES = ip/gtwizard_ultrascale_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + diff --git a/fpga/lib/eth/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl b/fpga/lib/eth/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl new file mode 100644 index 000000000..66db7a0de --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl @@ -0,0 +1,21 @@ + +create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name gtwizard_ultrascale_0 + +set_property -dict [list CONFIG.preset {GTH-10GBASE-R}] [get_ips gtwizard_ultrascale_0] + +set_property -dict [list \ + CONFIG.CHANNEL_ENABLE {X1Y15 X1Y14 X1Y13 X1Y12} \ + CONFIG.TX_MASTER_CHANNEL {X1Y12} \ + CONFIG.RX_MASTER_CHANNEL {X1Y12} \ + CONFIG.TX_LINE_RATE {10.3125} \ + CONFIG.TX_REFCLK_FREQUENCY {156.25} \ + CONFIG.TX_USER_DATA_WIDTH {64} \ + CONFIG.TX_INT_DATA_WIDTH {32} \ + CONFIG.RX_LINE_RATE {10.3125} \ + CONFIG.RX_REFCLK_FREQUENCY {156.25} \ + CONFIG.RX_USER_DATA_WIDTH {64} \ + CONFIG.RX_INT_DATA_WIDTH {32} \ + CONFIG.RX_REFCLK_SOURCE {X1Y15 clk0 X1Y14 clk0 X1Y13 clk0 X1Y12 clk0} \ + CONFIG.TX_REFCLK_SOURCE {X1Y15 clk0 X1Y14 clk0 X1Y13 clk0 X1Y12 clk0} \ + CONFIG.FREERUN_FREQUENCY {125} \ +] [get_ips gtwizard_ultrascale_0] diff --git a/fpga/lib/eth/example/ZCU102/fpga/lib/eth b/fpga/lib/eth/example/ZCU102/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/rtl/debounce_switch.v b/fpga/lib/eth/example/ZCU102/fpga/rtl/debounce_switch.v new file mode 100644 index 000000000..bb631cc35 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga.v b/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga.v new file mode 100644 index 000000000..9685e7c2e --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga.v @@ -0,0 +1,684 @@ +/* + +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. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 125MHz LVDS + * Reset: Push button, active low + */ + input wire clk_125mhz_p, + input wire clk_125mhz_n, + input wire reset, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + input wire uart_rts, + output wire uart_cts, + + /* + * Ethernet: SFP+ + */ + input wire sfp0_rx_p, + input wire sfp0_rx_n, + output wire sfp0_tx_p, + output wire sfp0_tx_n, + input wire sfp1_rx_p, + input wire sfp1_rx_n, + output wire sfp1_tx_p, + output wire sfp1_tx_n, + input wire sfp2_rx_p, + input wire sfp2_rx_n, + output wire sfp2_tx_p, + output wire sfp2_tx_n, + input wire sfp3_rx_p, + input wire sfp3_rx_n, + output wire sfp3_tx_p, + output wire sfp3_tx_n, + input wire sfp_mgt_refclk_0_p, + input wire sfp_mgt_refclk_0_n, + output wire sfp0_tx_disable_b, + output wire sfp1_tx_disable_b, + output wire sfp2_tx_disable_b, + output wire sfp3_tx_disable_b +); + +// Clock and reset + +wire clk_125mhz_ibufg; +wire clk_125mhz_bufg; + +// 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 = reset; +wire mmcm_locked; +wire mmcm_clkfb; + +IBUFGDS #( + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE") +) +clk_125mhz_ibufg_inst ( + .O (clk_125mhz_ibufg), + .I (clk_125mhz_p), + .IB (clk_125mhz_n) +); + +BUFG +clk_125mhz_bufg_in_inst ( + .I(clk_125mhz_ibufg), + .O(clk_125mhz_bufg) +); + +// MMCM instance +// 125 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 8, D = 1 sets Fvco = 1000 MHz (in range) +// Divide by 8 to get output frequency of 125 MHz +MMCME4_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(8), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(8.0), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(clk_125mhz_bufg), + .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 btnu_int; +wire btnl_int; +wire btnd_int; +wire btnr_int; +wire btnc_int; +wire [7:0] sw_int; + +debounce_switch #( + .WIDTH(9), + .N(8), + .RATE(156000) +) +debounce_switch_inst ( + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + .in({btnu, + btnl, + btnd, + btnr, + btnc, + sw}), + .out({btnu_int, + btnl_int, + btnd_int, + btnr_int, + btnc_int, + sw_int}) +); + +wire uart_rxd_int; +wire uart_rts_int; + +sync_signal #( + .WIDTH(2), + .N(2) +) +sync_signal_inst ( + .clk(clk_156mhz_int), + .in({uart_rxd, uart_rts}), + .out({uart_rxd_int, uart_rts_int}) +); + +// XGMII 10G PHY +assign sfp0_tx_disable_b = 1'b1; +assign sfp1_tx_disable_b = 1'b1; +assign sfp2_tx_disable_b = 1'b1; +assign sfp3_tx_disable_b = 1'b1; + +wire sfp0_tx_clk_int; +wire sfp0_tx_rst_int; +wire [63:0] sfp0_txd_int; +wire [7:0] sfp0_txc_int; +wire sfp0_rx_clk_int; +wire sfp0_rx_rst_int; +wire [63:0] sfp0_rxd_int; +wire [7:0] sfp0_rxc_int; + +wire sfp1_tx_clk_int; +wire sfp1_tx_rst_int; +wire [63:0] sfp1_txd_int; +wire [7:0] sfp1_txc_int; +wire sfp1_rx_clk_int; +wire sfp1_rx_rst_int; +wire [63:0] sfp1_rxd_int; +wire [7:0] sfp1_rxc_int; + +wire sfp2_tx_clk_int; +wire sfp2_tx_rst_int; +wire [63:0] sfp2_txd_int; +wire [7:0] sfp2_txc_int; +wire sfp2_rx_clk_int; +wire sfp2_rx_rst_int; +wire [63:0] sfp2_rxd_int; +wire [7:0] sfp2_rxc_int; + +wire sfp3_tx_clk_int; +wire sfp3_tx_rst_int; +wire [63:0] sfp3_txd_int; +wire [7:0] sfp3_txc_int; +wire sfp3_rx_clk_int; +wire sfp3_rx_rst_int; +wire [63:0] sfp3_rxd_int; +wire [7:0] sfp3_rxc_int; + +wire sfp0_rx_block_lock; +wire sfp1_rx_block_lock; +wire sfp2_rx_block_lock; +wire sfp3_rx_block_lock; + +wire sfp_mgt_refclk; + +wire [3:0] gt_txclkout; +wire gt_txusrclk; +wire gt_txusrclk2; + +wire [3:0] gt_rxclkout; +wire [3:0] gt_rxusrclk; +wire [3:0] gt_rxusrclk2; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [3:0] gt_txprgdivresetdone; +wire [3:0] gt_txpmaresetdone; +wire [3:0] gt_rxprgdivresetdone; +wire [3:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [3:0] gt_userclk_rx_active = 1'b0; + +IBUFDS_GTE4 ibufds_gte4_sfp_mgt_refclk_inst ( + .I (sfp_mgt_refclk_0_p), + .IB (sfp_mgt_refclk_0_n), + .CEB (1'b0), + .O (sfp_mgt_refclk), + .ODIV2 () +); + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +BUFG_GT bufg_gt_tx_usrclk2_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd1), + .I (gt_txclkout[0]), + .O (gt_txusrclk2) +); + +assign clk_156mhz_int = gt_txusrclk2; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +genvar n; + +generate + +for (n = 0 ; n < 4; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_0_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + BUFG_GT bufg_gt_rx_usrclk2_0_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd1), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk2[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .out(rst_156mhz_int) +); + +wire [5:0] sfp0_gt_txheader; +wire [63:0] sfp0_gt_txdata; +wire sfp0_gt_rxgearboxslip; +wire [5:0] sfp0_gt_rxheader; +wire [1:0] sfp0_gt_rxheadervalid; +wire [63:0] sfp0_gt_rxdata; +wire [1:0] sfp0_gt_rxdatavalid; + +wire [5:0] sfp1_gt_txheader; +wire [63:0] sfp1_gt_txdata; +wire sfp1_gt_rxgearboxslip; +wire [5:0] sfp1_gt_rxheader; +wire [1:0] sfp1_gt_rxheadervalid; +wire [63:0] sfp1_gt_rxdata; +wire [1:0] sfp1_gt_rxdatavalid; + +wire [5:0] sfp2_gt_txheader; +wire [63:0] sfp2_gt_txdata; +wire sfp2_gt_rxgearboxslip; +wire [5:0] sfp2_gt_rxheader; +wire [1:0] sfp2_gt_rxheadervalid; +wire [63:0] sfp2_gt_rxdata; +wire [1:0] sfp2_gt_rxdatavalid; + +wire [5:0] sfp3_gt_txheader; +wire [63:0] sfp3_gt_txdata; +wire sfp3_gt_rxgearboxslip; +wire [5:0] sfp3_gt_rxheader; +wire [1:0] sfp3_gt_rxheadervalid; +wire [63:0] sfp3_gt_rxdata; +wire [1:0] sfp3_gt_rxdatavalid; + +gtwizard_ultrascale_0 +sfp_gth_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in(sfp_mgt_refclk), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gthrxn_in({sfp3_rx_n, sfp2_rx_n, sfp1_rx_n, sfp0_rx_n}), + .gthrxp_in({sfp3_rx_p, sfp2_rx_p, sfp1_rx_p, sfp0_rx_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk2), + + .gtwiz_userdata_tx_in({sfp3_gt_txdata, sfp2_gt_txdata, sfp1_gt_txdata, sfp0_gt_txdata}), + .txheader_in({sfp3_gt_txheader, sfp2_gt_txheader, sfp1_gt_txheader, sfp0_gt_txheader}), + .txsequence_in({4{7'b0}}), + + .txusrclk_in({4{gt_txusrclk}}), + .txusrclk2_in({4{gt_txusrclk2}}), + + .gtpowergood_out(), + + .gthtxn_out({sfp3_tx_n, sfp2_tx_n, sfp1_tx_n, sfp0_tx_n}), + .gthtxp_out({sfp3_tx_p, sfp2_tx_p, sfp1_tx_p, sfp0_tx_p}), + + .rxgearboxslip_in({sfp3_gt_rxgearboxslip, sfp2_gt_rxgearboxslip, sfp1_gt_rxgearboxslip, sfp0_gt_rxgearboxslip}), + .gtwiz_userdata_rx_out({sfp3_gt_rxdata, sfp2_gt_rxdata, sfp1_gt_rxdata, sfp0_gt_rxdata}), + .rxdatavalid_out({sfp3_gt_rxdatavalid, sfp2_gt_rxdatavalid, sfp1_gt_rxdatavalid, sfp0_gt_rxdatavalid}), + .rxheader_out({sfp3_gt_rxheader, sfp2_gt_rxheader, sfp1_gt_rxheader, sfp0_gt_rxheader}), + .rxheadervalid_out({sfp3_gt_rxheadervalid, sfp2_gt_rxheadervalid, sfp1_gt_rxheadervalid, sfp0_gt_rxheadervalid}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign sfp0_tx_clk_int = clk_156mhz_int; +assign sfp0_tx_rst_int = rst_156mhz_int; + +assign sfp0_rx_clk_int = gt_rxusrclk2[0]; + +sync_reset #( + .N(4) +) +sfp0_rx_rst_reset_sync_inst ( + .clk(sfp0_rx_clk_int), + .rst(~gt_reset_rx_done), + .out(sfp0_rx_rst_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp0_phy_inst ( + .tx_clk(sfp0_tx_clk_int), + .tx_rst(sfp0_tx_rst_int), + .rx_clk(sfp0_rx_clk_int), + .rx_rst(sfp0_rx_rst_int), + .xgmii_txd(sfp0_txd_int), + .xgmii_txc(sfp0_txc_int), + .xgmii_rxd(sfp0_rxd_int), + .xgmii_rxc(sfp0_rxc_int), + .serdes_tx_data(sfp0_gt_txdata), + .serdes_tx_hdr(sfp0_gt_txheader), + .serdes_rx_data(sfp0_gt_rxdata), + .serdes_rx_hdr(sfp0_gt_rxheader), + .serdes_rx_bitslip(sfp0_gt_rxgearboxslip), + .rx_block_lock(sfp0_rx_block_lock), + .rx_high_ber() +); + +assign sfp1_tx_clk_int = clk_156mhz_int; +assign sfp1_tx_rst_int = rst_156mhz_int; + +assign sfp1_rx_clk_int = gt_rxusrclk2[1]; + +sync_reset #( + .N(4) +) +sfp1_rx_rst_reset_sync_inst ( + .clk(sfp1_rx_clk_int), + .rst(~gt_reset_rx_done), + .out(sfp1_rx_rst_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp1_phy_inst ( + .tx_clk(sfp1_tx_clk_int), + .tx_rst(sfp1_tx_rst_int), + .rx_clk(sfp1_rx_clk_int), + .rx_rst(sfp1_rx_rst_int), + .xgmii_txd(sfp1_txd_int), + .xgmii_txc(sfp1_txc_int), + .xgmii_rxd(sfp1_rxd_int), + .xgmii_rxc(sfp1_rxc_int), + .serdes_tx_data(sfp1_gt_txdata), + .serdes_tx_hdr(sfp1_gt_txheader), + .serdes_rx_data(sfp1_gt_rxdata), + .serdes_rx_hdr(sfp1_gt_rxheader), + .serdes_rx_bitslip(sfp1_gt_rxgearboxslip), + .rx_block_lock(sfp1_rx_block_lock), + .rx_high_ber() +); + +assign sfp2_tx_clk_int = clk_156mhz_int; +assign sfp2_tx_rst_int = rst_156mhz_int; + +assign sfp2_rx_clk_int = gt_rxusrclk2[2]; + +sync_reset #( + .N(4) +) +sfp2_rx_rst_reset_sync_inst ( + .clk(sfp2_rx_clk_int), + .rst(~gt_reset_rx_done), + .out(sfp2_rx_rst_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp2_phy_inst ( + .tx_clk(sfp2_tx_clk_int), + .tx_rst(sfp2_tx_rst_int), + .rx_clk(sfp2_rx_clk_int), + .rx_rst(sfp2_rx_rst_int), + .xgmii_txd(sfp2_txd_int), + .xgmii_txc(sfp2_txc_int), + .xgmii_rxd(sfp2_rxd_int), + .xgmii_rxc(sfp2_rxc_int), + .serdes_tx_data(sfp2_gt_txdata), + .serdes_tx_hdr(sfp2_gt_txheader), + .serdes_rx_data(sfp2_gt_rxdata), + .serdes_rx_hdr(sfp2_gt_rxheader), + .serdes_rx_bitslip(sfp2_gt_rxgearboxslip), + .rx_block_lock(sfp2_rx_block_lock), + .rx_high_ber() +); + +assign sfp3_tx_clk_int = clk_156mhz_int; +assign sfp3_tx_rst_int = rst_156mhz_int; + +assign sfp3_rx_clk_int = gt_rxusrclk2[3]; + +sync_reset #( + .N(4) +) +sfp3_rx_rst_reset_sync_inst ( + .clk(sfp3_rx_clk_int), + .rst(~gt_reset_rx_done), + .out(sfp3_rx_rst_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +sfp3_phy_inst ( + .tx_clk(sfp3_tx_clk_int), + .tx_rst(sfp3_tx_rst_int), + .rx_clk(sfp3_rx_clk_int), + .rx_rst(sfp3_rx_rst_int), + .xgmii_txd(sfp3_txd_int), + .xgmii_txc(sfp3_txc_int), + .xgmii_rxd(sfp3_rxd_int), + .xgmii_rxc(sfp3_rxc_int), + .serdes_tx_data(sfp3_gt_txdata), + .serdes_tx_hdr(sfp3_gt_txheader), + .serdes_rx_data(sfp3_gt_rxdata), + .serdes_rx_hdr(sfp3_gt_rxheader), + .serdes_rx_bitslip(sfp3_gt_rxgearboxslip), + .rx_block_lock(sfp3_rx_block_lock), + .rx_high_ber() +); + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .btnu(btnu_int), + .btnl(btnl_int), + .btnd(btnd_int), + .btnr(btnr_int), + .btnc(btnc_int), + .sw(sw_int), + .led(led), + /* + * UART: 115200 bps, 8N1 + */ + .uart_rxd(uart_rxd_int), + .uart_txd(uart_txd), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts), + /* + * Ethernet: SFP+ + */ + .sfp0_tx_clk(sfp0_tx_clk_int), + .sfp0_tx_rst(sfp0_tx_rst_int), + .sfp0_txd(sfp0_txd_int), + .sfp0_txc(sfp0_txc_int), + .sfp0_rx_clk(sfp0_rx_clk_int), + .sfp0_rx_rst(sfp0_rx_rst_int), + .sfp0_rxd(sfp0_rxd_int), + .sfp0_rxc(sfp0_rxc_int), + .sfp1_tx_clk(sfp1_tx_clk_int), + .sfp1_tx_rst(sfp1_tx_rst_int), + .sfp1_txd(sfp1_txd_int), + .sfp1_txc(sfp1_txc_int), + .sfp1_rx_clk(sfp1_rx_clk_int), + .sfp1_rx_rst(sfp1_rx_rst_int), + .sfp1_rxd(sfp1_rxd_int), + .sfp1_rxc(sfp1_rxc_int), + .sfp2_tx_clk(sfp2_tx_clk_int), + .sfp2_tx_rst(sfp2_tx_rst_int), + .sfp2_txd(sfp2_txd_int), + .sfp2_txc(sfp2_txc_int), + .sfp2_rx_clk(sfp2_rx_clk_int), + .sfp2_rx_rst(sfp2_rx_rst_int), + .sfp2_rxd(sfp2_rxd_int), + .sfp2_rxc(sfp2_rxc_int), + .sfp3_tx_clk(sfp3_tx_clk_int), + .sfp3_tx_rst(sfp3_tx_rst_int), + .sfp3_txd(sfp3_txd_int), + .sfp3_txc(sfp3_txc_int), + .sfp3_rx_clk(sfp3_rx_clk_int), + .sfp3_rx_rst(sfp3_rx_rst_int), + .sfp3_rxd(sfp3_rxd_int), + .sfp3_rxc(sfp3_rxc_int) +); + +endmodule diff --git a/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga_core.v b/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..b55cd06d9 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/rtl/fpga_core.v @@ -0,0 +1,626 @@ +/* + +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. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * FPGA core logic + */ +module fpga_core +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire btnu, + input wire btnl, + input wire btnd, + input wire btnr, + input wire btnc, + input wire [7:0] sw, + output wire [7:0] led, + + /* + * UART: 115200 bps, 8N1 + */ + input wire uart_rxd, + output wire uart_txd, + input wire uart_rts, + output wire uart_cts, + + /* + * Ethernet: SFP+ + */ + input wire sfp0_tx_clk, + input wire sfp0_tx_rst, + output wire [63:0] sfp0_txd, + output wire [7:0] sfp0_txc, + input wire sfp0_rx_clk, + input wire sfp0_rx_rst, + input wire [63:0] sfp0_rxd, + input wire [7:0] sfp0_rxc, + input wire sfp1_tx_clk, + input wire sfp1_tx_rst, + output wire [63:0] sfp1_txd, + output wire [7:0] sfp1_txc, + input wire sfp1_rx_clk, + input wire sfp1_rx_rst, + input wire [63:0] sfp1_rxd, + input wire [7:0] sfp1_rxc, + input wire sfp2_tx_clk, + input wire sfp2_tx_rst, + output wire [63:0] sfp2_txd, + output wire [7:0] sfp2_txc, + input wire sfp2_rx_clk, + input wire sfp2_rx_rst, + input wire [63:0] sfp2_rxd, + input wire [7:0] sfp2_rxc, + input wire sfp3_tx_clk, + input wire sfp3_tx_rst, + output wire [63:0] sfp3_txd, + output wire [7:0] sfp3_txc, + input wire sfp3_rx_clk, + input wire sfp3_rx_rst, + input wire [63:0] sfp3_rxd, + input wire [7:0] sfp3_rxc +); + +// 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 led = led_reg; + +assign sfp1_txd = 64'h0707070707070707; +assign sfp1_txc = 8'hff; +assign sfp2_txd = 64'h0707070707070707; +assign sfp2_txc = 8'hff; +assign sfp3_txd = 64'h0707070707070707; +assign sfp3_txc = 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(sfp0_rx_clk), + .rx_rst(sfp0_rx_rst), + .tx_clk(sfp0_tx_clk), + .tx_rst(sfp0_tx_rst), + .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(sfp0_rxd), + .xgmii_rxc(sfp0_rxc), + .xgmii_txd(sfp0_txd), + .xgmii_txc(sfp0_txc), + + .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 diff --git a/fpga/lib/eth/example/ZCU102/fpga/rtl/sync_signal.v b/fpga/lib/eth/example/ZCU102/fpga/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/arp_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/axis_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/eth_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/gmii_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/gmii_ep.py new file mode 120000 index 000000000..754166f2f --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/gmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/gmii_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/ip_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.py b/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.py new file mode 100755 index 000000000..76cbc0c0e --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python +""" + +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. + +""" + +from myhdl import * +import os + +import eth_ep +import arp_ep +import udp_ep +import gmii_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_1g.v") +srcs.append("../lib/eth/rtl/axis_gmii_rx.v") +srcs.append("../lib/eth/rtl/axis_gmii_tx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_adapter.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_switch.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_register.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + btnu = Signal(bool(0)) + btnl = Signal(bool(0)) + btnd = Signal(bool(0)) + btnr = Signal(bool(0)) + btnc = Signal(bool(0)) + sw = Signal(intbv(0)[8:]) + sfp0_tx_clk = Signal(bool(0)) + sfp0_tx_rst = Signal(bool(0)) + sfp0_rx_clk = Signal(bool(0)) + sfp0_rx_rst = Signal(bool(0)) + sfp0_rxd = Signal(intbv(0)[64:]) + sfp0_rxc = Signal(intbv(0)[8:]) + sfp1_tx_clk = Signal(bool(0)) + sfp1_tx_rst = Signal(bool(0)) + sfp1_rx_clk = Signal(bool(0)) + sfp1_rx_rst = Signal(bool(0)) + sfp1_rxd = Signal(intbv(0)[64:]) + sfp1_rxc = Signal(intbv(0)[8:]) + sfp2_tx_clk = Signal(bool(0)) + sfp2_tx_rst = Signal(bool(0)) + sfp2_rx_clk = Signal(bool(0)) + sfp2_rx_rst = Signal(bool(0)) + sfp2_rxd = Signal(intbv(0)[64:]) + sfp2_rxc = Signal(intbv(0)[8:]) + sfp3_tx_clk = Signal(bool(0)) + sfp3_tx_rst = Signal(bool(0)) + sfp3_rx_clk = Signal(bool(0)) + sfp3_rx_rst = Signal(bool(0)) + sfp3_rxd = Signal(intbv(0)[64:]) + sfp3_rxc = Signal(intbv(0)[8:]) + uart_rxd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + + # Outputs + led = Signal(intbv(0)[8:]) + sfp0_txd = Signal(intbv(0)[64:]) + sfp0_txc = Signal(intbv(0)[8:]) + sfp1_txd = Signal(intbv(0)[64:]) + sfp1_txc = Signal(intbv(0)[8:]) + sfp2_txd = Signal(intbv(0)[64:]) + sfp2_txc = Signal(intbv(0)[8:]) + sfp3_txd = Signal(intbv(0)[64:]) + sfp3_txc = Signal(intbv(0)[8:]) + uart_txd = Signal(bool(0)) + uart_cts = Signal(bool(0)) + + # sources and sinks + sfp0_source = xgmii_ep.XGMIISource() + sfp0_source_logic = sfp0_source.create_logic(sfp0_rx_clk, sfp0_rx_rst, txd=sfp0_rxd, txc=sfp0_rxc, name='sfp0_source') + + sfp0_sink = xgmii_ep.XGMIISink() + sfp0_sink_logic = sfp0_sink.create_logic(sfp0_tx_clk, sfp0_tx_rst, rxd=sfp0_txd, rxc=sfp0_txc, name='sfp0_sink') + + sfp1_source = xgmii_ep.XGMIISource() + sfp1_source_logic = sfp1_source.create_logic(sfp1_rx_clk, sfp1_rx_rst, txd=sfp1_rxd, txc=sfp1_rxc, name='sfp1_source') + + sfp1_sink = xgmii_ep.XGMIISink() + sfp1_sink_logic = sfp1_sink.create_logic(sfp1_tx_clk, sfp1_tx_rst, rxd=sfp1_txd, rxc=sfp1_txc, name='sfp1_sink') + + sfp2_source = xgmii_ep.XGMIISource() + sfp2_source_logic = sfp2_source.create_logic(sfp2_rx_clk, sfp2_rx_rst, txd=sfp2_rxd, txc=sfp2_rxc, name='sfp2_source') + + sfp2_sink = xgmii_ep.XGMIISink() + sfp2_sink_logic = sfp2_sink.create_logic(sfp2_tx_clk, sfp2_tx_rst, rxd=sfp2_txd, rxc=sfp2_txc, name='sfp2_sink') + + sfp3_source = xgmii_ep.XGMIISource() + sfp3_source_logic = sfp3_source.create_logic(sfp3_rx_clk, sfp3_rx_rst, txd=sfp3_rxd, txc=sfp3_rxc, name='sfp3_source') + + sfp3_sink = xgmii_ep.XGMIISink() + sfp3_sink_logic = sfp3_sink.create_logic(sfp3_tx_clk, sfp3_tx_rst, rxd=sfp3_txd, rxc=sfp3_txc, name='sfp3_sink') + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + btnu=btnu, + btnl=btnl, + btnd=btnd, + btnr=btnr, + btnc=btnc, + sw=sw, + led=led, + + sfp0_tx_clk=sfp0_tx_clk, + sfp0_tx_rst=sfp0_tx_rst, + sfp0_txd=sfp0_txd, + sfp0_txc=sfp0_txc, + sfp0_rx_clk=sfp0_rx_clk, + sfp0_rx_rst=sfp0_rx_rst, + sfp0_rxd=sfp0_rxd, + sfp0_rxc=sfp0_rxc, + sfp1_tx_clk=sfp1_tx_clk, + sfp1_tx_rst=sfp1_tx_rst, + sfp1_txd=sfp1_txd, + sfp1_txc=sfp1_txc, + sfp1_rx_clk=sfp1_rx_clk, + sfp1_rx_rst=sfp1_rx_rst, + sfp1_rxd=sfp1_rxd, + sfp1_rxc=sfp1_rxc, + sfp2_tx_clk=sfp2_tx_clk, + sfp2_tx_rst=sfp2_tx_rst, + sfp2_txd=sfp2_txd, + sfp2_txc=sfp2_txc, + sfp2_rx_clk=sfp2_rx_clk, + sfp2_rx_rst=sfp2_rx_rst, + sfp2_rxd=sfp2_rxd, + sfp2_rxc=sfp2_rxc, + sfp3_tx_clk=sfp3_tx_clk, + sfp3_tx_rst=sfp3_tx_rst, + sfp3_txd=sfp3_txd, + sfp3_txc=sfp3_txc, + sfp3_rx_clk=sfp3_rx_clk, + sfp3_rx_rst=sfp3_rx_rst, + sfp3_rxd=sfp3_rxd, + sfp3_rxc=sfp3_rxc, + + uart_rxd=uart_rxd, + uart_txd=uart_txd, + uart_rts=uart_rts, + uart_cts=uart_cts + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + sfp0_tx_clk.next = not sfp0_tx_clk + sfp0_rx_clk.next = not sfp0_rx_clk + sfp1_tx_clk.next = not sfp1_tx_clk + sfp1_rx_clk.next = not sfp1_rx_clk + sfp2_tx_clk.next = not sfp2_tx_clk + sfp2_rx_clk.next = not sfp2_rx_clk + sfp3_tx_clk.next = not sfp3_tx_clk + sfp3_rx_clk.next = not sfp3_rx_clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + sfp0_tx_rst.next = 1 + sfp0_rx_rst.next = 1 + sfp1_tx_rst.next = 1 + sfp1_rx_rst.next = 1 + sfp2_tx_rst.next = 1 + sfp2_rx_rst.next = 1 + sfp3_tx_rst.next = 1 + sfp3_rx_rst.next = 1 + yield clk.posedge + rst.next = 0 + sfp0_tx_rst.next = 0 + sfp0_rx_rst.next = 0 + sfp1_tx_rst.next = 0 + sfp1_rx_rst.next = 0 + sfp2_tx_rst.next = 0 + sfp2_rx_rst.next = 0 + sfp3_tx_rst.next = 0 + sfp3_rx_rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + sfp0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while sfp0_sink.empty(): + yield clk.posedge + + rx_frame = sfp0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + sfp0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while sfp0_sink.empty(): + yield clk.posedge + + rx_frame = sfp0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert sfp0_source.empty() + assert sfp0_sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.v b/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.v new file mode 100644 index 000000000..257d80c32 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/test_fpga_core.v @@ -0,0 +1,194 @@ +/* + +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. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg btnu = 0; +reg btnl = 0; +reg btnd = 0; +reg btnr = 0; +reg btnc = 0; +reg [7:0] sw = 0; +reg sfp0_tx_clk = 0; +reg sfp0_tx_rst = 0; +reg sfp0_rx_clk = 0; +reg sfp0_rx_rst = 0; +reg [63:0] sfp0_rxd = 0; +reg [7:0] sfp0_rxc = 0; +reg sfp1_tx_clk = 0; +reg sfp1_tx_rst = 0; +reg sfp1_rx_clk = 0; +reg sfp1_rx_rst = 0; +reg [63:0] sfp1_rxd = 0; +reg [7:0] sfp1_rxc = 0; +reg sfp2_tx_clk = 0; +reg sfp2_tx_rst = 0; +reg sfp2_rx_clk = 0; +reg sfp2_rx_rst = 0; +reg [63:0] sfp2_rxd = 0; +reg [7:0] sfp2_rxc = 0; +reg sfp3_tx_clk = 0; +reg sfp3_tx_rst = 0; +reg sfp3_rx_clk = 0; +reg sfp3_rx_rst = 0; +reg [63:0] sfp3_rxd = 0; +reg [7:0] sfp3_rxc = 0; +reg uart_rxd = 0; +reg uart_rts = 0; + +// Outputs +wire [7:0] led; +wire [63:0] sfp0_txd; +wire [7:0] sfp0_txc; +wire [63:0] sfp1_txd; +wire [7:0] sfp1_txc; +wire [63:0] sfp_2_txd; +wire [7:0] sfp_2_txc; +wire [63:0] sfp_3_txd; +wire [7:0] sfp_3_txc; +wire uart_txd; +wire uart_cts; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + btnu, + btnl, + btnd, + btnr, + btnc, + sw, + sfp0_tx_clk, + sfp0_tx_rst, + sfp0_rx_clk, + sfp0_rx_rst, + sfp0_rxd, + sfp0_rxc, + sfp1_tx_clk, + sfp1_tx_rst, + sfp1_rx_clk, + sfp1_rx_rst, + sfp1_rxd, + sfp1_rxc, + sfp2_tx_clk, + sfp2_tx_rst, + sfp2_rx_clk, + sfp2_rx_rst, + sfp2_rxd, + sfp2_rxc, + sfp3_tx_clk, + sfp3_tx_rst, + sfp3_rx_clk, + sfp3_rx_rst, + sfp3_rxd, + sfp3_rxc, + uart_rxd, + uart_rts + ); + $to_myhdl( + led, + sfp0_txd, + sfp0_txc, + sfp1_txd, + sfp1_txc, + sfp2_txd, + sfp2_txc, + sfp3_txd, + sfp3_txc, + uart_txd, + uart_cts + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .btnu(btnu), + .btnl(btnl), + .btnd(btnd), + .btnr(btnr), + .btnc(btnc), + .sw(sw), + .led(led), + .sfp0_tx_clk(sfp0_tx_clk), + .sfp0_tx_rst(sfp0_tx_rst), + .sfp0_txd(sfp0_txd), + .sfp0_txc(sfp0_txc), + .sfp0_rx_clk(sfp0_rx_clk), + .sfp0_rx_rst(sfp0_rx_rst), + .sfp0_rxd(sfp0_rxd), + .sfp0_rxc(sfp0_rxc), + .sfp1_tx_clk(sfp1_tx_clk), + .sfp1_tx_rst(sfp1_tx_rst), + .sfp1_txd(sfp1_txd), + .sfp1_txc(sfp1_txc), + .sfp1_rx_clk(sfp1_rx_clk), + .sfp1_rx_rst(sfp1_rx_rst), + .sfp1_rxd(sfp1_rxd), + .sfp1_rxc(sfp1_rxc), + .sfp2_tx_clk(sfp2_tx_clk), + .sfp2_tx_rst(sfp2_tx_rst), + .sfp2_txd(sfp2_txd), + .sfp2_txc(sfp2_txc), + .sfp2_rx_clk(sfp2_rx_clk), + .sfp2_rx_rst(sfp2_rx_rst), + .sfp2_rxd(sfp2_rxd), + .sfp2_rxc(sfp2_rxc), + .sfp3_tx_clk(sfp3_tx_clk), + .sfp3_tx_rst(sfp3_tx_rst), + .sfp3_txd(sfp3_txd), + .sfp3_txc(sfp3_txc), + .sfp3_rx_clk(sfp3_rx_clk), + .sfp3_rx_rst(sfp3_rx_rst), + .sfp3_rxd(sfp3_rxd), + .sfp3_rxc(sfp3_rxc), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd), + .uart_rts(uart_rts), + .uart_cts(uart_cts) +); + +endmodule diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/udp_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/ZCU102/fpga/tb/xgmii_ep.py b/fpga/lib/eth/example/ZCU102/fpga/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/fpga/lib/eth/example/ZCU102/fpga/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/Makefile b/fpga/lib/eth/example/fb2CG/fpga_10g/Makefile new file mode 100644 index 000000000..f504bd06f --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/Makefile @@ -0,0 +1,25 @@ +# 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 diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/README.md b/fpga/lib/eth/example/fb2CG/fpga_10g/README.md new file mode 100644 index 000000000..5f41827ff --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/README.md @@ -0,0 +1,24 @@ +# Verilog Ethernet fb2CG@KU15P Example Design + +## Introduction + +This example design targets the Silicom fb2CG@KU15P 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: xcku15p-ffve1760-2-e +PHY: 10G BASE-R PHY IP core and internal GTY transceiver + +## How to build + +Run make to build. Ensure that the Xilinx Vivado toolchain components are +in PATH. + +## How to test + +Run make program to program the fb2CG@KU15P 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. + diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/common/vivado.mk b/fpga/lib/eth/example/fb2CG/fpga_10g/common/vivado.mk new file mode 100644 index 000000000..ee83637e0 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/common/vivado.mk @@ -0,0 +1,123 @@ +################################################################### +# +# 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: clean fpga + +# prevent make from deleting intermediate files and reports +.PRECIOUS: %.xpr %.bit %.mcs %.prm +.SECONDARY: + +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) +IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES)) + +ifdef XDC_FILES + XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) +else + XDC_FILES_REL = $(FPGA_TOP).xdc +endif + +################################################################### +# Main Targets +# +# all: build everything +# clean: remove output files and project files +################################################################### + +all: fpga + +fpga: $(FPGA_TOP).bit + +vivado: $(FPGA_TOP).xpr + vivado $(FPGA_TOP).xpr + +tmpclean: + -rm -rf *.log *.jou *.cache *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v + -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl + +clean: tmpclean + -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + +distclean: clean + -rm -rf rev + +################################################################### +# Target implementations +################################################################### + +# Vivado project file +%.xpr: 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) $*" > create_project.tcl + echo "add_files -fileset sources_1 defines.v" >> create_project.tcl + for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done + for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done + echo "exit" >> create_project.tcl + vivado -nojournal -nolog -mode batch -source create_project.tcl + +# synthesis run +%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $*.xpr" > run_synth.tcl + echo "reset_run synth_1" >> run_synth.tcl + echo "launch_runs synth_1" >> run_synth.tcl + echo "wait_on_run synth_1" >> run_synth.tcl + echo "exit" >> run_synth.tcl + vivado -nojournal -nolog -mode batch -source run_synth.tcl + +# implementation run +%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp + echo "open_project $*.xpr" > run_impl.tcl + echo "reset_run impl_1" >> run_impl.tcl + echo "launch_runs impl_1" >> run_impl.tcl + echo "wait_on_run impl_1" >> run_impl.tcl + echo "exit" >> run_impl.tcl + vivado -nojournal -nolog -mode batch -source run_impl.tcl + +# bit file +%.bit: %.runs/impl_1/%_routed.dcp + echo "open_project $*.xpr" > generate_bit.tcl + echo "open_run impl_1" >> generate_bit.tcl + echo "write_bitstream -force $*.bit" >> generate_bit.tcl + echo "exit" >> generate_bit.tcl + vivado -nojournal -nolog -mode batch -source generate_bit.tcl + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do COUNT=$$((COUNT+1)); done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/fpga.xdc b/fpga/lib/eth/example/fb2CG/fpga_10g/fpga.xdc new file mode 100644 index 000000000..94440c0ec --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/fpga.xdc @@ -0,0 +1,227 @@ +# XDC constraints for the fb2CG@KU15P +# part: xcku15p-ffve1760-2-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS true [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN disable [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design] +set_property CONFIG_MODE SPIx4 [current_design] +set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] + +# System clocks +# init clock 50 MHz +set_property -dict {LOC E7 IOSTANDARD LVCMOS18} [get_ports init_clk] +create_clock -period 20.000 -name init_clk [get_ports init_clk] + +# E7 is not a global clock capable input, so need to set CLOCK_DEDICATED_ROUTE to satisfy DRC +#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets init_clk_ibuf_inst/O] +set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets init_clk_bufg] + +# DDR4 refclk1 +#set_property -dict {LOC AT32 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk1_p] +#set_property -dict {LOC AU32 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk1_n] +#create_clock -period 3.750 -name clk_ddr4_refclk1 [get_ports clk_ddr4_refclk1_p] + +# DDR4 refclk2 +#set_property -dict {LOC G29 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk2_p] +#set_property -dict {LOC G28 IOSTANDARD DIFF_SSTL12} [get_ports clk_ddr4_refclk2_n] +#create_clock -period 3.750 -name clk_ddr4_refclk2 [get_ports clk_ddr4_refclk1_p] + +# LEDs +set_property -dict {LOC C4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_d] +set_property -dict {LOC B3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_ld] +set_property -dict {LOC G3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports led_sreg_clk] +set_property -dict {LOC C5 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {led_bmc[0]}] +set_property -dict {LOC C6 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {led_bmc[1]}] +set_property -dict {LOC D3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports {led_exp[0]}] +set_property -dict {LOC D4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports {led_exp[1]}] + +# GPIO +#set_property -dict {LOC B4 IOSTANDARD LVCMOS33} [get_ports pps_in] ;# from SMA J6 via Q1 (inverted) +#set_property -dict {LOC A4 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 4} [get_ports pps_out] ;# to SMA J6 via U4 and U5, and u.FL J7 (PPS OUT) via U3 +#set_property -dict {LOC A3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports pps_out_en] ; # to U5 IN (connects pps_out to SMA J6 when high) +#set_property -dict {LOC H2 IOSTANDARD LVCMOS33} [get_ports misc_ucoax] ; from u.FL J5 (PPS IN) + +# BMC interface +#set_property -dict {LOC D7 IOSTANDARD LVCMOS18} [get_ports bmc_miso] +#set_property -dict {LOC J4 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_nss] +#set_property -dict {LOC B6 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_clk] +#set_property -dict {LOC D5 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports bmc_mosi] +#set_property -dict {LOC H4 IOSTANDARD LVCMOS18} [get_ports bmc_int] + +# Board status +#set_property -dict {LOC J2 IOSTANDARD LVCMOS33} [get_ports {fan_tacho[0]}] +#set_property -dict {LOC J3 IOSTANDARD LVCMOS33} [get_ports {fan_tacho[1]}] +set_property -dict {LOC A6 IOSTANDARD LVCMOS18} [get_ports {pg[0]}] +set_property -dict {LOC C7 IOSTANDARD LVCMOS18} [get_ports {pg[1]}] +#set_property -dict {LOC E2 IOSTANDARD LVCMOS33} [get_ports pwrbrk] + +# QSFP28 Interfaces +set_property -dict {LOC Y39 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC Y40 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC Y34 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC Y35 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_130 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC W41 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W42 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC W36 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC W37 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_130 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC V39 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V40 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC V34 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC V35 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_130 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC U41 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U42 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC U36 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +#set_property -dict {LOC U37 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_130 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3 +set_property -dict {LOC W32 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_130 from U28 +#set_property -dict {LOC W33 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_130 from U28 +set_property -dict {LOC B9 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_mod_prsnt_n] +set_property -dict {LOC A8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_reset_n] +set_property -dict {LOC A9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_lp_mode] +set_property -dict {LOC A10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_0_intr_n] +#set_property -dict {LOC B8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_i2c_scl] +#set_property -dict {LOC B7 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_0_i2c_sda] + +# 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 M39 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC M40 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC M34 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC M35 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_132 GTYE4_CHANNEL_X0Y20 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC L41 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L42 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC L36 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC L37 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_132 GTYE4_CHANNEL_X0Y21 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC K39 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K40 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC K34 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_132 GTYE4_CHANNEL_X0Y22 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC J41 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J42 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC J36 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +#set_property -dict {LOC J37 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_132 GTYE4_CHANNEL_X0Y23 / GTYE4_COMMON_X0Y5 +set_property -dict {LOC P30 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_132 from U28 +#set_property -dict {LOC P31 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_132 from U28 +set_property -dict {LOC E10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_mod_prsnt_n] +set_property -dict {LOC C10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_reset_n] +set_property -dict {LOC D9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_lp_mode] +set_property -dict {LOC D10 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_1_intr_n] +#set_property -dict {LOC C9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_i2c_scl] +#set_property -dict {LOC D8 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 4} [get_ports qsfp_1_i2c_sda] + +# 161.1328125 MHz MGT reference clock +create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p] + +# Expansion connector +#set_property -dict {LOC AG41} [get_ports {exp_rx_p[0]}] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG42} [get_ports {exp_rx_n[0]}] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG36} [get_ports {exp_tx_p[0]}] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AG37} [get_ports {exp_tx_n[0]}] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH39} [get_ports {exp_rx_p[1]}] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH40} [get_ports {exp_rx_n[1]}] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH34} [get_ports {exp_tx_p[1]}] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AH35} [get_ports {exp_tx_n[1]}] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1 +#set_property -dict {LOC AJ41} [get_ports {exp_rx_p[2]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ42} [get_ports {exp_rx_n[2]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ36} [get_ports {exp_tx_p[2]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AJ37} [get_ports {exp_tx_n[2]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK39} [get_ports {exp_rx_p[3]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK40} [get_ports {exp_rx_n[3]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK34} [get_ports {exp_tx_p[3]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AK35} [get_ports {exp_tx_n[3]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL41} [get_ports {exp_rx_p[4]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL42} [get_ports {exp_rx_n[4]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL36} [get_ports {exp_tx_p[4]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL37} [get_ports {exp_tx_n[4]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM39} [get_ports {exp_rx_p[5]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM40} [get_ports {exp_rx_n[5]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM34} [get_ports {exp_tx_p[5]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AM35} [get_ports {exp_tx_n[5]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0 +#set_property -dict {LOC AL32} [get_ports exp_refclk_0_p] ;# MGTREFCLK0P_128 from U28 +#set_property -dict {LOC AL33} [get_ports exp_refclk_0_n] ;# MGTREFCLK0N_128 from U28 +#set_property -dict {LOC AG32} [get_ports exp_refclk_1_p] ;# MGTREFCLK0P_127 from U28 +#set_property -dict {LOC AG33} [get_ports exp_refclk_1_n] ;# MGTREFCLK0N_127 from U28 +#set_property -dict {LOC E3 IOSTANDARD LVCMOS33} [get_ports {exp_gpio[0]}] +#set_property -dict {LOC F3 IOSTANDARD LVCMOS33} [get_ports {exp_gpio[1]}] + +# 161.1328125 MHz MGT reference clock +#create_clock -period 6.206 -name exp_refclk_0 [get_ports exp_refclk_0_p] +#create_clock -period 6.206 -name exp_refclk_1 [get_ports exp_refclk_1_p] + +# PCIe Interface +#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[0]}] ;# MGTHRXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[0]}] ;# MGTHRXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AG6 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AG5 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AH4 } [get_ports {pcie_rx_p[1]}] ;# MGTHRXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AH3 } [get_ports {pcie_rx_n[1]}] ;# MGTHRXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AH8 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AH7 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[2]}] ;# MGTHRXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[2]}] ;# MGTHRXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AJ6 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AJ5 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[3]}] ;# MGTHRXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[3]}] ;# MGTHRXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AK8 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AK7 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y3 +#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[4]}] ;# MGTHRXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[4]}] ;# MGTHRXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AL6 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AL5 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[5]}] ;# MGTHRXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[5]}] ;# MGTHRXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AM8 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AM7 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[6]}] ;# MGTHRXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[6]}] ;# MGTHRXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AN6 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AN5 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[7]}] ;# MGTHRXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[7]}] ;# MGTHRXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AP8 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AP7 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y2 +#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[8]}] ;# MGTHRXP3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[8]}] ;# MGTHRXN3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AR6 } [get_ports {pcie_tx_p[8]}] ;# MGTHTXP3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AR5 } [get_ports {pcie_tx_n[8]}] ;# MGTHTXN3_225 GTHE4_CHANNEL_X0Y7 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[9]}] ;# MGTHRXP2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[9]}] ;# MGTHRXN2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AT8 } [get_ports {pcie_tx_p[9]}] ;# MGTHTXP2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AT7 } [get_ports {pcie_tx_n[9]}] ;# MGTHTXN2_225 GTHE4_CHANNEL_X0Y6 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[10]}] ;# MGTHRXP1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[10]}] ;# MGTHRXN1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AU6 } [get_ports {pcie_tx_p[10]}] ;# MGTHTXP1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AU5 } [get_ports {pcie_tx_n[10]}] ;# MGTHTXN1_225 GTHE4_CHANNEL_X0Y5 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[11]}] ;# MGTHRXP0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[11]}] ;# MGTHRXN0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AV8 } [get_ports {pcie_tx_p[11]}] ;# MGTHTXP0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AV7 } [get_ports {pcie_tx_n[11]}] ;# MGTHTXN0_225 GTHE4_CHANNEL_X0Y4 / GTHE4_COMMON_X0Y1 +#set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[12]}] ;# MGTHRXP3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[12]}] ;# MGTHRXN3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AW6 } [get_ports {pcie_tx_p[12]}] ;# MGTHTXP3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AW5 } [get_ports {pcie_tx_n[12]}] ;# MGTHTXN3_224 GTHE4_CHANNEL_X0Y3 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[13]}] ;# MGTHRXP2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[13]}] ;# MGTHRXN2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AY8 } [get_ports {pcie_tx_p[13]}] ;# MGTHTXP2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AY7 } [get_ports {pcie_tx_n[13]}] ;# MGTHTXN2_224 GTHE4_CHANNEL_X0Y2 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTHRXP1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTHRXN1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BA6 } [get_ports {pcie_tx_p[14]}] ;# MGTHTXP1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BA5 } [get_ports {pcie_tx_n[14]}] ;# MGTHTXN1_224 GTHE4_CHANNEL_X0Y1 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[15]}] ;# MGTHRXP0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[15]}] ;# MGTHRXN0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BB8 } [get_ports {pcie_tx_p[15]}] ;# MGTHTXP0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC BB7 } [get_ports {pcie_tx_n[15]}] ;# MGTHTXN0_224 GTHE4_CHANNEL_X0Y0 / GTHE4_COMMON_X0Y0 +#set_property -dict {LOC AN10} [get_ports pcie_refclk_p] ;# MGTREFCLK0P_226 +#set_property -dict {LOC AN9 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_226 +#set_property -dict {LOC G1 IOSTANDARD LVCMOS33 PULLUP true} [get_ports pcie_rst_n] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p] diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/fpga/Makefile b/fpga/lib/eth/example/fb2CG/fpga_10g/fpga/Makefile new file mode 100644 index 000000000..bfce2fc9d --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/fpga/Makefile @@ -0,0 +1,72 @@ + +# FPGA settings +FPGA_PART = xcku15p-ffve1760-2-e +FPGA_TOP = fpga +FPGA_ARCH = kintexuplus + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/led_sreg_driver.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v +SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v +SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/eth_phy_10g.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_frame_sync.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_ber_mon.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v +SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v +SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete_64.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v +SYN_FILES += lib/eth/rtl/udp_64.v +SYN_FILES += lib/eth/rtl/udp_ip_rx_64.v +SYN_FILES += lib/eth/rtl/udp_ip_tx_64.v +SYN_FILES += lib/eth/rtl/ip_complete_64.v +SYN_FILES += lib/eth/rtl/ip_64.v +SYN_FILES += lib/eth/rtl/ip_eth_rx_64.v +SYN_FILES += lib/eth/rtl/ip_eth_tx_64.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v + +# XDC files +XDC_FILES = fpga.xdc +XDC_FILES += led.tcl +XDC_FILES += lib/eth/syn/eth_mac_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/axis_async_fifo.tcl +XDC_FILES += lib/eth/lib/axis/syn/sync_reset.tcl + +# IP +IP_TCL_FILES += ip/gtwizard_ultrascale_0.tcl + +include ../common/vivado.mk + +program: $(FPGA_TOP).bit + echo "open_hw" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/ip/gtwizard_ultrascale_0.tcl b/fpga/lib/eth/example/fb2CG/fpga_10g/ip/gtwizard_ultrascale_0.tcl new file mode 100644 index 000000000..acf48c552 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/ip/gtwizard_ultrascale_0.tcl @@ -0,0 +1,21 @@ + +create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name gtwizard_ultrascale_0 + +set_property -dict [list CONFIG.preset {GTY-10GBASE-R}] [get_ips gtwizard_ultrascale_0] + +set_property -dict [list \ + CONFIG.CHANNEL_ENABLE {X0Y23 X0Y22 X0Y21 X0Y20 X0Y15 X0Y14 X0Y13 X0Y12} \ + CONFIG.TX_MASTER_CHANNEL {X0Y12} \ + CONFIG.RX_MASTER_CHANNEL {X0Y12} \ + CONFIG.TX_LINE_RATE {10.3125} \ + CONFIG.TX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.TX_USER_DATA_WIDTH {64} \ + CONFIG.TX_INT_DATA_WIDTH {64} \ + CONFIG.RX_LINE_RATE {10.3125} \ + CONFIG.RX_REFCLK_FREQUENCY {161.1328125} \ + CONFIG.RX_USER_DATA_WIDTH {64} \ + CONFIG.RX_INT_DATA_WIDTH {64} \ + CONFIG.RX_REFCLK_SOURCE {X0Y23 clk0 X0Y22 clk0 X0Y21 clk0 X0Y20 clk0 X0Y15 clk0 X0Y14 clk0 X0Y13 clk0 X0Y12 clk0} \ + CONFIG.TX_REFCLK_SOURCE {X0Y23 clk0 X0Y22 clk0 X0Y21 clk0 X0Y20 clk0 X0Y15 clk0 X0Y14 clk0 X0Y13 clk0 X0Y12 clk0} \ + CONFIG.FREERUN_FREQUENCY {125} \ +] [get_ips gtwizard_ultrascale_0] diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/led.tcl b/fpga/lib/eth/example/fb2CG/fpga_10g/led.tcl new file mode 100644 index 000000000..e430903ef --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/led.tcl @@ -0,0 +1,12 @@ +# Timing constraints for led_sreg_driver + +foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == led_sreg_driver || REF_NAME == led_sreg_driver)}] { + puts "Inserting timing constraints for led_sreg_driver instance $inst" + + set select_ffs [get_cells "$inst/led_sync_reg_1_reg[*] $inst/led_sync_reg_2_reg[*]"] + + if {[llength $select_ffs]} { + set_property ASYNC_REG TRUE $select_ffs + set_false_path -from [all_registers] -to [get_cells "$inst/led_sync_reg_1_reg[*]"] + } +} diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/lib/eth b/fpga/lib/eth/example/fb2CG/fpga_10g/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga.v b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga.v new file mode 100644 index 000000000..49d55c5e0 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga.v @@ -0,0 +1,911 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 100MHz + */ + input wire init_clk, + + /* + * GPIO + */ + output wire led_sreg_d, + output wire led_sreg_ld, + output wire led_sreg_clk, + output wire [1:0] led_bmc, + output wire [1:0] led_exp, + + /* + * Board status + */ + input wire [1:0] pg, + + /* + * 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_mod_prsnt_n, + output wire qsfp_0_reset_n, + output wire qsfp_0_lp_mode, + input wire qsfp_0_intr_n, + + 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_mod_prsnt_n, + output wire qsfp_1_reset_n, + output wire qsfp_1_lp_mode, + input wire qsfp_1_intr_n +); + +// Clock and reset + +wire init_clk_bufg; + +// 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 = !pg[0] || !pg[1]; +wire mmcm_locked; +wire mmcm_clkfb; + +BUFG +init_clk_bufg_inst ( + .I(init_clk), + .O(init_clk_bufg) +); + +// MMCM instance +// 50 MHz in, 125 MHz out +// PFD range: 10 MHz to 500 MHz +// VCO range: 800 MHz to 1600 MHz +// M = 20, D = 1 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(20), + .CLKFBOUT_PHASE(0), + .DIVCLK_DIVIDE(1), + .REF_JITTER1(0.010), + .CLKIN1_PERIOD(20.000), + .STARTUP_WAIT("FALSE"), + .CLKOUT4_CASCADE("FALSE") +) +clk_mmcm_inst ( + .CLKIN1(init_clk_bufg), + .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 [7:0] led_red; +wire [7:0] led_green; +wire [15:0] led_merged; + +assign led_merged[0] = led_red[0]; +assign led_merged[1] = led_green[0]; +assign led_merged[2] = led_red[1]; +assign led_merged[3] = led_green[1]; +assign led_merged[4] = led_red[2]; +assign led_merged[5] = led_green[2]; +assign led_merged[6] = led_red[3]; +assign led_merged[7] = led_green[3]; +assign led_merged[8] = led_red[4]; +assign led_merged[9] = led_green[4]; +assign led_merged[10] = led_red[5]; +assign led_merged[11] = led_green[5]; +assign led_merged[12] = led_red[6]; +assign led_merged[13] = led_green[6]; +assign led_merged[14] = led_red[7]; +assign led_merged[15] = led_green[7]; + +led_sreg_driver #( + .COUNT(16), + .INVERT(1), + .PRESCALE(31) +) +led_sreg_driver_inst ( + .clk(clk_125mhz_int), + .rst(rst_125mhz_int), + + .led(led_merged), + + .sreg_d(led_sreg_d), + .sreg_ld(led_sreg_ld), + .sreg_clk(led_sreg_clk) +); + +// XGMII 10G PHY +assign qsfp_0_reset_n = 1'b1; +assign qsfp_0_lp_mode = 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 qsfp_1_reset_n = 1'b1; +assign qsfp_1_lp_mode = 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_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_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_0_gtpowergood_0; +wire qsfp_0_gtpowergood_1; +wire qsfp_0_gtpowergood_2; +wire qsfp_0_gtpowergood_3; +wire qsfp_1_gtpowergood_0; +wire qsfp_1_gtpowergood_1; +wire qsfp_1_gtpowergood_2; +wire qsfp_1_gtpowergood_3; + +wire qsfp_0_mgt_refclk; +wire qsfp_1_mgt_refclk; + +wire [7:0] gt_txclkout; +wire gt_txusrclk; + +wire [7:0] gt_rxclkout; +wire [7:0] gt_rxusrclk; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [7:0] gt_txprgdivresetdone; +wire [7:0] gt_txpmaresetdone; +wire [7:0] gt_rxprgdivresetdone; +wire [7:0] gt_rxpmaresetdone; + +wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); +wire gt_rx_reset = ~>_rxpmaresetdone; + +reg gt_userclk_tx_active = 1'b0; +reg [7:0] gt_userclk_rx_active = 1'b0; + +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 () +); + +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 () +); + +BUFG_GT bufg_gt_tx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txclkout[0]), + .O (gt_txusrclk) +); + +assign clk_156mhz_int = gt_txusrclk; + +always @(posedge gt_txusrclk, posedge gt_tx_reset) begin + if (gt_tx_reset) begin + gt_userclk_tx_active <= 1'b0; + end else begin + gt_userclk_tx_active <= 1'b1; + end +end + +generate + +genvar n; + +for (n = 0; n < 8; n = n + 1) begin + + BUFG_GT bufg_gt_rx_usrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxclkout[n]), + .O (gt_rxusrclk[n]) + ); + + always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin + if (gt_rx_reset) begin + gt_userclk_rx_active[n] <= 1'b0; + end else begin + gt_userclk_rx_active[n] <= 1'b1; + end + end + +end + +endgenerate + +sync_reset #( + .N(4) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz_int), + .rst(~gt_reset_tx_done), + .out(rst_156mhz_int) +); + +wire [5:0] qsfp_0_gt_txheader_0; +wire [63:0] qsfp_0_gt_txdata_0; +wire qsfp_0_gt_rxgearboxslip_0; +wire [5:0] qsfp_0_gt_rxheader_0; +wire [1:0] qsfp_0_gt_rxheadervalid_0; +wire [63:0] qsfp_0_gt_rxdata_0; +wire [1:0] qsfp_0_gt_rxdatavalid_0; + +wire [5:0] qsfp_0_gt_txheader_1; +wire [63:0] qsfp_0_gt_txdata_1; +wire qsfp_0_gt_rxgearboxslip_1; +wire [5:0] qsfp_0_gt_rxheader_1; +wire [1:0] qsfp_0_gt_rxheadervalid_1; +wire [63:0] qsfp_0_gt_rxdata_1; +wire [1:0] qsfp_0_gt_rxdatavalid_1; + +wire [5:0] qsfp_0_gt_txheader_2; +wire [63:0] qsfp_0_gt_txdata_2; +wire qsfp_0_gt_rxgearboxslip_2; +wire [5:0] qsfp_0_gt_rxheader_2; +wire [1:0] qsfp_0_gt_rxheadervalid_2; +wire [63:0] qsfp_0_gt_rxdata_2; +wire [1:0] qsfp_0_gt_rxdatavalid_2; + +wire [5:0] qsfp_0_gt_txheader_3; +wire [63:0] qsfp_0_gt_txdata_3; +wire qsfp_0_gt_rxgearboxslip_3; +wire [5:0] qsfp_0_gt_rxheader_3; +wire [1:0] qsfp_0_gt_rxheadervalid_3; +wire [63:0] qsfp_0_gt_rxdata_3; +wire [1:0] qsfp_0_gt_rxdatavalid_3; + +wire [5:0] qsfp_1_gt_txheader_0; +wire [63:0] qsfp_1_gt_txdata_0; +wire qsfp_1_gt_rxgearboxslip_0; +wire [5:0] qsfp_1_gt_rxheader_0; +wire [1:0] qsfp_1_gt_rxheadervalid_0; +wire [63:0] qsfp_1_gt_rxdata_0; +wire [1:0] qsfp_1_gt_rxdatavalid_0; + +wire [5:0] qsfp_1_gt_txheader_1; +wire [63:0] qsfp_1_gt_txdata_1; +wire qsfp_1_gt_rxgearboxslip_1; +wire [5:0] qsfp_1_gt_rxheader_1; +wire [1:0] qsfp_1_gt_rxheadervalid_1; +wire [63:0] qsfp_1_gt_rxdata_1; +wire [1:0] qsfp_1_gt_rxdatavalid_1; + +wire [5:0] qsfp_1_gt_txheader_2; +wire [63:0] qsfp_1_gt_txdata_2; +wire qsfp_1_gt_rxgearboxslip_2; +wire [5:0] qsfp_1_gt_rxheader_2; +wire [1:0] qsfp_1_gt_rxheadervalid_2; +wire [63:0] qsfp_1_gt_rxdata_2; +wire [1:0] qsfp_1_gt_rxdatavalid_2; + +wire [5:0] qsfp_1_gt_txheader_3; +wire [63:0] qsfp_1_gt_txdata_3; +wire qsfp_1_gt_rxgearboxslip_3; +wire [5:0] qsfp_1_gt_rxheader_3; +wire [1:0] qsfp_1_gt_rxheadervalid_3; +wire [63:0] qsfp_1_gt_rxdata_3; +wire [1:0] qsfp_1_gt_rxdatavalid_3; + +gtwizard_ultrascale_0 +qsfp_gty_inst ( + .gtwiz_userclk_tx_active_in(>_userclk_tx_active), + .gtwiz_userclk_rx_active_in(>_userclk_rx_active), + + .gtwiz_reset_clk_freerun_in(clk_125mhz_int), + .gtwiz_reset_all_in(rst_125mhz_int), + + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(1'b0), + + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(1'b0), + + .gtwiz_reset_rx_cdr_stable_out(), + + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + + .gtrefclk00_in({qsfp_1_mgt_refclk, qsfp_0_mgt_refclk}), + + .qpll0outclk_out(), + .qpll0outrefclk_out(), + + .gtyrxn_in({qsfp_1_rx_3_n, qsfp_1_rx_2_n, qsfp_1_rx_1_n, qsfp_1_rx_0_n, qsfp_0_rx_3_n, qsfp_0_rx_2_n, qsfp_0_rx_1_n, qsfp_0_rx_0_n}), + .gtyrxp_in({qsfp_1_rx_3_p, qsfp_1_rx_2_p, qsfp_1_rx_1_p, qsfp_1_rx_0_p, qsfp_0_rx_3_p, qsfp_0_rx_2_p, qsfp_0_rx_1_p, qsfp_0_rx_0_p}), + + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk), + + .gtwiz_userdata_tx_in({qsfp_1_gt_txdata_3, qsfp_1_gt_txdata_2, qsfp_1_gt_txdata_1, qsfp_1_gt_txdata_0, qsfp_0_gt_txdata_3, qsfp_0_gt_txdata_2, qsfp_0_gt_txdata_1, qsfp_0_gt_txdata_0}), + .txheader_in({qsfp_1_gt_txheader_3, qsfp_1_gt_txheader_2, qsfp_1_gt_txheader_1, qsfp_1_gt_txheader_0, qsfp_0_gt_txheader_3, qsfp_0_gt_txheader_2, qsfp_0_gt_txheader_1, qsfp_0_gt_txheader_0}), + .txsequence_in({8{1'b0}}), + + .txusrclk_in({8{gt_txusrclk}}), + .txusrclk2_in({8{gt_txusrclk}}), + + .gtpowergood_out({qsfp_1_gtpowergood_3, qsfp_1_gtpowergood_2, qsfp_1_gtpowergood_1, qsfp_1_gtpowergood_0, qsfp_0_gtpowergood_3, qsfp_0_gtpowergood_2, qsfp_0_gtpowergood_1, qsfp_0_gtpowergood_0}), + + .gtytxn_out({qsfp_1_tx_3_n, qsfp_1_tx_2_n, qsfp_1_tx_1_n, qsfp_1_tx_0_n, qsfp_0_tx_3_n, qsfp_0_tx_2_n, qsfp_0_tx_1_n, qsfp_0_tx_0_n}), + .gtytxp_out({qsfp_1_tx_3_p, qsfp_1_tx_2_p, qsfp_1_tx_1_p, qsfp_1_tx_0_p, qsfp_0_tx_3_p, qsfp_0_tx_2_p, qsfp_0_tx_1_p, qsfp_0_tx_0_p}), + + .rxgearboxslip_in({qsfp_1_gt_rxgearboxslip_3, qsfp_1_gt_rxgearboxslip_2, qsfp_1_gt_rxgearboxslip_1, qsfp_1_gt_rxgearboxslip_0, qsfp_0_gt_rxgearboxslip_3, qsfp_0_gt_rxgearboxslip_2, qsfp_0_gt_rxgearboxslip_1, qsfp_0_gt_rxgearboxslip_0}), + .gtwiz_userdata_rx_out({qsfp_1_gt_rxdata_3, qsfp_1_gt_rxdata_2, qsfp_1_gt_rxdata_1, qsfp_1_gt_rxdata_0, qsfp_0_gt_rxdata_3, qsfp_0_gt_rxdata_2, qsfp_0_gt_rxdata_1, qsfp_0_gt_rxdata_0}), + .rxdatavalid_out({qsfp_1_gt_rxdatavalid_3, qsfp_1_gt_rxdatavalid_2, qsfp_1_gt_rxdatavalid_1, qsfp_1_gt_rxdatavalid_0, qsfp_0_gt_rxdatavalid_3, qsfp_0_gt_rxdatavalid_2, qsfp_0_gt_rxdatavalid_1, qsfp_0_gt_rxdatavalid_0}), + .rxheader_out({qsfp_1_gt_rxheader_3, qsfp_1_gt_rxheader_2, qsfp_1_gt_rxheader_1, qsfp_1_gt_rxheader_0, qsfp_0_gt_rxheader_3, qsfp_0_gt_rxheader_2, qsfp_0_gt_rxheader_1, qsfp_0_gt_rxheader_0}), + .rxheadervalid_out({qsfp_1_gt_rxheadervalid_3, qsfp_1_gt_rxheadervalid_2, qsfp_1_gt_rxheadervalid_1, qsfp_1_gt_rxheadervalid_0, qsfp_0_gt_rxheadervalid_3, qsfp_0_gt_rxheadervalid_2, qsfp_0_gt_rxheadervalid_1, qsfp_0_gt_rxheadervalid_0}), + .rxoutclk_out(gt_rxclkout), + .rxpmaresetdone_out(gt_rxpmaresetdone), + .rxprgdivresetdone_out(gt_rxprgdivresetdone), + .rxstartofseq_out(), + + .txoutclk_out(gt_txclkout), + .txpmaresetdone_out(gt_txpmaresetdone), + .txprgdivresetdone_out(gt_txprgdivresetdone) +); + +assign qsfp_0_tx_clk_0_int = clk_156mhz_int; +assign qsfp_0_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_0_int = gt_rxusrclk[0]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_0_reset_sync_inst ( + .clk(qsfp_0_rx_clk_0_int), + .rst(~gt_reset_rx_done), + .out(qsfp_0_rx_rst_0_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_0_inst ( + .tx_clk(qsfp_0_tx_clk_0_int), + .tx_rst(qsfp_0_tx_rst_0_int), + .rx_clk(qsfp_0_rx_clk_0_int), + .rx_rst(qsfp_0_rx_rst_0_int), + .xgmii_txd(qsfp_0_txd_0_int), + .xgmii_txc(qsfp_0_txc_0_int), + .xgmii_rxd(qsfp_0_rxd_0_int), + .xgmii_rxc(qsfp_0_rxc_0_int), + .serdes_tx_data(qsfp_0_gt_txdata_0), + .serdes_tx_hdr(qsfp_0_gt_txheader_0), + .serdes_rx_data(qsfp_0_gt_rxdata_0), + .serdes_rx_hdr(qsfp_0_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_0_rx_block_lock_0), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_1_int = clk_156mhz_int; +assign qsfp_0_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_1_int = gt_rxusrclk[1]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_1_reset_sync_inst ( + .clk(qsfp_0_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp_0_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_1_inst ( + .tx_clk(qsfp_0_tx_clk_1_int), + .tx_rst(qsfp_0_tx_rst_1_int), + .rx_clk(qsfp_0_rx_clk_1_int), + .rx_rst(qsfp_0_rx_rst_1_int), + .xgmii_txd(qsfp_0_txd_1_int), + .xgmii_txc(qsfp_0_txc_1_int), + .xgmii_rxd(qsfp_0_rxd_1_int), + .xgmii_rxc(qsfp_0_rxc_1_int), + .serdes_tx_data(qsfp_0_gt_txdata_1), + .serdes_tx_hdr(qsfp_0_gt_txheader_1), + .serdes_rx_data(qsfp_0_gt_rxdata_1), + .serdes_rx_hdr(qsfp_0_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_0_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_2_int = clk_156mhz_int; +assign qsfp_0_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_2_int = gt_rxusrclk[2]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_2_reset_sync_inst ( + .clk(qsfp_0_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp_0_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_2_inst ( + .tx_clk(qsfp_0_tx_clk_2_int), + .tx_rst(qsfp_0_tx_rst_2_int), + .rx_clk(qsfp_0_rx_clk_2_int), + .rx_rst(qsfp_0_rx_rst_2_int), + .xgmii_txd(qsfp_0_txd_2_int), + .xgmii_txc(qsfp_0_txc_2_int), + .xgmii_rxd(qsfp_0_rxd_2_int), + .xgmii_rxc(qsfp_0_rxc_2_int), + .serdes_tx_data(qsfp_0_gt_txdata_2), + .serdes_tx_hdr(qsfp_0_gt_txheader_2), + .serdes_rx_data(qsfp_0_gt_rxdata_2), + .serdes_rx_hdr(qsfp_0_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_0_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp_0_tx_clk_3_int = clk_156mhz_int; +assign qsfp_0_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_0_rx_clk_3_int = gt_rxusrclk[3]; + +sync_reset #( + .N(4) +) +qsfp_0_rx_rst_3_reset_sync_inst ( + .clk(qsfp_0_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp_0_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_0_phy_3_inst ( + .tx_clk(qsfp_0_tx_clk_3_int), + .tx_rst(qsfp_0_tx_rst_3_int), + .rx_clk(qsfp_0_rx_clk_3_int), + .rx_rst(qsfp_0_rx_rst_3_int), + .xgmii_txd(qsfp_0_txd_3_int), + .xgmii_txc(qsfp_0_txc_3_int), + .xgmii_rxd(qsfp_0_rxd_3_int), + .xgmii_rxc(qsfp_0_rxc_3_int), + .serdes_tx_data(qsfp_0_gt_txdata_3), + .serdes_tx_hdr(qsfp_0_gt_txheader_3), + .serdes_rx_data(qsfp_0_gt_rxdata_3), + .serdes_rx_hdr(qsfp_0_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_0_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_0_rx_block_lock_3), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_0_int = clk_156mhz_int; +assign qsfp_1_tx_rst_0_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_0_int = gt_rxusrclk[4]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_0_reset_sync_inst ( + .clk(qsfp_1_rx_clk_0_int), + .rst(~gt_reset_rx_done), + .out(qsfp_1_rx_rst_0_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_0_inst ( + .tx_clk(qsfp_1_tx_clk_0_int), + .tx_rst(qsfp_1_tx_rst_0_int), + .rx_clk(qsfp_1_rx_clk_0_int), + .rx_rst(qsfp_1_rx_rst_0_int), + .xgmii_txd(qsfp_1_txd_0_int), + .xgmii_txc(qsfp_1_txc_0_int), + .xgmii_rxd(qsfp_1_rxd_0_int), + .xgmii_rxc(qsfp_1_rxc_0_int), + .serdes_tx_data(qsfp_1_gt_txdata_0), + .serdes_tx_hdr(qsfp_1_gt_txheader_0), + .serdes_rx_data(qsfp_1_gt_rxdata_0), + .serdes_rx_hdr(qsfp_1_gt_rxheader_0), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_0), + .rx_block_lock(qsfp_1_rx_block_lock_0), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_1_int = clk_156mhz_int; +assign qsfp_1_tx_rst_1_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_1_int = gt_rxusrclk[5]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_1_reset_sync_inst ( + .clk(qsfp_1_rx_clk_1_int), + .rst(~gt_reset_rx_done), + .out(qsfp_1_rx_rst_1_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_1_inst ( + .tx_clk(qsfp_1_tx_clk_1_int), + .tx_rst(qsfp_1_tx_rst_1_int), + .rx_clk(qsfp_1_rx_clk_1_int), + .rx_rst(qsfp_1_rx_rst_1_int), + .xgmii_txd(qsfp_1_txd_1_int), + .xgmii_txc(qsfp_1_txc_1_int), + .xgmii_rxd(qsfp_1_rxd_1_int), + .xgmii_rxc(qsfp_1_rxc_1_int), + .serdes_tx_data(qsfp_1_gt_txdata_1), + .serdes_tx_hdr(qsfp_1_gt_txheader_1), + .serdes_rx_data(qsfp_1_gt_rxdata_1), + .serdes_rx_hdr(qsfp_1_gt_rxheader_1), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_1), + .rx_block_lock(qsfp_1_rx_block_lock_1), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_2_int = clk_156mhz_int; +assign qsfp_1_tx_rst_2_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_2_int = gt_rxusrclk[6]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_2_reset_sync_inst ( + .clk(qsfp_1_rx_clk_2_int), + .rst(~gt_reset_rx_done), + .out(qsfp_1_rx_rst_2_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_2_inst ( + .tx_clk(qsfp_1_tx_clk_2_int), + .tx_rst(qsfp_1_tx_rst_2_int), + .rx_clk(qsfp_1_rx_clk_2_int), + .rx_rst(qsfp_1_rx_rst_2_int), + .xgmii_txd(qsfp_1_txd_2_int), + .xgmii_txc(qsfp_1_txc_2_int), + .xgmii_rxd(qsfp_1_rxd_2_int), + .xgmii_rxc(qsfp_1_rxc_2_int), + .serdes_tx_data(qsfp_1_gt_txdata_2), + .serdes_tx_hdr(qsfp_1_gt_txheader_2), + .serdes_rx_data(qsfp_1_gt_rxdata_2), + .serdes_rx_hdr(qsfp_1_gt_rxheader_2), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_2), + .rx_block_lock(qsfp_1_rx_block_lock_2), + .rx_high_ber() +); + +assign qsfp_1_tx_clk_3_int = clk_156mhz_int; +assign qsfp_1_tx_rst_3_int = rst_156mhz_int; + +assign qsfp_1_rx_clk_3_int = gt_rxusrclk[7]; + +sync_reset #( + .N(4) +) +qsfp_1_rx_rst_3_reset_sync_inst ( + .clk(qsfp_1_rx_clk_3_int), + .rst(~gt_reset_rx_done), + .out(qsfp_1_rx_rst_3_int) +); + +eth_phy_10g #( + .BIT_REVERSE(1) +) +qsfp_1_phy_3_inst ( + .tx_clk(qsfp_1_tx_clk_3_int), + .tx_rst(qsfp_1_tx_rst_3_int), + .rx_clk(qsfp_1_rx_clk_3_int), + .rx_rst(qsfp_1_rx_rst_3_int), + .xgmii_txd(qsfp_1_txd_3_int), + .xgmii_txc(qsfp_1_txc_3_int), + .xgmii_rxd(qsfp_1_rxd_3_int), + .xgmii_rxc(qsfp_1_rxc_3_int), + .serdes_tx_data(qsfp_1_gt_txdata_3), + .serdes_tx_hdr(qsfp_1_gt_txheader_3), + .serdes_rx_data(qsfp_1_gt_rxdata_3), + .serdes_rx_hdr(qsfp_1_gt_rxheader_3), + .serdes_rx_bitslip(qsfp_1_gt_rxgearboxslip_3), + .rx_block_lock(qsfp_1_rx_block_lock_3), + .rx_high_ber() +); + +assign led_green = {qsfp_1_rx_block_lock_3, qsfp_1_rx_block_lock_2, qsfp_1_rx_block_lock_1, qsfp_1_rx_block_lock_0, qsfp_0_rx_block_lock_3, qsfp_0_rx_block_lock_2, qsfp_0_rx_block_lock_1, qsfp_0_rx_block_lock_0}; + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz_int), + .rst(rst_156mhz_int), + /* + * GPIO + */ + .led_red(led_red), + // .led_green(led_green), + .led_bmc(led_bmc), + .led_exp(led_exp), + /* + * 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 diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga_core.v b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga_core.v new file mode 100644 index 000000000..ec6ba8f58 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/fpga_core.v @@ -0,0 +1,664 @@ +/* + +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 + +`timescale 1ns / 1ps + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "XILINX" +) +( + /* + * Clock: 156.25MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + + /* + * GPIO + */ + output wire [7:0] led_red, + output wire [7:0] led_green, + output wire [1:0] led_bmc, + output wire [1:0] led_exp, + + /* + * 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 led_red = led_reg; +assign led_green = led_reg; +assign led_bmc = 2'b00; +assign led_exp = 2'b11; + +assign phy_reset_n = !rst; + +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 diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/led_sreg_driver.v b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/led_sreg_driver.v new file mode 100644 index 000000000..fa81ea1a7 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/led_sreg_driver.v @@ -0,0 +1,135 @@ +/* + +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. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * LED shift register driver + */ +module led_sreg_driver #( + // number of LEDs + parameter COUNT = 8, + // invert output + parameter INVERT = 0, + // clock prescale + parameter PRESCALE = 31 +) +( + input wire clk, + input wire rst, + + input wire [COUNT-1:0] led, + + output wire sreg_d, + output wire sreg_ld, + output wire sreg_clk +); + +localparam CL_COUNT = $clog2(COUNT+1); +localparam CL_PRESCALE = $clog2(PRESCALE+1); + +reg [CL_COUNT-1:0] count_reg = 0; +reg [CL_PRESCALE-1:0] prescale_count_reg = 0; +reg enable_reg = 1'b0; +reg update_reg = 1'b1; +reg cycle_reg = 1'b0; + +reg [COUNT-1:0] led_sync_reg_1 = 0; +reg [COUNT-1:0] led_sync_reg_2 = 0; +reg [COUNT-1:0] led_reg = 0; + +reg sreg_d_reg = 1'b0; +reg sreg_ld_reg = 1'b0; +reg sreg_clk_reg = 1'b0; + +assign sreg_d = INVERT ? !sreg_d_reg : sreg_d_reg; +assign sreg_ld = sreg_ld_reg; +assign sreg_clk = sreg_clk_reg; + +always @(posedge clk) begin + led_sync_reg_1 <= led; + led_sync_reg_2 <= led_sync_reg_1; + + enable_reg <= 1'b0; + + if (prescale_count_reg) begin + prescale_count_reg <= prescale_count_reg - 1; + end else begin + enable_reg <= 1'b1; + prescale_count_reg <= PRESCALE; + end + + if (enable_reg) begin + if (cycle_reg) begin + cycle_reg <= 1'b0; + sreg_clk_reg <= 1'b1; + end else if (count_reg) begin + sreg_clk_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + + if (count_reg < COUNT) begin + count_reg <= count_reg + 1; + cycle_reg <= 1'b1; + sreg_d_reg <= led_reg[count_reg]; + end else begin + count_reg <= 0; + cycle_reg <= 1'b0; + sreg_d_reg <= 1'b0; + sreg_ld_reg <= 1'b1; + end + end else begin + sreg_clk_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + + if (update_reg) begin + update_reg <= 1'b0; + + count_reg <= 1; + cycle_reg <= 1'b1; + sreg_d_reg <= led_reg[0]; + end + end + end + + if (led_sync_reg_2 != led_reg) begin + led_reg <= led_sync_reg_2; + update_reg <= 1'b1; + end + + if (rst) begin + count_reg <= 0; + prescale_count_reg <= 0; + enable_reg <= 1'b0; + update_reg <= 1'b1; + cycle_reg <= 1'b0; + led_reg <= 0; + sreg_d_reg <= 1'b0; + sreg_ld_reg <= 1'b0; + sreg_clk_reg <= 1'b0; + end +end + +endmodule diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/sync_signal.v b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/sync_signal.v new file mode 100644 index 000000000..b2a8ce3de --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +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 + +`timescale 1 ns / 1 ps + +/* + * 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 diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/arp_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/arp_ep.py new file mode 120000 index 000000000..7b3d3ed97 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/axis_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/axis_ep.py new file mode 120000 index 000000000..385bb0300 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/eth_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/eth_ep.py new file mode 120000 index 000000000..bac19feea --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/ip_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/ip_ep.py new file mode 120000 index 000000000..6dfa928a7 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.py new file mode 100755 index 000000000..d6f438d61 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.py @@ -0,0 +1,463 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016-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. + +""" + +from myhdl import * +import os + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' +testbench = 'test_%s' % module + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") +srcs.append("../lib/eth/rtl/eth_mac_10g.v") +srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") +srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") +srcs.append("../lib/eth/rtl/lfsr.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") +srcs.append("../lib/eth/rtl/udp_complete_64.v") +srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") +srcs.append("../lib/eth/rtl/udp_64.v") +srcs.append("../lib/eth/rtl/udp_ip_rx_64.v") +srcs.append("../lib/eth/rtl/udp_ip_tx_64.v") +srcs.append("../lib/eth/rtl/ip_complete_64.v") +srcs.append("../lib/eth/rtl/ip_64.v") +srcs.append("../lib/eth/rtl/ip_eth_rx_64.v") +srcs.append("../lib/eth/rtl/ip_eth_tx_64.v") +srcs.append("../lib/eth/rtl/ip_arb_mux.v") +srcs.append("../lib/eth/rtl/arp.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx.v") +srcs.append("../lib/eth/rtl/arp_eth_tx.v") +srcs.append("../lib/eth/rtl/eth_arb_mux.v") +srcs.append("../lib/eth/lib/axis/rtl/arbiter.v") +srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v") +srcs.append("%s.v" % testbench) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + qsfp_0_tx_clk_0 = Signal(bool(0)) + qsfp_0_tx_rst_0 = Signal(bool(0)) + qsfp_0_rx_clk_0 = Signal(bool(0)) + qsfp_0_rx_rst_0 = Signal(bool(0)) + qsfp_0_rxd_0 = Signal(intbv(0)[64:]) + qsfp_0_rxc_0 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_1 = Signal(bool(0)) + qsfp_0_tx_rst_1 = Signal(bool(0)) + qsfp_0_rx_clk_1 = Signal(bool(0)) + qsfp_0_rx_rst_1 = Signal(bool(0)) + qsfp_0_rxd_1 = Signal(intbv(0)[64:]) + qsfp_0_rxc_1 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_2 = Signal(bool(0)) + qsfp_0_tx_rst_2 = Signal(bool(0)) + qsfp_0_rx_clk_2 = Signal(bool(0)) + qsfp_0_rx_rst_2 = Signal(bool(0)) + qsfp_0_rxd_2 = Signal(intbv(0)[64:]) + qsfp_0_rxc_2 = Signal(intbv(0)[8:]) + qsfp_0_tx_clk_3 = Signal(bool(0)) + qsfp_0_tx_rst_3 = Signal(bool(0)) + qsfp_0_rx_clk_3 = Signal(bool(0)) + qsfp_0_rx_rst_3 = Signal(bool(0)) + qsfp_0_rxd_3 = Signal(intbv(0)[64:]) + qsfp_0_rxc_3 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_0 = Signal(bool(0)) + qsfp_1_tx_rst_0 = Signal(bool(0)) + qsfp_1_rx_clk_0 = Signal(bool(0)) + qsfp_1_rx_rst_0 = Signal(bool(0)) + qsfp_1_rxd_0 = Signal(intbv(0)[64:]) + qsfp_1_rxc_0 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_1 = Signal(bool(0)) + qsfp_1_tx_rst_1 = Signal(bool(0)) + qsfp_1_rx_clk_1 = Signal(bool(0)) + qsfp_1_rx_rst_1 = Signal(bool(0)) + qsfp_1_rxd_1 = Signal(intbv(0)[64:]) + qsfp_1_rxc_1 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_2 = Signal(bool(0)) + qsfp_1_tx_rst_2 = Signal(bool(0)) + qsfp_1_rx_clk_2 = Signal(bool(0)) + qsfp_1_rx_rst_2 = Signal(bool(0)) + qsfp_1_rxd_2 = Signal(intbv(0)[64:]) + qsfp_1_rxc_2 = Signal(intbv(0)[8:]) + qsfp_1_tx_clk_3 = Signal(bool(0)) + qsfp_1_tx_rst_3 = Signal(bool(0)) + qsfp_1_rx_clk_3 = Signal(bool(0)) + qsfp_1_rx_rst_3 = Signal(bool(0)) + qsfp_1_rxd_3 = Signal(intbv(0)[64:]) + qsfp_1_rxc_3 = Signal(intbv(0)[8:]) + + # Outputs + led_red = Signal(intbv(0)[8:]) + led_green = Signal(intbv(0)[8:]) + led_bmc = Signal(intbv(0)[2:]) + led_exp = Signal(intbv(0)[2:]) + qsfp_0_txd_0 = Signal(intbv(0)[64:]) + qsfp_0_txc_0 = Signal(intbv(0)[8:]) + qsfp_0_txd_1 = Signal(intbv(0)[64:]) + qsfp_0_txc_1 = Signal(intbv(0)[8:]) + qsfp_0_txd_2 = Signal(intbv(0)[64:]) + qsfp_0_txc_2 = Signal(intbv(0)[8:]) + qsfp_0_txd_3 = Signal(intbv(0)[64:]) + qsfp_0_txc_3 = Signal(intbv(0)[8:]) + qsfp_1_txd_0 = Signal(intbv(0)[64:]) + qsfp_1_txc_0 = Signal(intbv(0)[8:]) + qsfp_1_txd_1 = Signal(intbv(0)[64:]) + qsfp_1_txc_1 = Signal(intbv(0)[8:]) + qsfp_1_txd_2 = Signal(intbv(0)[64:]) + qsfp_1_txc_2 = Signal(intbv(0)[8:]) + qsfp_1_txd_3 = Signal(intbv(0)[64:]) + qsfp_1_txc_3 = Signal(intbv(0)[8:]) + + # sources and sinks + qsfp_0_0_source = xgmii_ep.XGMIISource() + qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') + + qsfp_0_0_sink = xgmii_ep.XGMIISink() + qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') + + qsfp_0_1_source = xgmii_ep.XGMIISource() + qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') + + qsfp_0_1_sink = xgmii_ep.XGMIISink() + qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') + + qsfp_0_2_source = xgmii_ep.XGMIISource() + qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') + + qsfp_0_2_sink = xgmii_ep.XGMIISink() + qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') + + qsfp_0_3_source = xgmii_ep.XGMIISource() + qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') + + qsfp_0_3_sink = xgmii_ep.XGMIISink() + qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') + + qsfp_1_0_source = xgmii_ep.XGMIISource() + qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') + + qsfp_1_0_sink = xgmii_ep.XGMIISink() + qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') + + qsfp_1_1_source = xgmii_ep.XGMIISource() + qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') + + qsfp_1_1_sink = xgmii_ep.XGMIISink() + qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') + + qsfp_1_2_source = xgmii_ep.XGMIISource() + qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') + + qsfp_1_2_sink = xgmii_ep.XGMIISink() + qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') + + qsfp_1_3_source = xgmii_ep.XGMIISource() + qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') + + qsfp_1_3_sink = xgmii_ep.XGMIISink() + qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') + + # DUT + if os.system(build_cmd): + raise Exception("Error running build command") + + dut = Cosimulation( + "vvp -m myhdl %s.vvp -lxt2" % testbench, + clk=clk, + rst=rst, + current_test=current_test, + + led_red=led_red, + led_green=led_green, + led_bmc=led_bmc, + led_exp=led_exp, + + qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, + qsfp_0_txd_0=qsfp_0_txd_0, + qsfp_0_txc_0=qsfp_0_txc_0, + qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, + qsfp_0_rxd_0=qsfp_0_rxd_0, + qsfp_0_rxc_0=qsfp_0_rxc_0, + qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, + qsfp_0_txd_1=qsfp_0_txd_1, + qsfp_0_txc_1=qsfp_0_txc_1, + qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, + qsfp_0_rxd_1=qsfp_0_rxd_1, + qsfp_0_rxc_1=qsfp_0_rxc_1, + qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, + qsfp_0_txd_2=qsfp_0_txd_2, + qsfp_0_txc_2=qsfp_0_txc_2, + qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, + qsfp_0_rxd_2=qsfp_0_rxd_2, + qsfp_0_rxc_2=qsfp_0_rxc_2, + qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, + qsfp_0_txd_3=qsfp_0_txd_3, + qsfp_0_txc_3=qsfp_0_txc_3, + qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, + qsfp_0_rxd_3=qsfp_0_rxd_3, + qsfp_0_rxc_3=qsfp_0_rxc_3, + qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, + qsfp_1_txd_0=qsfp_1_txd_0, + qsfp_1_txc_0=qsfp_1_txc_0, + qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, + qsfp_1_rxd_0=qsfp_1_rxd_0, + qsfp_1_rxc_0=qsfp_1_rxc_0, + qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, + qsfp_1_txd_1=qsfp_1_txd_1, + qsfp_1_txc_1=qsfp_1_txc_1, + qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, + qsfp_1_rxd_1=qsfp_1_rxd_1, + qsfp_1_rxc_1=qsfp_1_rxc_1, + qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, + qsfp_1_txd_2=qsfp_1_txd_2, + qsfp_1_txc_2=qsfp_1_txc_2, + qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, + qsfp_1_rxd_2=qsfp_1_rxd_2, + qsfp_1_rxc_2=qsfp_1_rxc_2, + qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, + qsfp_1_txd_3=qsfp_1_txd_3, + qsfp_1_txc_3=qsfp_1_txc_3, + qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, + qsfp_1_rxd_3=qsfp_1_rxd_3, + qsfp_1_rxc_3=qsfp_1_rxc_3 + ) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 + qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 + qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 + qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 + qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 + qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 + qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 + qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 + qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 + qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 + qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 + qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 + qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 + qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 + qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 + qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + qsfp_0_tx_rst_1.next = 1 + qsfp_0_rx_rst_1.next = 1 + qsfp_0_tx_rst_2.next = 1 + qsfp_0_rx_rst_2.next = 1 + qsfp_0_tx_rst_3.next = 1 + qsfp_0_rx_rst_3.next = 1 + qsfp_0_tx_rst_0.next = 1 + qsfp_0_rx_rst_0.next = 1 + qsfp_1_tx_rst_1.next = 1 + qsfp_1_rx_rst_1.next = 1 + qsfp_1_tx_rst_2.next = 1 + qsfp_1_rx_rst_2.next = 1 + qsfp_1_tx_rst_3.next = 1 + qsfp_1_rx_rst_3.next = 1 + qsfp_1_tx_rst_0.next = 1 + qsfp_1_rx_rst_0.next = 1 + yield clk.posedge + rst.next = 0 + qsfp_0_tx_rst_1.next = 0 + qsfp_0_rx_rst_1.next = 0 + qsfp_0_tx_rst_2.next = 0 + qsfp_0_rx_rst_2.next = 0 + qsfp_0_tx_rst_3.next = 0 + qsfp_0_rx_rst_3.next = 0 + qsfp_0_tx_rst_0.next = 0 + qsfp_0_rx_rst_0.next = 0 + qsfp_1_tx_rst_1.next = 0 + qsfp_1_rx_rst_1.next = 0 + qsfp_1_tx_rst_2.next = 0 + qsfp_1_rx_rst_2.next = 0 + qsfp_1_tx_rst_3.next = 0 + qsfp_1_rx_rst_3.next = 0 + qsfp_1_tx_rst_0.next = 0 + qsfp_1_rx_rst_0.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # testbench stimulus + + yield clk.posedge + print("test 1: test UDP RX packet") + current_test.next = 1 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x020000000000 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80181 + test_frame.ip_dest_ip = 0xc0a80180 + test_frame.udp_source_port = 5678 + test_frame.udp_dest_port = 1234 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x020000000000 + assert check_frame.arp_spa == 0xc0a80180 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80181 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x020000000000 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80181 + arp_frame.arp_tha = 0x020000000000 + arp_frame.arp_tpa = 0xc0a80180 + + qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while qsfp_0_0_sink.empty(): + yield clk.posedge + + rx_frame = qsfp_0_0_sink.recv() + check_eth_frame = eth_ep.EthFrame() + check_eth_frame.parse_axis_fcs(rx_frame.data[8:]) + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(check_eth_frame) + + print(check_frame) + + assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5 + assert check_frame.eth_src_mac == 0x020000000000 + assert check_frame.eth_type == 0x0800 + assert check_frame.ip_version == 4 + assert check_frame.ip_ihl == 5 + assert check_frame.ip_dscp == 0 + assert check_frame.ip_ecn == 0 + assert check_frame.ip_identification == 0 + assert check_frame.ip_flags == 2 + assert check_frame.ip_fragment_offset == 0 + assert check_frame.ip_ttl == 64 + assert check_frame.ip_protocol == 0x11 + assert check_frame.ip_source_ip == 0xc0a80180 + assert check_frame.ip_dest_ip == 0xc0a80181 + assert check_frame.udp_source_port == 1234 + assert check_frame.udp_dest_port == 5678 + assert check_frame.payload.data == bytearray(range(32)) + + assert qsfp_0_0_source.empty() + assert qsfp_0_0_sink.empty() + + yield delay(100) + + raise StopSimulation + + return instances() + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.v b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.v new file mode 100644 index 000000000..91a59fc3a --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/test_fpga_core.v @@ -0,0 +1,269 @@ +/* + +Copyright (c) 2016-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 + +`timescale 1ns / 1ps + +/* + * Testbench for fpga_core + */ +module test_fpga_core; + +// Parameters + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg qsfp_0_tx_clk_0 = 0; +reg qsfp_0_tx_rst_0 = 0; +reg qsfp_0_rx_clk_0 = 0; +reg qsfp_0_rx_rst_0 = 0; +reg [63:0] qsfp_0_rxd_0 = 0; +reg [7:0] qsfp_0_rxc_0 = 0; +reg qsfp_0_tx_clk_1 = 0; +reg qsfp_0_tx_rst_1 = 0; +reg qsfp_0_rx_clk_1 = 0; +reg qsfp_0_rx_rst_1 = 0; +reg [63:0] qsfp_0_rxd_1 = 0; +reg [7:0] qsfp_0_rxc_1 = 0; +reg qsfp_0_tx_clk_2 = 0; +reg qsfp_0_tx_rst_2 = 0; +reg qsfp_0_rx_clk_2 = 0; +reg qsfp_0_rx_rst_2 = 0; +reg [63:0] qsfp_0_rxd_2 = 0; +reg [7:0] qsfp_0_rxc_2 = 0; +reg qsfp_0_tx_clk_3 = 0; +reg qsfp_0_tx_rst_3 = 0; +reg qsfp_0_rx_clk_3 = 0; +reg qsfp_0_rx_rst_3 = 0; +reg [63:0] qsfp_0_rxd_3 = 0; +reg [7:0] qsfp_0_rxc_3 = 0; +reg qsfp_1_tx_clk_0 = 0; +reg qsfp_1_tx_rst_0 = 0; +reg qsfp_1_rx_clk_0 = 0; +reg qsfp_1_rx_rst_0 = 0; +reg [63:0] qsfp_1_rxd_0 = 0; +reg [7:0] qsfp_1_rxc_0 = 0; +reg qsfp_1_tx_clk_1 = 0; +reg qsfp_1_tx_rst_1 = 0; +reg qsfp_1_rx_clk_1 = 0; +reg qsfp_1_rx_rst_1 = 0; +reg [63:0] qsfp_1_rxd_1 = 0; +reg [7:0] qsfp_1_rxc_1 = 0; +reg qsfp_1_tx_clk_2 = 0; +reg qsfp_1_tx_rst_2 = 0; +reg qsfp_1_rx_clk_2 = 0; +reg qsfp_1_rx_rst_2 = 0; +reg [63:0] qsfp_1_rxd_2 = 0; +reg [7:0] qsfp_1_rxc_2 = 0; +reg qsfp_1_tx_clk_3 = 0; +reg qsfp_1_tx_rst_3 = 0; +reg qsfp_1_rx_clk_3 = 0; +reg qsfp_1_rx_rst_3 = 0; +reg [63:0] qsfp_1_rxd_3 = 0; +reg [7:0] qsfp_1_rxc_3 = 0; + +// Outputs +wire [7:0] led_red; +wire [7:0] led_green; +wire [1:0] led_bmc; +wire [1:0] led_exp; +wire [63:0] qsfp_0_txd_0; +wire [7:0] qsfp_0_txc_0; +wire [63:0] qsfp_0_txd_1; +wire [7:0] qsfp_0_txc_1; +wire [63:0] qsfp_0_txd_2; +wire [7:0] qsfp_0_txc_2; +wire [63:0] qsfp_0_txd_3; +wire [7:0] qsfp_0_txc_3; +wire [63:0] qsfp_1_txd_0; +wire [7:0] qsfp_1_txc_0; +wire [63:0] qsfp_1_txd_1; +wire [7:0] qsfp_1_txc_1; +wire [63:0] qsfp_1_txd_2; +wire [7:0] qsfp_1_txc_2; +wire [63:0] qsfp_1_txd_3; +wire [7:0] qsfp_1_txc_3; + +initial begin + // myhdl integration + $from_myhdl( + clk, + rst, + current_test, + qsfp_0_tx_clk_0, + qsfp_0_tx_rst_0, + qsfp_0_rx_clk_0, + qsfp_0_rx_rst_0, + qsfp_0_rxd_0, + qsfp_0_rxc_0, + qsfp_0_tx_clk_1, + qsfp_0_tx_rst_1, + qsfp_0_rx_clk_1, + qsfp_0_rx_rst_1, + qsfp_0_rxd_1, + qsfp_0_rxc_1, + qsfp_0_tx_clk_2, + qsfp_0_tx_rst_2, + qsfp_0_rx_clk_2, + qsfp_0_rx_rst_2, + qsfp_0_rxd_2, + qsfp_0_rxc_2, + qsfp_0_tx_clk_3, + qsfp_0_tx_rst_3, + qsfp_0_rx_clk_3, + qsfp_0_rx_rst_3, + qsfp_0_rxd_3, + qsfp_0_rxc_3, + qsfp_1_tx_clk_0, + qsfp_1_tx_rst_0, + qsfp_1_rx_clk_0, + qsfp_1_rx_rst_0, + qsfp_1_rxd_0, + qsfp_1_rxc_0, + qsfp_1_tx_clk_1, + qsfp_1_tx_rst_1, + qsfp_1_rx_clk_1, + qsfp_1_rx_rst_1, + qsfp_1_rxd_1, + qsfp_1_rxc_1, + qsfp_1_tx_clk_2, + qsfp_1_tx_rst_2, + qsfp_1_rx_clk_2, + qsfp_1_rx_rst_2, + qsfp_1_rxd_2, + qsfp_1_rxc_2, + qsfp_1_tx_clk_3, + qsfp_1_tx_rst_3, + qsfp_1_rx_clk_3, + qsfp_1_rx_rst_3, + qsfp_1_rxd_3, + qsfp_1_rxc_3 + ); + $to_myhdl( + led_red, + led_green, + led_bmc, + led_exp, + qsfp_0_txd_0, + qsfp_0_txc_0, + qsfp_0_txd_1, + qsfp_0_txc_1, + qsfp_0_txd_2, + qsfp_0_txc_2, + qsfp_0_txd_3, + qsfp_0_txc_3, + qsfp_1_txd_0, + qsfp_1_txc_0, + qsfp_1_txd_1, + qsfp_1_txc_1, + qsfp_1_txd_2, + qsfp_1_txc_2, + qsfp_1_txd_3, + qsfp_1_txc_3 + ); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .led_red(led_red), + .led_green(led_green), + .led_bmc(led_bmc), + .led_exp(led_exp), + .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), + .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), + .qsfp_0_txd_0(qsfp_0_txd_0), + .qsfp_0_txc_0(qsfp_0_txc_0), + .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), + .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), + .qsfp_0_rxd_0(qsfp_0_rxd_0), + .qsfp_0_rxc_0(qsfp_0_rxc_0), + .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), + .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), + .qsfp_0_txd_1(qsfp_0_txd_1), + .qsfp_0_txc_1(qsfp_0_txc_1), + .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), + .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), + .qsfp_0_rxd_1(qsfp_0_rxd_1), + .qsfp_0_rxc_1(qsfp_0_rxc_1), + .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), + .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), + .qsfp_0_txd_2(qsfp_0_txd_2), + .qsfp_0_txc_2(qsfp_0_txc_2), + .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), + .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), + .qsfp_0_rxd_2(qsfp_0_rxd_2), + .qsfp_0_rxc_2(qsfp_0_rxc_2), + .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), + .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), + .qsfp_0_txd_3(qsfp_0_txd_3), + .qsfp_0_txc_3(qsfp_0_txc_3), + .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), + .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), + .qsfp_0_rxd_3(qsfp_0_rxd_3), + .qsfp_0_rxc_3(qsfp_0_rxc_3), + .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), + .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), + .qsfp_1_txd_0(qsfp_1_txd_0), + .qsfp_1_txc_0(qsfp_1_txc_0), + .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), + .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), + .qsfp_1_rxd_0(qsfp_1_rxd_0), + .qsfp_1_rxc_0(qsfp_1_rxc_0), + .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), + .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), + .qsfp_1_txd_1(qsfp_1_txd_1), + .qsfp_1_txc_1(qsfp_1_txc_1), + .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), + .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), + .qsfp_1_rxd_1(qsfp_1_rxd_1), + .qsfp_1_rxc_1(qsfp_1_rxc_1), + .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), + .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), + .qsfp_1_txd_2(qsfp_1_txd_2), + .qsfp_1_txc_2(qsfp_1_txc_2), + .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), + .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), + .qsfp_1_rxd_2(qsfp_1_rxd_2), + .qsfp_1_rxc_2(qsfp_1_rxc_2), + .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), + .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), + .qsfp_1_txd_3(qsfp_1_txd_3), + .qsfp_1_txc_3(qsfp_1_txc_3), + .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), + .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), + .qsfp_1_rxd_3(qsfp_1_rxd_3), + .qsfp_1_rxc_3(qsfp_1_rxc_3) +); + +endmodule diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/udp_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/udp_ep.py new file mode 120000 index 000000000..073c5d3c6 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/lib/eth/example/fb2CG/fpga_10g/tb/xgmii_ep.py b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/xgmii_ep.py new file mode 120000 index 000000000..63b6d3567 --- /dev/null +++ b/fpga/lib/eth/example/fb2CG/fpga_10g/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file