diff --git a/example/HXT100G/fpga/Makefile b/example/HXT100G/fpga/Makefile new file mode 100644 index 00000000..9f8bd404 --- /dev/null +++ b/example/HXT100G/fpga/Makefile @@ -0,0 +1,25 @@ +# Targets +TARGETS:= + +# Subdirectories +SUBDIRS = coregen 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/example/HXT100G/fpga/README.md b/example/HXT100G/fpga/README.md new file mode 100644 index 00000000..9da6d1a3 --- /dev/null +++ b/example/HXT100G/fpga/README.md @@ -0,0 +1,25 @@ +# Verilog Ethernet HXT100G Example Design + +## Introduction + +This example design targets the HiTech Global HXT100G 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: XC6VHX565T-2FFG1923 +PHY: 10G BASE-R PHY IP core and internal GTH transceiver + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the HXT100G board with the Xilinx Impact software. +Then run netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. +Anyntext entered into netcat will be echoed back after pressing enter. + + diff --git a/example/HXT100G/fpga/common/xilinx.mk b/example/HXT100G/fpga/common/xilinx.mk new file mode 100644 index 00000000..f10a45f8 --- /dev/null +++ b/example/HXT100G/fpga/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/HXT100G/fpga/coregen/Makefile b/example/HXT100G/fpga/coregen/Makefile new file mode 100644 index 00000000..09ec2cdf --- /dev/null +++ b/example/HXT100G/fpga/coregen/Makefile @@ -0,0 +1,33 @@ +# Tools +COREGEN:=coregen +XAW2VERILOG:=xaw2verilog + +# Source +XCO:=ten_gig_eth_pcs_pma_v2_6.xco ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco +XAW:= + +# Targets +TARGETS += $(XCO:.xco=) +TARGETS += $(XAW:.xaw=) + +# Rules +.PHONY: all +all: $(TARGETS) + +.PHONY: clean +clean: + -rm -rf $(TARGETS) + +%: %.xco + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(COREGEN) -p coregen.cgp -b $(notdir $<) + mv $($@_TMP) $@ + +%: %.xaw + $(eval $@_TMP := $(shell mktemp -d)) + cp -a coregen.cgp $($@_TMP) + cp -a $< $($@_TMP) + cd $($@_TMP) && $(XAW2VERILOG) -st $(notdir $<) $(notdir $*) + mv $($@_TMP) $@ diff --git a/example/HXT100G/fpga/coregen/coregen.cgp b/example/HXT100G/fpga/coregen/coregen.cgp new file mode 100644 index 00000000..dbe49f4c --- /dev/null +++ b/example/HXT100G/fpga/coregen/coregen.cgp @@ -0,0 +1,22 @@ +# Date: Wed Apr 1 17:38:18 2015 + +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = ./tmp/ + +# CRC: 3d2f7d04 diff --git a/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco new file mode 100644 index 00000000..2d141c5b --- /dev/null +++ b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6.xco @@ -0,0 +1,53 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 17:39:05 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Ten_Gigabit_Ethernet_PCS/PMA_(10GBASE-R/KR) xilinx.com:ip:ten_gig_eth_pcs_pma:2.6 +# END Select +# BEGIN Parameters +CSET autonegotiation=false +CSET base_kr=BASE-R +CSET component_name=ten_gig_eth_pcs_pma_v2_6 +CSET fec=false +CSET ieee_1588=None +CSET mdio_management=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-10-08T14:58:05Z +# END Extra information +GENERATE +# CRC: d3dbdcf5 diff --git a/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco new file mode 100644 index 00000000..3c380f10 --- /dev/null +++ b/example/HXT100G/fpga/coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper.xco @@ -0,0 +1,185 @@ +############################################################## +# +# Xilinx Core Generator version 14.7 +# Date: Wed Apr 1 18:19:03 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:v6_gthwizard:1.11 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc6vhx565t +SET devicefamily = virtex6 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1923 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Virtex-6_FPGA_GTH_Transceiver_Wizard xilinx.com:ip:v6_gthwizard:1.11 +# END Select +# BEGIN Parameters +CSET component_name=ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper +CSET config_identical=true +CSET drp_clock=50.00 +CSET gth0_datapath_width=64 +CSET gth0_encoding=10GbE_64B/66B +CSET gth0_line_rate=10.3125 +CSET gth0_postcursor_emphasis=0 +CSET gth0_precursor_emphasis=0 +CSET gth0_protocol_file=10GBASE-R +CSET gth0_rxeqmix=1000 +CSET gth0_tx_swing=800 +CSET gth0_use_dfetrainctrl=false +CSET gth0_use_lat_msr=false +CSET gth0_use_port_powerdown=true +CSET gth0_use_port_rxbufreset=true +CSET gth0_use_port_rxcodeerr=true +CSET gth0_use_port_rxctrl=true +CSET gth0_use_port_rxdisperr=false +CSET gth0_use_port_rxencommadet=false +CSET gth0_use_port_rxpolarity=false +CSET gth0_use_port_rxpowerdown=true +CSET gth0_use_port_rxslip=false +CSET gth0_use_port_rxvalid=false +CSET gth0_use_port_txbufreset=true +CSET gth0_use_port_txctrl=true +CSET gth0_use_port_txpowerdown=true +CSET gth1_datapath_width=64 +CSET gth1_encoding=10GbE_64B/66B +CSET gth1_line_rate=10.3125 +CSET gth1_postcursor_emphasis=0 +CSET gth1_precursor_emphasis=0 +CSET gth1_protocol_file=10GBASE-R +CSET gth1_rxeqmix=1000 +CSET gth1_tx_swing=800 +CSET gth1_use_dfetrainctrl=false +CSET gth1_use_lat_msr=false +CSET gth1_use_port_powerdown=true +CSET gth1_use_port_rxbufreset=true +CSET gth1_use_port_rxcodeerr=true +CSET gth1_use_port_rxctrl=true +CSET gth1_use_port_rxdisperr=false +CSET gth1_use_port_rxencommadet=false +CSET gth1_use_port_rxpolarity=false +CSET gth1_use_port_rxpowerdown=true +CSET gth1_use_port_rxslip=false +CSET gth1_use_port_rxvalid=false +CSET gth1_use_port_txbufreset=true +CSET gth1_use_port_txctrl=true +CSET gth1_use_port_txpowerdown=true +CSET gth2_datapath_width=64 +CSET gth2_encoding=10GbE_64B/66B +CSET gth2_line_rate=10.3125 +CSET gth2_postcursor_emphasis=0 +CSET gth2_precursor_emphasis=0 +CSET gth2_protocol_file=10GBASE-R +CSET gth2_rxeqmix=1000 +CSET gth2_tx_swing=800 +CSET gth2_use_dfetrainctrl=false +CSET gth2_use_lat_msr=false +CSET gth2_use_port_powerdown=true +CSET gth2_use_port_rxbufreset=true +CSET gth2_use_port_rxcodeerr=true +CSET gth2_use_port_rxctrl=true +CSET gth2_use_port_rxdisperr=false +CSET gth2_use_port_rxencommadet=false +CSET gth2_use_port_rxpolarity=false +CSET gth2_use_port_rxpowerdown=true +CSET gth2_use_port_rxslip=false +CSET gth2_use_port_rxvalid=false +CSET gth2_use_port_txbufreset=true +CSET gth2_use_port_txctrl=true +CSET gth2_use_port_txpowerdown=true +CSET gth3_datapath_width=64 +CSET gth3_encoding=10GbE_64B/66B +CSET gth3_line_rate=10.3125 +CSET gth3_postcursor_emphasis=0 +CSET gth3_precursor_emphasis=0 +CSET gth3_protocol_file=10GBASE-R +CSET gth3_rxeqmix=1000 +CSET gth3_tx_swing=800 +CSET gth3_use_dfetrainctrl=false +CSET gth3_use_lat_msr=false +CSET gth3_use_port_powerdown=true +CSET gth3_use_port_rxbufreset=true +CSET gth3_use_port_rxcodeerr=true +CSET gth3_use_port_rxctrl=true +CSET gth3_use_port_rxdisperr=false +CSET gth3_use_port_rxencommadet=false +CSET gth3_use_port_rxpolarity=false +CSET gth3_use_port_rxpowerdown=true +CSET gth3_use_port_rxslip=false +CSET gth3_use_port_rxvalid=false +CSET gth3_use_port_txbufreset=true +CSET gth3_use_port_txctrl=true +CSET gth3_use_port_txpowerdown=true +CSET gth_column=Right_Column_(X1) +CSET gthx4lane=false +CSET protocol_template=10GBASE-R +CSET refclk_x0y0=CLK_Y0 +CSET refclk_x0y1=CLK_Y1 +CSET refclk_x0y2=CLK_Y2 +CSET refclk_x1y0=CLK_Y0 +CSET refclk_x1y1=CLK_Y1 +CSET refclk_x1y2=CLK_Y2 +CSET reference_clock=156.25 +CSET target_line_rate=10.3125 +CSET use_gth0_x0y0=true +CSET use_gth0_x0y1=true +CSET use_gth0_x0y2=true +CSET use_gth0_x1y0=true +CSET use_gth0_x1y1=true +CSET use_gth0_x1y2=true +CSET use_gth1_x0y0=true +CSET use_gth1_x0y1=true +CSET use_gth1_x0y2=true +CSET use_gth1_x1y0=true +CSET use_gth1_x1y1=true +CSET use_gth1_x1y2=true +CSET use_gth2_x0y0=true +CSET use_gth2_x0y1=true +CSET use_gth2_x0y2=true +CSET use_gth2_x1y0=true +CSET use_gth2_x1y1=true +CSET use_gth2_x1y2=true +CSET use_gth3_x0y0=true +CSET use_gth3_x0y1=true +CSET use_gth3_x0y2=true +CSET use_gth3_x1y0=true +CSET use_gth3_x1y1=true +CSET use_gth3_x1y2=true +CSET use_gth_quad_x0y0=false +CSET use_gth_quad_x0y1=false +CSET use_gth_quad_x0y2=false +CSET use_gth_quad_x1y0=true +CSET use_gth_quad_x1y1=false +CSET use_gth_quad_x1y2=false +CSET use_no_rx=false +CSET use_no_tx=false +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-04-05T17:48:34Z +# END Extra information +GENERATE +# CRC: 75800c49 diff --git a/example/HXT100G/fpga/fpga.ucf b/example/HXT100G/fpga/fpga.ucf new file mode 100644 index 00000000..784dcb36 --- /dev/null +++ b/example/HXT100G/fpga/fpga.ucf @@ -0,0 +1,269 @@ +# User Constraints File for the HTG-V6HXT-100GIG FPGA board + +CONFIG PART = xc6vhx565t-2ff1923; + +# 50 MHz clock +NET "sys_clk" LOC = "AP33" | IOSTANDARD=LVCMOS25; # SYS_CLK, 50MHz +NET "sys_clk" TNM_NET = "sys_clk"; +TIMESPEC "TS_sys_clk" = PERIOD "sys_clk" 20.000 ns HIGH 50% INPUT_JITTER 200.0ps; + +# 156.25 MHz transceiver clock +NET "*txclk156" TNM_NET = "txclk156"; +TIMESPEC "TS_txclk156" = PERIOD "txclk156" 6400 ps; + +NET "*rx_clk_0" TNM_NET = "rx_clk"; +NET "*rx_clk_1" TNM_NET = "rx_clk"; +NET "*rx_clk_2" TNM_NET = "rx_clk"; +NET "*rx_clk_3" TNM_NET = "rx_clk"; +TIMESPEC "TS_rx_clk" = PERIOD "rx_clk" 6400 ps; + +# clock crossing constraints +TIMESPEC "TS_txclk156_to_sys_clk" = FROM "txclk156" TO "sys_clk" 10 ns; +TIMESPEC "TS_sys_clk_to_txclk156" = FROM "sys_clk" TO "txclk156" 10 ns; +TIMESPEC "TS_sys_clk_to_rx_clk" = FROM "sys_clk" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_sys_clk" = FROM "rx_clk" TO "sys_clk" 10 ns; + +# PHY elastic buffer constraints +NET "*elastic_buffer_i*rd_truegray" MAXDELAY = 6.0 ns; +NET "*elastic_buffer_i?can_insert_wra" TIG; +NET "*wr_gray*" MAXDELAY = 6.0 ns; +NET "*rd_lastgray*" MAXDELAY = 6.0 ns; + +TIMESPEC "TS_txclk156_to_rx_clk" = FROM "txclk156" TO "rx_clk" 10 ns; +TIMESPEC "TS_rx_clk_to_txclk156" = FROM "rx_clk" TO "txclk156" 10 ns; + +# 200 MHz DDR3 clock +#NET "clk_ddr3_p" LOC = "AL13" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_n" LOC = "AL12" | IOSTANDARD=LVDS_25; +#NET "clk_ddr3_p" TNM_NET = "clk_ddr3"; +#TIMESPEC "TS_clk_ddr3" = PERIOD "clk_ddr3" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# User clock +#NET "clk_usr_p" LOC = "J33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_n" LOC = "H33" | IOSTANDARD=LVDS_25; +#NET "clk_usr_p" TNM_NET = "clk_usr"; +#TIMESPEC "TS_clk_usr" = PERIOD "clk_usr" 5.000 ns HIGH 50% INPUT_JITTER 20.0ps; + +# Button +NET "reset_n" LOC = "AY12" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (S7) + +# DIP switches +NET "sw<0>" LOC = "BB32" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW0) +NET "sw<1>" LOC = "AT30" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (USER_SW1) + +# Jumpers +NET "jp<0>" LOC = "AW34" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO0, JP18) +NET "jp<1>" LOC = "AY35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO1, JP19) +NET "jp<2>" LOC = "AW35" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO2, JP20) +NET "jp<3>" LOC = "AV33" | IOSTANDARD=LVCMOS25; # IO_L1N_M0_CMPMISO_2 (IO3, JP21) + +# LEDs +NET "led<0>" LOC = "AY33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D20) +NET "led<1>" LOC = "AW33" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D23) +NET "led<2>" LOC = "AK35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D26) +NET "led<3>" LOC = "AL35" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (D31) + +# Silicon Labs CP2102 +NET "uart_rst" LOC = "D10" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_suspend" LOC = "E12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_ri" LOC = "B12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dcd" LOC = "C11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dtr" LOC = "B11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_dsr" LOC = "D11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_rxd" LOC = "E11" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66N_SCP0 +NET "uart_txd" LOC = "B9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # IO_L66P_SCP1 +NET "uart_rts" LOC = "A9" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # +NET "uart_cts" LOC = "F12" | IOSTANDARD=LVCMOS25 | SLEW=SLOW | DRIVE=2; # + +# Clock muxes +NET "clk_gth_scl" LOC = "M11"; +NET "clk_gth_sda" LOC = "L10"; +NET "clk_gth_rst_n" LOC = "AR7"; +NET "clk_gthl_alm" LOC = "M34"; +NET "clk_gthr_alm" LOC = "R13"; +NET "clk_gthl_lol" LOC = "L34"; +NET "clk_gthr_lol" LOC = "L12"; + +# AirMax I/O +#NET "amh_right_io<0>" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +#NET "amh_right_io<1>" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +#NET "amh_right_io<2>" LOC="F34"; # AMH1R_IO2 J6.TX[13]_P +#NET "amh_right_io<3>" LOC="G34"; # AMH1R_IO3 J6.TX[13]_N +#NET "amh_right_io<4>" LOC="K33"; # AMH1R_IO4 J6.TX[14]_P +#NET "amh_right_io<5>" LOC="L33"; # AMH1R_IO5 J6.TX[14]_N +#NET "amh_right_io<6>" LOC="N34"; # AMH1R_IO6 J6.TX[15]_P +#NET "amh_right_io<7>" LOC="H34"; # AMH1R_IO7 J6.TX[15]_N reset_n + +#NET "amh_left_io<0>" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +#NET "amh_left_io<1>" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +#NET "amh_left_io<2>" LOC="A35"; # AMH1L_IO2 J3.TX[13]_P +#NET "amh_left_io<3>" LOC="B35"; # AMH1L_IO3 J3.TX[13]_N +#NET "amh_left_io<4>" LOC="G35"; # AMH1L_IO4 J3.TX[14]_P +#NET "amh_left_io<5>" LOC="F35"; # AMH1L_IO5 J3.TX[14]_N +#NET "amh_left_io<6>" LOC="A37"; # AMH1L_IO6 J3.TX[15]_P +#NET "amh_left_io<7>" LOC="B36"; # AMH1L_IO7 J3.TX[15]_N reset_n + +NET "amh_right_mdc" LOC="N33"; # AMH1R_IO0 J6.TX[12]_P mdc +NET "amh_right_mdio" LOC="J34"; # AMH1R_IO1 J6.TX[12]_N mdio +NET "amh_right_phy_rst_n" LOC="H34" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +NET "amh_left_mdc" LOC="E35"; # AMH1L_IO0 J3.TX[12]_P mdc +NET "amh_left_mdio" LOC="B37"; # AMH1L_IO1 J3.TX[12]_N mdio +NET "amh_left_phy_rst_n" LOC="B36" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; + +# 10G Ethernet interfaces +# Quad A X0Y0 +# Ports 11, 9, 10, 8 (right) +# SFP 0, 2, 4, 6 +NET "gth_quad_A_refclk_p" LOC = "R41"; +NET "gth_quad_A_refclk_n" LOC = "R42"; + +NET "gth_quad_A_txp_0" LOC = "T43"; +NET "gth_quad_A_txn_0" LOC = "T44"; +NET "gth_quad_A_rxp_0" LOC = "U41"; +NET "gth_quad_A_rxn_0" LOC = "U42"; + +NET "gth_quad_A_txp_1" LOC = "P43"; +NET "gth_quad_A_txn_1" LOC = "P44"; +NET "gth_quad_A_rxp_1" LOC = "T39"; +NET "gth_quad_A_rxn_1" LOC = "T40"; + +NET "gth_quad_A_txp_2" LOC = "M43"; +NET "gth_quad_A_txn_2" LOC = "M44"; +NET "gth_quad_A_rxp_2" LOC = "N37"; +NET "gth_quad_A_rxn_2" LOC = "N38"; + +NET "gth_quad_A_txp_3" LOC = "N41"; +NET "gth_quad_A_txn_3" LOC = "N42"; +NET "gth_quad_A_rxp_3" LOC = "M39"; +NET "gth_quad_A_rxn_3" LOC = "M40"; + +# Quad B X0Y1 +# Ports 4, 6, 5, 7 (right) +# SFP 3, 5, 1, 7 +NET "gth_quad_B_refclk_p" LOC = "J41"; +NET "gth_quad_B_refclk_n" LOC = "J42"; + +NET "gth_quad_B_txp_0" LOC = "L41"; +NET "gth_quad_B_txn_0" LOC = "L42"; +NET "gth_quad_B_rxp_0" LOC = "K39"; +NET "gth_quad_B_rxn_0" LOC = "K40"; + +NET "gth_quad_B_txp_1" LOC = "K43"; +NET "gth_quad_B_txn_1" LOC = "K44"; +NET "gth_quad_B_rxp_1" LOC = "L37"; +NET "gth_quad_B_rxn_1" LOC = "L38"; + +NET "gth_quad_B_txp_2" LOC = "G41"; +NET "gth_quad_B_txn_2" LOC = "G42"; +NET "gth_quad_B_rxp_2" LOC = "H39"; +NET "gth_quad_B_rxn_2" LOC = "H40"; + +NET "gth_quad_B_txp_3" LOC = "H43"; +NET "gth_quad_B_txn_3" LOC = "H44"; +NET "gth_quad_B_rxp_3" LOC = "J37"; +NET "gth_quad_B_rxn_3" LOC = "J38"; + +# Quad C X0Y2 +# Ports 1, 0, 3, 2 (right) +# SFP 8, 9, 11, 10 +NET "gth_quad_C_refclk_p" LOC = "E41"; +NET "gth_quad_C_refclk_n" LOC = "E42"; + +NET "gth_quad_C_txp_0" LOC = "F43"; +NET "gth_quad_C_txn_0" LOC = "F44"; +NET "gth_quad_C_rxp_0" LOC = "G37"; +NET "gth_quad_C_rxn_0" LOC = "G38"; + +NET "gth_quad_C_txp_1" LOC = "D43"; +NET "gth_quad_C_txn_1" LOC = "D44"; +NET "gth_quad_C_rxp_1" LOC = "F39"; +NET "gth_quad_C_rxn_1" LOC = "F40"; + +NET "gth_quad_C_txp_2" LOC = "A41"; +NET "gth_quad_C_txn_2" LOC = "A42"; +NET "gth_quad_C_rxp_2" LOC = "B39"; +NET "gth_quad_C_rxn_2" LOC = "B40"; + +NET "gth_quad_C_txp_3" LOC = "C41"; +NET "gth_quad_C_txn_3" LOC = "C42"; +NET "gth_quad_C_rxp_3" LOC = "D39"; +NET "gth_quad_C_rxn_3" LOC = "D40"; + +# Quad D X1Y0 +# Ports 11, 9, 10, 8 (left) +# SFP 0, 2, 4, 6 +NET "gth_quad_D_refclk_p" LOC = "R4"; +NET "gth_quad_D_refclk_n" LOC = "R3"; + +NET "gth_quad_D_txp_0" LOC = "T2"; +NET "gth_quad_D_txn_0" LOC = "T1"; +NET "gth_quad_D_rxp_0" LOC = "U4"; +NET "gth_quad_D_rxn_0" LOC = "U3"; + +NET "gth_quad_D_txp_1" LOC = "P2"; +NET "gth_quad_D_txn_1" LOC = "P1"; +NET "gth_quad_D_rxp_1" LOC = "T6"; +NET "gth_quad_D_rxn_1" LOC = "T5"; + +NET "gth_quad_D_txp_2" LOC = "M2"; +NET "gth_quad_D_txn_2" LOC = "M1"; +NET "gth_quad_D_rxp_2" LOC = "N8"; +NET "gth_quad_D_rxn_2" LOC = "N7"; + +NET "gth_quad_D_txp_3" LOC = "N4"; +NET "gth_quad_D_txn_3" LOC = "N3"; +NET "gth_quad_D_rxp_3" LOC = "M6"; +NET "gth_quad_D_rxn_3" LOC = "M5"; + +# Quad E X1Y1 +# Ports 4, 6, 5, 7 (left) +# SFP 3, 5, 1, 7 +NET "gth_quad_E_refclk_p" LOC = "J4"; +NET "gth_quad_E_refclk_n" LOC = "J3"; + +NET "gth_quad_E_txp_0" LOC = "L4"; +NET "gth_quad_E_txn_0" LOC = "L3"; +NET "gth_quad_E_rxp_0" LOC = "K6"; +NET "gth_quad_E_rxn_0" LOC = "K5"; + +NET "gth_quad_E_txp_1" LOC = "K2"; +NET "gth_quad_E_txn_1" LOC = "K1"; +NET "gth_quad_E_rxp_1" LOC = "L8"; +NET "gth_quad_E_rxn_1" LOC = "L7"; + +NET "gth_quad_E_txp_2" LOC = "G4"; +NET "gth_quad_E_txn_2" LOC = "G3"; +NET "gth_quad_E_rxp_2" LOC = "H6"; +NET "gth_quad_E_rxn_2" LOC = "H5"; + +NET "gth_quad_E_txp_3" LOC = "H2"; +NET "gth_quad_E_txn_3" LOC = "H1"; +NET "gth_quad_E_rxp_3" LOC = "J8"; +NET "gth_quad_E_rxn_3" LOC = "J7"; + +# Quad F X1Y2 +# Ports 1, 0, 3, 2 (left) +# SFP 8, 9, 11, 10 +NET "gth_quad_F_refclk_p" LOC = "E4"; +NET "gth_quad_F_refclk_n" LOC = "E3"; + +NET "gth_quad_F_txp_0" LOC = "F2"; +NET "gth_quad_F_txn_0" LOC = "F1"; +NET "gth_quad_F_rxp_0" LOC = "G8"; +NET "gth_quad_F_rxn_0" LOC = "G7"; + +NET "gth_quad_F_txp_1" LOC = "D2"; +NET "gth_quad_F_txn_1" LOC = "D1"; +NET "gth_quad_F_rxp_1" LOC = "F6"; +NET "gth_quad_F_rxn_1" LOC = "F5"; + +NET "gth_quad_F_txp_2" LOC = "A4"; +NET "gth_quad_F_txn_2" LOC = "A3"; +NET "gth_quad_F_rxp_2" LOC = "B6"; +NET "gth_quad_F_rxn_2" LOC = "B5"; + +NET "gth_quad_F_txp_3" LOC = "C4"; +NET "gth_quad_F_txn_3" LOC = "C3"; +NET "gth_quad_F_rxp_3" LOC = "D6"; +NET "gth_quad_F_rxn_3" LOC = "D5"; diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile new file mode 100644 index 00000000..838b74de --- /dev/null +++ b/example/HXT100G/fpga/fpga/Makefile @@ -0,0 +1,93 @@ + +# FPGA settings +FPGA_PART = xc6vhx565t-2ff1923 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/debounce_switch.v +SYN_FILES += rtl/sync_reset.v +SYN_FILES += rtl/sync_signal.v +SYN_FILES += rtl/i2c_master.v +SYN_FILES += rtl/gth_i2c_init.v +SYN_FILES += rtl/eth_gth_phy_quad.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/eth_mac_10g_rx.v +SYN_FILES += lib/eth/rtl/eth_mac_10g_tx.v +SYN_FILES += lib/eth/rtl/eth_crc_8.v +SYN_FILES += lib/eth/rtl/eth_crc_16.v +SYN_FILES += lib/eth/rtl/eth_crc_24.v +SYN_FILES += lib/eth/rtl/eth_crc_32.v +SYN_FILES += lib/eth/rtl/eth_crc_40.v +SYN_FILES += lib/eth/rtl/eth_crc_48.v +SYN_FILES += lib/eth/rtl/eth_crc_56.v +SYN_FILES += lib/eth/rtl/eth_crc_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/udp_complete_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_64_2.v +SYN_FILES += lib/eth/rtl/ip_mux_64_2.v +SYN_FILES += lib/eth/rtl/arp_64.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx_64.v +SYN_FILES += lib/eth/rtl/arp_eth_tx_64.v +SYN_FILES += lib/eth/rtl/eth_arb_mux_64_2.v +SYN_FILES += lib/eth/rtl/eth_mux_64_2.v +SYN_FILES += lib/eth/rtl/xgmii_interleave.v +SYN_FILES += lib/eth/rtl/xgmii_deinterleave.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_64.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6/ten_gig_eth_pcs_pma_v2_6/example_design/ten_gig_eth_pcs_pma_v2_6_management_arbiter.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_quad.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_init.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_tx_pcs_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_gth_rx_pcs_cdr_reset.v +SYN_FILES += coregen/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper/ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_pulse_synchronizer.v + +# UCF files +UCF_FILES = fpga.ucf + +# NGC paths for ngdbuild +NGC_PATHS = coregen/ten_gig_eth_pcs_pma_v2_6 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 1" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + +program_flash: $(FPGA_TOP).mcs + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).mcs" >> program.cmd + echo "program -p 1 -e" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/HXT100G/fpga/lib/eth b/example/HXT100G/fpga/lib/eth new file mode 120000 index 00000000..11a54ed3 --- /dev/null +++ b/example/HXT100G/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/HXT100G/fpga/rtl/debounce_switch.v b/example/HXT100G/fpga/rtl/debounce_switch.v new file mode 100644 index 00000000..e820eb41 --- /dev/null +++ b/example/HXT100G/fpga/rtl/debounce_switch.v @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2014-2016 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) 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/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v new file mode 100644 index 00000000..be42ab25 --- /dev/null +++ b/example/HXT100G/fpga/rtl/eth_gth_phy_quad.v @@ -0,0 +1,567 @@ +/* + +Copyright (c) 2015-2016 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. + +*/ + +module eth_gth_phy_quad ( + /* + * Clock and reset + */ + input wire clk156, + input wire rst156, + input wire dclk, + input wire dclk_reset, + + output wire txclk156, + + input wire gth_reset, + output wire gth_reset_done, + + /* + * Transciever pins + */ + input wire refclk_p, + input wire refclk_n, + output wire txp_0, + output wire txn_0, + input wire rxp_0, + input wire rxn_0, + output wire txp_1, + output wire txn_1, + input wire rxp_1, + input wire rxn_1, + output wire txp_2, + output wire txn_2, + input wire rxp_2, + input wire rxn_2, + output wire txp_3, + output wire txn_3, + input wire rxp_3, + input wire rxn_3, + + /* + * XGMII interfaces + */ + input wire [63:0] xgmii_txd_0, + input wire [7:0] xgmii_txc_0, + output wire [63:0] xgmii_rxd_0, + output wire [7:0] xgmii_rxc_0, + input wire [63:0] xgmii_txd_1, + input wire [7:0] xgmii_txc_1, + output wire [63:0] xgmii_rxd_1, + output wire [7:0] xgmii_rxc_1, + input wire [63:0] xgmii_txd_2, + input wire [7:0] xgmii_txc_2, + output wire [63:0] xgmii_rxd_2, + output wire [7:0] xgmii_rxc_2, + input wire [63:0] xgmii_txd_3, + input wire [7:0] xgmii_txc_3, + output wire [63:0] xgmii_rxd_3, + output wire [7:0] xgmii_rxc_3, + + /* + * Control + */ + input wire tx_powerdown_0, + input wire rx_powerdown_0, + input wire tx_powerdown_1, + input wire rx_powerdown_1, + input wire tx_powerdown_2, + input wire rx_powerdown_2, + input wire tx_powerdown_3, + input wire rx_powerdown_3 +); + +wire [63:0] gth_txd_0; +wire [7:0] gth_txc_0; +wire [63:0] gth_rxd_0; +wire [7:0] gth_rxc_0; +wire [63:0] gth_txd_1; +wire [7:0] gth_txc_1; +wire [63:0] gth_rxd_1; +wire [7:0] gth_rxc_1; +wire [63:0] gth_txd_2; +wire [7:0] gth_txc_2; +wire [63:0] gth_rxd_2; +wire [7:0] gth_rxc_2; +wire [63:0] gth_txd_3; +wire [7:0] gth_txc_3; +wire [63:0] gth_rxd_3; +wire [7:0] gth_rxc_3; + +wire mgmt_rd; +wire mgmt_wr; +wire mgmt_rdack; +wire [20:0] mgmt_addr; +wire [15:0] mgmt_rddata; +wire [15:0] mgmt_wrdata; + +wire mgmt_rd0; +wire mgmt_wr0; +wire [20:0] mgmt_addr0; +wire [15:0] mgmt_wrdata0; + +wire mgmt_req0; +wire mgmt_gnt0; + +wire mgmt_rd1; +wire mgmt_wr1; +wire [20:0] mgmt_addr1; +wire [15:0] mgmt_wrdata1; + +wire mgmt_req1; +wire mgmt_gnt1; + +wire mgmt_rd2; +wire mgmt_wr2; +wire [20:0] mgmt_addr2; +wire [15:0] mgmt_wrdata2; + +wire mgmt_req2; +wire mgmt_gnt2; + +wire mgmt_rd3; +wire mgmt_wr3; +wire [20:0] mgmt_addr3; +wire [15:0] mgmt_wrdata3; + +wire mgmt_req3; +wire mgmt_gnt3; + +// clocking +wire refclk; + +IBUFDS_GTHE1 refclk_ibufds_inst +( + .I(refclk_p), + .IB(refclk_n), + .O(refclk) +); + +wire rx_clk_0; +wire rx_clk_0_buf; +wire rx_clk_1; +wire rx_clk_1_buf; +wire rx_clk_2; +wire rx_clk_2_buf; +wire rx_clk_3; +wire rx_clk_3_buf; + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_0_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_0), + .O(rx_clk_0_buf) +); + +BUFR #( + .SIM_DEVICE("VIRTEX6") +) +rx_clk_1_buf_inst +( + .CE(1'b1), + .CLR(1'b0), + .I(rx_clk_1), + .O(rx_clk_1_buf) +); + +BUFG rx_clk_2_buf_inst +( + .I(rx_clk_2), + .O(rx_clk_2_buf) +); + +BUFG rx_clk_3_buf_inst +( + .I(rx_clk_3), + .O(rx_clk_3_buf) +); + +wire tx_resetdone_0; +wire rx_resetdone_0; +wire tx_resetdone_1; +wire rx_resetdone_1; +wire tx_resetdone_2; +wire rx_resetdone_2; +wire tx_resetdone_3; +wire rx_resetdone_3; + +wire resetdone_0 = tx_resetdone_0 & rx_resetdone_0; +wire resetdone_1 = tx_resetdone_1 & rx_resetdone_1; +wire resetdone_2 = tx_resetdone_2 & rx_resetdone_2; +wire resetdone_3 = tx_resetdone_3 & rx_resetdone_3; + +reg gth_reset_done_reg = 0; + +assign gth_reset_done = gth_reset_done_reg; + +// register overall reset done output +always @(posedge clk156) begin + gth_reset_done_reg <= resetdone_0 & resetdone_1 & resetdone_2 & resetdone_3; +end + +wire disable_drp = gth_reset_done & disable_drp_mgmt; + +wire lane_sel = {mgmt_gnt3, mgmt_gnt2, mgmt_gnt1, mgmt_gnt0}; + +// GTH quad wrapper +ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_QUAD # +( + // Simulation attributes + .QUAD_SIM_GTHRESET_SPEEDUP(0) +) +gth_inst +( + //------------------------------- Resetdone -------------------------------- + .TX_PCS_RESETDONE0_OUT (tx_resetdone_0), + .RX_PCS_CDR_RESETDONE0_OUT (rx_resetdone_0), + .TX_PCS_RESETDONE1_OUT (tx_resetdone_1), + .RX_PCS_CDR_RESETDONE1_OUT (rx_resetdone_1), + .TX_PCS_RESETDONE2_OUT (tx_resetdone_2), + .RX_PCS_CDR_RESETDONE2_OUT (rx_resetdone_2), + .TX_PCS_RESETDONE3_OUT (tx_resetdone_3), + .RX_PCS_CDR_RESETDONE3_OUT (rx_resetdone_3), + //------------------------------- Initdone --------------------------------- + .GTHINITDONE_OUT (), + //------------------------------- PCS Resets ------------------------------- + .TX_PCS_RESET0_IN (1'b0), + .RX_PCS_CDR_RESET0_IN (1'b0), + .TX_PCS_RESET1_IN (1'b0), + .RX_PCS_CDR_RESET1_IN (1'b0), + .TX_PCS_RESET2_IN (1'b0), + .RX_PCS_CDR_RESET2_IN (1'b0), + .TX_PCS_RESET3_IN (1'b0), + .RX_PCS_CDR_RESET3_IN (1'b0), + //------------------------------- Powerdown -------------------------------- + .POWERDOWN0_IN (1'b0), + .POWERDOWN1_IN (1'b0), + .POWERDOWN2_IN (1'b0), + .POWERDOWN3_IN (1'b0), + .RXPOWERDOWN0_IN ({rx_powerdown_0 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN1_IN ({rx_powerdown_1 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN2_IN ({rx_powerdown_2 | (~gth_reset_done), 1'b0}), + .RXPOWERDOWN3_IN ({rx_powerdown_3 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN0_IN ({tx_powerdown_0 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN1_IN ({tx_powerdown_1 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN2_IN ({tx_powerdown_2 | (~gth_reset_done), 1'b0}), + .TXPOWERDOWN3_IN ({tx_powerdown_3 | (~gth_reset_done), 1'b0}), + //----------------------------- Receive Ports ------------------------------ + .RXBUFRESET0_IN (1'b0), + .RXBUFRESET1_IN (1'b0), + .RXBUFRESET2_IN (1'b0), + .RXBUFRESET3_IN (1'b0), + .RXCODEERR0_OUT (), + .RXCODEERR1_OUT (), + .RXCODEERR2_OUT (), + .RXCODEERR3_OUT (), + .RXCTRL0_OUT (gth_rxc_0), + .RXCTRL1_OUT (gth_rxc_1), + .RXCTRL2_OUT (gth_rxc_2), + .RXCTRL3_OUT (gth_rxc_3), + .RXCTRLACK0_OUT (), + .RXCTRLACK1_OUT (), + .RXCTRLACK2_OUT (), + .RXCTRLACK3_OUT (), + .RXDATA0_OUT (gth_rxd_0), + .RXDATA1_OUT (gth_rxd_1), + .RXDATA2_OUT (gth_rxd_2), + .RXDATA3_OUT (gth_rxd_3), + .RXN0_IN (rxn_0), + .RXN1_IN (rxn_1), + .RXN2_IN (rxn_2), + .RXN3_IN (rxn_3), + .RXP0_IN (rxp_0), + .RXP1_IN (rxp_1), + .RXP2_IN (rxp_2), + .RXP3_IN (rxp_3), + .RXUSERCLKIN0_IN (rx_clk_0_buf), + .RXUSERCLKIN1_IN (rx_clk_1_buf), + .RXUSERCLKIN2_IN (rx_clk_2_buf), + .RXUSERCLKIN3_IN (rx_clk_3_buf), + .RXUSERCLKOUT0_OUT (rx_clk_0), + .RXUSERCLKOUT1_OUT (rx_clk_1), + .RXUSERCLKOUT2_OUT (rx_clk_2), + .RXUSERCLKOUT3_OUT (rx_clk_3), + //----------- Shared Ports - Dynamic Reconfiguration Port () ------------ + .DADDR_IN (16'h0000), + .DCLK_IN (dclk), + .DEN_IN (1'b0), + .DI_IN (16'h0000), + .DISABLEDRP_IN (disable_drp), + .DRDY_OUT (), + .DRPDO_OUT (), + .DWE_IN (1'b0), + //-------------------------- Shared Ports - Other -------------------------- + .TSTREFCLKFAB_OUT (), + .TSTREFCLKOUT_OUT (), + .GTHINIT_IN (1'b0), + .GTHRESET_IN (gth_reset), + .MGMTPCSLANESEL_IN (lane_sel), + .MGMTPCSMMDADDR_IN (mgmt_addr[20:16]), + .MGMTPCSRDACK_OUT (mgmt_rdack), + .MGMTPCSRDDATA_OUT (mgmt_rddata), + .MGMTPCSREGADDR_IN (mgmt_addr[15:0]), + .MGMTPCSREGRD_IN (mgmt_rd), + .MGMTPCSREGWR_IN (mgmt_wr), + .MGMTPCSWRDATA_IN (mgmt_wrdata), + .REFCLK_IN (refclk), + //----------------------------- Transmit Ports ----------------------------- + .TXBUFRESET0_IN (1'b0), + .TXBUFRESET1_IN (1'b0), + .TXBUFRESET2_IN (1'b0), + .TXBUFRESET3_IN (1'b0), + .TXCTRL0_IN (gth_txc_0), + .TXCTRL1_IN (gth_txc_1), + .TXCTRL2_IN (gth_txc_2), + .TXCTRL3_IN (gth_txc_3), + .TXCTRLACK0_OUT (), + .TXCTRLACK1_OUT (), + .TXCTRLACK2_OUT (), + .TXCTRLACK3_OUT (), + .TXDATA0_IN (gth_txd_0), + .TXDATA1_IN (gth_txd_1), + .TXDATA2_IN (gth_txd_2), + .TXDATA3_IN (gth_txd_3), + .TXN0_OUT (txn_0), + .TXN1_OUT (txn_1), + .TXN2_OUT (txn_2), + .TXN3_OUT (txn_3), + .TXP0_OUT (txp_0), + .TXP1_OUT (txp_1), + .TXP2_OUT (txp_2), + .TXP3_OUT (txp_3), + .TXUSERCLKIN0_IN (clk156), + .TXUSERCLKIN1_IN (clk156), + .TXUSERCLKIN2_IN (clk156), + .TXUSERCLKIN3_IN (clk156), + .TXUSERCLKOUT0_OUT (txclk156), + .TXUSERCLKOUT1_OUT (), + .TXUSERCLKOUT2_OUT (), + .TXUSERCLKOUT3_OUT () +); + +wire [535:0] configuration_vector; + +assign configuration_vector[14:1] = 0; +assign configuration_vector[79:17] = 0; +assign configuration_vector[109:84] = 0; +assign configuration_vector[175:170] = 0; +assign configuration_vector[239:234] = 0; +assign configuration_vector[269:246] = 0; +assign configuration_vector[511:272] = 0; +assign configuration_vector[515:513] = 0; +assign configuration_vector[517:517] = 0; +assign configuration_vector[0] = 0; // pma_loopback; +assign configuration_vector[15] = 0; // pma_reset; +assign configuration_vector[16] = 0; // global_tx_disable; +assign configuration_vector[83:80] = 0; // pma_vs_loopback; +assign configuration_vector[110] = 0; // pcs_loopback; +assign configuration_vector[111] = 0; // pcs_reset; +assign configuration_vector[169:112] = 0; // test_patt_a; +assign configuration_vector[233:176] = 0; // test_patt_b; +assign configuration_vector[240] = 0; // data_patt_sel; +assign configuration_vector[241] = 0; // test_patt_sel; +assign configuration_vector[242] = 0; // rx_test_patt_en; +assign configuration_vector[243] = 0; // tx_test_patt_en; +assign configuration_vector[244] = 0; // prbs31_tx_en; +assign configuration_vector[245] = 0; // prbs31_rx_en; +assign configuration_vector[271:270] = 0; // pcs_vs_loopback; +assign configuration_vector[512] = 0; // set_pma_link_status; +assign configuration_vector[516] = 0; // set_pcs_link_status; +assign configuration_vector[518] = 0; // clear_pcs_status2; +assign configuration_vector[519] = 0; // clear_test_patt_err_count; +assign configuration_vector[535:520] = 0; + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_0 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_0_buf), + .xgmii_txd(xgmii_txd_0), + .xgmii_txc(xgmii_txc_0), + .xgmii_rxd(xgmii_rxd_0), + .xgmii_rxc(xgmii_rxc_0), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req0), + .mgmt_gnt(mgmt_gnt0), + .mgmt_rd_out(mgmt_rd0), + .mgmt_wr_out(mgmt_wr0), + .mgmt_addr_out(mgmt_addr0), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata0), + .gt_txd(gth_txd_0), + .gt_txc(gth_txc_0), + .gt_rxd(gth_rxd_0), + .gt_rxc(gth_rxc_0), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_1 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_1_buf), + .xgmii_txd(xgmii_txd_1), + .xgmii_txc(xgmii_txc_1), + .xgmii_rxd(xgmii_rxd_1), + .xgmii_rxc(xgmii_rxc_1), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req1), + .mgmt_gnt(mgmt_gnt1), + .mgmt_rd_out(mgmt_rd1), + .mgmt_wr_out(mgmt_wr1), + .mgmt_addr_out(mgmt_addr1), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata1), + .gt_txd(gth_txd_1), + .gt_txc(gth_txc_1), + .gt_rxd(gth_rxd_1), + .gt_rxc(gth_rxc_1), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_2 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_2_buf), + .xgmii_txd(xgmii_txd_2), + .xgmii_txc(xgmii_txc_2), + .xgmii_rxd(xgmii_rxd_2), + .xgmii_rxc(xgmii_rxc_2), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req2), + .mgmt_gnt(mgmt_gnt2), + .mgmt_rd_out(mgmt_rd2), + .mgmt_wr_out(mgmt_wr2), + .mgmt_addr_out(mgmt_addr2), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata2), + .gt_txd(gth_txd_2), + .gt_txc(gth_txc_2), + .gt_rxd(gth_rxd_2), + .gt_rxc(gth_rxc_2), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6 +ten_gig_eth_pcs_pma_core_inst_3 +( + .reset(rst156), + .clk156(clk156), + .rxclk156(rx_clk_3_buf), + .xgmii_txd(xgmii_txd_3), + .xgmii_txc(xgmii_txc_3), + .xgmii_rxd(xgmii_rxd_3), + .xgmii_rxc(xgmii_rxc_3), + .configuration_vector(configuration_vector), + .status_vector(), + .dclk(dclk), + .mgmt_req(mgmt_req3), + .mgmt_gnt(mgmt_gnt3), + .mgmt_rd_out(mgmt_rd3), + .mgmt_wr_out(mgmt_wr3), + .mgmt_addr_out(mgmt_addr3), + .mgmt_rdack_in(mgmt_rdack), + .mgmt_rddata_in(mgmt_rddata), + .mgmt_wrdata_out(mgmt_wrdata3), + .gt_txd(gth_txd_3), + .gt_txc(gth_txc_3), + .gt_rxd(gth_rxd_3), + .gt_rxc(gth_rxc_3), + .signal_detect(1'b1), + .tx_fault(1'b0), + .tx_disable() +); + +ten_gig_eth_pcs_pma_v2_6_management_arbiter +mgmt_arb_inst +( + .dclk(dclk), + .reset(dclk_reset), + + .mgmt_rd0(mgmt_rd0), + .mgmt_wr0(mgmt_wr0), + .mgmt_addr0(mgmt_addr0), + .mgmt_wrdata0(mgmt_wrdata0), + + .mgmt_req0(mgmt_req0), + .mgmt_gnt0(mgmt_gnt0), + + .mgmt_rd1(mgmt_rd1), + .mgmt_wr1(mgmt_wr1), + .mgmt_addr1(mgmt_addr1), + .mgmt_wrdata1(mgmt_wrdata1), + + .mgmt_req1(mgmt_req1), + .mgmt_gnt1(mgmt_gnt1), + + .mgmt_rd2(mgmt_rd2), + .mgmt_wr2(mgmt_wr2), + .mgmt_addr2(mgmt_addr2), + .mgmt_wrdata2(mgmt_wrdata2), + + .mgmt_req2(mgmt_req2), + .mgmt_gnt2(mgmt_gnt2), + + .mgmt_rd3(mgmt_rd3), + .mgmt_wr3(mgmt_wr3), + .mgmt_addr3(mgmt_addr3), + .mgmt_wrdata3(mgmt_wrdata3), + + .mgmt_req3(mgmt_req3), + .mgmt_gnt3(mgmt_gnt3), + + .mgmt_rd(mgmt_rd), + .mgmt_wr(mgmt_wr), + .mgmt_addr(mgmt_addr), + .mgmt_wrdata(mgmt_wrdata), + + .drp_req(1'b0), + .drp_gnt(), + + .disable_drp(disable_drp_mgmt) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v new file mode 100644 index 00000000..159608c8 --- /dev/null +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -0,0 +1,1059 @@ +/* + +Copyright (c) 2016 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. + +*/ + +module fpga ( + /* + * Clock: 50MHz + */ + input wire sys_clk, + /* + * Clock: 200MHz + */ + //input wire clk_ddr3_p, + //input wire clk_ddr3_n, + /* + * Clock: User + */ + //input wire clk_usr_p, + //input wire clk_usr_pr_n, + /* + * Reset: Push button, active low + */ + input wire reset_n, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * Clock muxes + */ + inout wire clk_gth_scl, + inout wire clk_gth_sda, + output wire clk_gth_rst_n, + input wire clk_gthl_alm, + input wire clk_gthl_lol, + input wire clk_gthr_alm, + input wire clk_gthr_lol, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + inout wire amh_right_mdio, + output wire amh_right_phy_rst_n, + output wire amh_left_mdc, + inout wire amh_left_mdio, + output wire amh_left_phy_rst_n, + /* + * 10G Ethernet + */ + input wire gth_quad_A_refclk_p, + input wire gth_quad_A_refclk_n, + output wire gth_quad_A_txp_0, + output wire gth_quad_A_txn_0, + input wire gth_quad_A_rxp_0, + input wire gth_quad_A_rxn_0, + output wire gth_quad_A_txp_1, + output wire gth_quad_A_txn_1, + input wire gth_quad_A_rxp_1, + input wire gth_quad_A_rxn_1, + output wire gth_quad_A_txp_2, + output wire gth_quad_A_txn_2, + input wire gth_quad_A_rxp_2, + input wire gth_quad_A_rxn_2, + output wire gth_quad_A_txp_3, + output wire gth_quad_A_txn_3, + input wire gth_quad_A_rxp_3, + input wire gth_quad_A_rxn_3, + input wire gth_quad_B_refclk_p, + input wire gth_quad_B_refclk_n, + output wire gth_quad_B_txp_0, + output wire gth_quad_B_txn_0, + input wire gth_quad_B_rxp_0, + input wire gth_quad_B_rxn_0, + output wire gth_quad_B_txp_1, + output wire gth_quad_B_txn_1, + input wire gth_quad_B_rxp_1, + input wire gth_quad_B_rxn_1, + output wire gth_quad_B_txp_2, + output wire gth_quad_B_txn_2, + input wire gth_quad_B_rxp_2, + input wire gth_quad_B_rxn_2, + output wire gth_quad_B_txp_3, + output wire gth_quad_B_txn_3, + input wire gth_quad_B_rxp_3, + input wire gth_quad_B_rxn_3, + input wire gth_quad_C_refclk_p, + input wire gth_quad_C_refclk_n, + output wire gth_quad_C_txp_0, + output wire gth_quad_C_txn_0, + input wire gth_quad_C_rxp_0, + input wire gth_quad_C_rxn_0, + output wire gth_quad_C_txp_1, + output wire gth_quad_C_txn_1, + input wire gth_quad_C_rxp_1, + input wire gth_quad_C_rxn_1, + output wire gth_quad_C_txp_2, + output wire gth_quad_C_txn_2, + input wire gth_quad_C_rxp_2, + input wire gth_quad_C_rxn_2, + output wire gth_quad_C_txp_3, + output wire gth_quad_C_txn_3, + input wire gth_quad_C_rxp_3, + input wire gth_quad_C_rxn_3, + input wire gth_quad_D_refclk_p, + input wire gth_quad_D_refclk_n, + output wire gth_quad_D_txp_0, + output wire gth_quad_D_txn_0, + input wire gth_quad_D_rxp_0, + input wire gth_quad_D_rxn_0, + output wire gth_quad_D_txp_1, + output wire gth_quad_D_txn_1, + input wire gth_quad_D_rxp_1, + input wire gth_quad_D_rxn_1, + output wire gth_quad_D_txp_2, + output wire gth_quad_D_txn_2, + input wire gth_quad_D_rxp_2, + input wire gth_quad_D_rxn_2, + output wire gth_quad_D_txp_3, + output wire gth_quad_D_txn_3, + input wire gth_quad_D_rxp_3, + input wire gth_quad_D_rxn_3, + input wire gth_quad_E_refclk_p, + input wire gth_quad_E_refclk_n, + output wire gth_quad_E_txp_0, + output wire gth_quad_E_txn_0, + input wire gth_quad_E_rxp_0, + input wire gth_quad_E_rxn_0, + output wire gth_quad_E_txp_1, + output wire gth_quad_E_txn_1, + input wire gth_quad_E_rxp_1, + input wire gth_quad_E_rxn_1, + output wire gth_quad_E_txp_2, + output wire gth_quad_E_txn_2, + input wire gth_quad_E_rxp_2, + input wire gth_quad_E_rxn_2, + output wire gth_quad_E_txp_3, + output wire gth_quad_E_txn_3, + input wire gth_quad_E_rxp_3, + input wire gth_quad_E_rxn_3, + input wire gth_quad_F_refclk_p, + input wire gth_quad_F_refclk_n, + output wire gth_quad_F_txp_0, + output wire gth_quad_F_txn_0, + input wire gth_quad_F_rxp_0, + input wire gth_quad_F_rxn_0, + output wire gth_quad_F_txp_1, + output wire gth_quad_F_txn_1, + input wire gth_quad_F_rxp_1, + input wire gth_quad_F_rxn_1, + output wire gth_quad_F_txp_2, + output wire gth_quad_F_txn_2, + input wire gth_quad_F_rxp_2, + input wire gth_quad_F_rxn_2, + output wire gth_quad_F_txp_3, + output wire gth_quad_F_txn_3, + input wire gth_quad_F_rxp_3, + input wire gth_quad_F_rxn_3 +); + +/* + * Clock: 50MHz + */ +wire sys_clk_ibufg; +wire sys_clk_int; + +/* + * Clock: 156.25 MHz + */ +wire clk_156mhz; + +/* + * Synchronous reset + */ +wire sys_rst; +wire rst_156mhz; + +/* + * GPIO + */ +wire [1:0] sw_int; +wire [3:0] jp_int; +wire [3:0] led_int; + +/* + * Silicon Labs CP2102 USB UART + */ +wire uart_sys_rst; +wire uart_suspend_int; +wire uart_ri_int; +wire uart_dcd_int; +wire uart_dtr_int; +wire uart_dsr_int; +wire uart_txd_int; +wire uart_rxd_int; +wire uart_rts_int; +wire uart_cts_int; + +/* + * Clock muxes + */ +wire clk_gth_scl_i; +wire clk_gth_scl_o; +wire clk_gth_scl_t; +wire clk_gth_sda_i; +wire clk_gth_sda_o; +wire clk_gth_sda_t; +wire clk_gthl_alm_int; +wire clk_gthl_lol_int; +wire clk_gthr_alm_int; +wire clk_gthr_lol_int; + +/* + * AirMax I/O + */ +wire amh_right_mdc_int; +wire amh_right_mdio_i_int; +wire amh_right_mdio_o_int; +wire amh_right_mdio_t_int; +wire amh_left_mdc_int; +wire amh_left_mdio_i_int; +wire amh_left_mdio_o_int; +wire amh_left_mdio_t_int; + +/* + * 10G Ethernet + */ +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r0_rxd; +wire [7:0] eth_r0_rxc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r1_rxd; +wire [7:0] eth_r1_rxc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r2_rxd; +wire [7:0] eth_r2_rxc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r3_rxd; +wire [7:0] eth_r3_rxc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r4_rxd; +wire [7:0] eth_r4_rxc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r5_rxd; +wire [7:0] eth_r5_rxc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r6_rxd; +wire [7:0] eth_r6_rxc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r7_rxd; +wire [7:0] eth_r7_rxc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r8_rxd; +wire [7:0] eth_r8_rxc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r9_rxd; +wire [7:0] eth_r9_rxc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r10_rxd; +wire [7:0] eth_r10_rxc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_r11_rxd; +wire [7:0] eth_r11_rxc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l0_rxd; +wire [7:0] eth_l0_rxc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l1_rxd; +wire [7:0] eth_l1_rxc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l2_rxd; +wire [7:0] eth_l2_rxc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l3_rxd; +wire [7:0] eth_l3_rxc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l4_rxd; +wire [7:0] eth_l4_rxc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l5_rxd; +wire [7:0] eth_l5_rxc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l6_rxd; +wire [7:0] eth_l6_rxc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l7_rxd; +wire [7:0] eth_l7_rxc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l8_rxd; +wire [7:0] eth_l8_rxc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l9_rxd; +wire [7:0] eth_l9_rxc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l10_rxd; +wire [7:0] eth_l10_rxc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; +wire [63:0] eth_l11_rxd; +wire [7:0] eth_l11_rxc; + +// Clock buffering for 50 MHz sys_clk +IBUFG +sys_clk_ibufg_inst ( + .I(sys_clk), + .O(sys_clk_ibufg) +); + +BUFG +sys_clk_bufg_inst ( + .I(sys_clk_ibufg), + .O(sys_clk_int) +); + +// 156.25 MHz clock from GTH +wire txclk156; + +BUFG +clk156_bufg_inst ( + .I(txclk156), + .O(clk_156mhz) +); + +// Synchronize reset signal +sync_reset #( + .N(6) +) +sync_reset_inst ( + .clk(sys_clk_int), + .rst(~reset_n), + .sync_reset_out(sys_rst) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_50mhz_inst ( + .clk(sys_clk_int), + .in({clk_gthl_alm, + clk_gthl_lol, + clk_gthr_alm, + clk_gthr_lol}), + .out({clk_gthl_alm_int, + clk_gthl_lol_int, + clk_gthr_alm_int, + clk_gthr_lol_int}) +); + +sync_signal #( + .WIDTH(4), + .N(2) +) +sync_signal_156mhz_inst ( + .clk(clk_156mhz), + .in({uart_suspend, + uart_dtr, + uart_txd, + uart_rts}), + .out({uart_suspend_int, + uart_dtr_int, + uart_txd_int, + uart_rts_int}) +); + +// Debounce switch inputs +debounce_switch #( + .WIDTH(6), + .N(4), + .RATE(50000) +) +debounce_switch_inst ( + .clk(sys_clk_int), + .rst(sys_rst), + .in({sw, jp}), + .out({sw_int, jp_int}) +); + +// pass through outputs +assign led = led_int; + +assign uart_rst = uart_rst_int; +assign uart_ri = uart_ri_int; +assign uart_dcd = uart_dcd_int; +assign uart_dsr = uart_dsr_int; +assign uart_rxd = uart_rxd_int; +assign uart_cts = uart_cts_int; + +// clock mux I2C +assign clk_gth_scl_i = clk_gth_scl; +assign clk_gth_scl = clk_gth_scl_t ? 1'bz : clk_gth_scl_o; +assign clk_gth_sda_i = clk_gth_sda; +assign clk_gth_sda = clk_gth_sda_t ? 1'bz : clk_gth_sda_o; + +assign clk_gth_rst_n = ~sys_rst; + +wire [6:0] clk_gth_i2c_cmd_address; +wire clk_gth_i2c_cmd_start; +wire clk_gth_i2c_cmd_read; +wire clk_gth_i2c_cmd_write; +wire clk_gth_i2c_cmd_write_multiple; +wire clk_gth_i2c_cmd_stop; +wire clk_gth_i2c_cmd_valid; +wire clk_gth_i2c_cmd_ready; + +wire [7:0] clk_gth_i2c_data; +wire clk_gth_i2c_data_valid; +wire clk_gth_i2c_data_ready; +wire clk_gth_i2c_data_last; + +gth_i2c_init +clk_gth_i2c_init ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_out(clk_gth_i2c_data), + .data_out_valid(clk_gth_i2c_data_valid), + .data_out_ready(clk_gth_i2c_data_ready), + .data_out_last(clk_gth_i2c_data_last), + .busy(), + .start(1) +); + +i2c_master +clk_gth_i2c_master ( + .clk(sys_clk_int), + .rst(sys_rst), + .cmd_address(clk_gth_i2c_cmd_address), + .cmd_start(clk_gth_i2c_cmd_start), + .cmd_read(clk_gth_i2c_cmd_read), + .cmd_write(clk_gth_i2c_cmd_write), + .cmd_write_multiple(clk_gth_i2c_cmd_write_multiple), + .cmd_stop(clk_gth_i2c_cmd_stop), + .cmd_valid(clk_gth_i2c_cmd_valid), + .cmd_ready(clk_gth_i2c_cmd_ready), + .data_in(clk_gth_i2c_data), + .data_in_valid(clk_gth_i2c_data_valid), + .data_in_ready(clk_gth_i2c_data_ready), + .data_in_last(clk_gth_i2c_data_last), + .data_out(), + .data_out_valid(), + .data_out_ready(1), + .data_out_last(), + .scl_i(clk_gth_scl_i), + .scl_o(clk_gth_scl_o), + .scl_t(clk_gth_scl_t), + .sda_i(clk_gth_sda_i), + .sda_o(clk_gth_sda_o), + .sda_t(clk_gth_sda_t), + .busy(), + .bus_control(), + .bus_active(), + .missed_ack(), + .prescale(312), + .stop_on_idle(1) +); + +// reset logic +wire gth_reset; + +wire gth_reset_done_A; +wire gth_reset_done_B; +wire gth_reset_done_C; +wire gth_reset_done_D; +wire gth_reset_done_E; +wire gth_reset_done_F; + +wire gth_reset_done = gth_reset_done_A & gth_reset_done_B & gth_reset_done_C & gth_reset_done_D & gth_reset_done_E & gth_reset_done_F; + +wire clk_gth_ready = ~clk_gthl_lol_int & ~clk_gthr_lol_int; + +sync_reset #( + .N(6) +) +sync_reset_gth_inst ( + .clk(sys_clk_int), + .rst(sys_rst | ~clk_gth_ready), + .sync_reset_out(gth_reset) +); + +sync_reset #( + .N(6) +) +sync_reset_156mhz_inst ( + .clk(clk_156mhz), + .rst(gth_reset | ~gth_reset_done), + .sync_reset_out(rst_156mhz) +); + +assign amh_right_phy_rst_n = ~rst_156mhz; +assign amh_left_phy_rst_n = ~rst_156mhz; + +// AirMax I/O + +assign amh_right_mdc = amh_right_mdc_int; + +assign amh_right_mdio_i_int = amh_right_mdio; +assign amh_right_mdio = amh_right_mdio_t_int ? 1'bz : amh_right_mdio_o_int; + +assign amh_left_mdc = amh_left_mdc_int; + +assign amh_left_mdio_i_int = amh_left_mdio; +assign amh_left_mdio = amh_left_mdio_t_int ? 1'bz : amh_left_mdio_o_int; + +// 10G Ethernet PCS/PMA + +// Quad A X0Y0 +eth_gth_phy_quad +eth_gth_phy_quad_A_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(txclk156), // pickoff one transmit clock for 156.25 MHz core clock + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_A), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_A_refclk_p), + .refclk_n(gth_quad_A_refclk_n), + .txn_0(gth_quad_A_txn_0), + .txp_0(gth_quad_A_txp_0), + .rxn_0(gth_quad_A_rxn_0), + .rxp_0(gth_quad_A_rxp_0), + .txn_1(gth_quad_A_txn_1), + .txp_1(gth_quad_A_txp_1), + .rxn_1(gth_quad_A_rxn_1), + .rxp_1(gth_quad_A_rxp_1), + .txn_2(gth_quad_A_txn_2), + .txp_2(gth_quad_A_txp_2), + .rxn_2(gth_quad_A_rxn_2), + .rxp_2(gth_quad_A_rxp_2), + .txn_3(gth_quad_A_txn_3), + .txp_3(gth_quad_A_txp_3), + .rxn_3(gth_quad_A_rxn_3), + .rxp_3(gth_quad_A_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r0_txd), + .xgmii_txc_0(eth_r0_txc), + .xgmii_rxd_0(eth_r0_rxd), + .xgmii_rxc_0(eth_r0_rxc), + .xgmii_txd_1(eth_r2_txd), + .xgmii_txc_1(eth_r2_txc), + .xgmii_rxd_1(eth_r2_rxd), + .xgmii_rxc_1(eth_r2_rxc), + .xgmii_txd_2(eth_r4_txd), + .xgmii_txc_2(eth_r4_txc), + .xgmii_rxd_2(eth_r4_rxd), + .xgmii_rxc_2(eth_r4_rxc), + .xgmii_txd_3(eth_r6_txd), + .xgmii_txc_3(eth_r6_txc), + .xgmii_rxd_3(eth_r6_rxd), + .xgmii_rxc_3(eth_r6_rxc) +); + +// Quad B X0Y1 +eth_gth_phy_quad +eth_gth_phy_quad_B_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_B), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_B_refclk_p), + .refclk_n(gth_quad_B_refclk_n), + .txn_0(gth_quad_B_txn_0), + .txp_0(gth_quad_B_txp_0), + .rxn_0(gth_quad_B_rxn_0), + .rxp_0(gth_quad_B_rxp_0), + .txn_1(gth_quad_B_txn_1), + .txp_1(gth_quad_B_txp_1), + .rxn_1(gth_quad_B_rxn_1), + .rxp_1(gth_quad_B_rxp_1), + .txn_2(gth_quad_B_txn_2), + .txp_2(gth_quad_B_txp_2), + .rxn_2(gth_quad_B_rxn_2), + .rxp_2(gth_quad_B_rxp_2), + .txn_3(gth_quad_B_txn_3), + .txp_3(gth_quad_B_txp_3), + .rxn_3(gth_quad_B_rxn_3), + .rxp_3(gth_quad_B_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r3_txd), + .xgmii_txc_0(eth_r3_txc), + .xgmii_rxd_0(eth_r3_rxd), + .xgmii_rxc_0(eth_r3_rxc), + .xgmii_txd_1(eth_r5_txd), + .xgmii_txc_1(eth_r5_txc), + .xgmii_rxd_1(eth_r5_rxd), + .xgmii_rxc_1(eth_r5_rxc), + .xgmii_txd_2(eth_r1_txd), + .xgmii_txc_2(eth_r1_txc), + .xgmii_rxd_2(eth_r1_rxd), + .xgmii_rxc_2(eth_r1_rxc), + .xgmii_txd_3(eth_r7_txd), + .xgmii_txc_3(eth_r7_txc), + .xgmii_rxd_3(eth_r7_rxd), + .xgmii_rxc_3(eth_r7_rxc) +); + +// Quad C X0Y2 +eth_gth_phy_quad +eth_gth_phy_quad_C_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_C), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_C_refclk_p), + .refclk_n(gth_quad_C_refclk_n), + .txn_0(gth_quad_C_txn_0), + .txp_0(gth_quad_C_txp_0), + .rxn_0(gth_quad_C_rxn_0), + .rxp_0(gth_quad_C_rxp_0), + .txn_1(gth_quad_C_txn_1), + .txp_1(gth_quad_C_txp_1), + .rxn_1(gth_quad_C_rxn_1), + .rxp_1(gth_quad_C_rxp_1), + .txn_2(gth_quad_C_txn_2), + .txp_2(gth_quad_C_txp_2), + .rxn_2(gth_quad_C_rxn_2), + .rxp_2(gth_quad_C_rxp_2), + .txn_3(gth_quad_C_txn_3), + .txp_3(gth_quad_C_txp_3), + .rxn_3(gth_quad_C_rxn_3), + .rxp_3(gth_quad_C_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_r8_txd), + .xgmii_txc_0(eth_r8_txc), + .xgmii_rxd_0(eth_r8_rxd), + .xgmii_rxc_0(eth_r8_rxc), + .xgmii_txd_1(eth_r9_txd), + .xgmii_txc_1(eth_r9_txc), + .xgmii_rxd_1(eth_r9_rxd), + .xgmii_rxc_1(eth_r9_rxc), + .xgmii_txd_2(eth_r11_txd), + .xgmii_txc_2(eth_r11_txc), + .xgmii_rxd_2(eth_r11_rxd), + .xgmii_rxc_2(eth_r11_rxc), + .xgmii_txd_3(eth_r10_txd), + .xgmii_txc_3(eth_r10_txc), + .xgmii_rxd_3(eth_r10_rxd), + .xgmii_rxc_3(eth_r10_rxc) +); + +// Quad D X1Y0 +eth_gth_phy_quad +eth_gth_phy_quad_D_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_D), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_D_refclk_p), + .refclk_n(gth_quad_D_refclk_n), + .txn_0(gth_quad_D_txn_0), + .txp_0(gth_quad_D_txp_0), + .rxn_0(gth_quad_D_rxn_0), + .rxp_0(gth_quad_D_rxp_0), + .txn_1(gth_quad_D_txn_1), + .txp_1(gth_quad_D_txp_1), + .rxn_1(gth_quad_D_rxn_1), + .rxp_1(gth_quad_D_rxp_1), + .txn_2(gth_quad_D_txn_2), + .txp_2(gth_quad_D_txp_2), + .rxn_2(gth_quad_D_rxn_2), + .rxp_2(gth_quad_D_rxp_2), + .txn_3(gth_quad_D_txn_3), + .txp_3(gth_quad_D_txp_3), + .rxn_3(gth_quad_D_rxn_3), + .rxp_3(gth_quad_D_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l0_txd), + .xgmii_txc_0(eth_l0_txc), + .xgmii_rxd_0(eth_l0_rxd), + .xgmii_rxc_0(eth_l0_rxc), + .xgmii_txd_1(eth_l2_txd), + .xgmii_txc_1(eth_l2_txc), + .xgmii_rxd_1(eth_l2_rxd), + .xgmii_rxc_1(eth_l2_rxc), + .xgmii_txd_2(eth_l4_txd), + .xgmii_txc_2(eth_l4_txc), + .xgmii_rxd_2(eth_l4_rxd), + .xgmii_rxc_2(eth_l4_rxc), + .xgmii_txd_3(eth_l6_txd), + .xgmii_txc_3(eth_l6_txc), + .xgmii_rxd_3(eth_l6_rxd), + .xgmii_rxc_3(eth_l6_rxc) +); + +// Quad E X1Y1 +eth_gth_phy_quad +eth_gth_phy_quad_E_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_E), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_E_refclk_p), + .refclk_n(gth_quad_E_refclk_n), + .txn_0(gth_quad_E_txn_0), + .txp_0(gth_quad_E_txp_0), + .rxn_0(gth_quad_E_rxn_0), + .rxp_0(gth_quad_E_rxp_0), + .txn_1(gth_quad_E_txn_1), + .txp_1(gth_quad_E_txp_1), + .rxn_1(gth_quad_E_rxn_1), + .rxp_1(gth_quad_E_rxp_1), + .txn_2(gth_quad_E_txn_2), + .txp_2(gth_quad_E_txp_2), + .rxn_2(gth_quad_E_rxn_2), + .rxp_2(gth_quad_E_rxp_2), + .txn_3(gth_quad_E_txn_3), + .txp_3(gth_quad_E_txp_3), + .rxn_3(gth_quad_E_rxn_3), + .rxp_3(gth_quad_E_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l3_txd), + .xgmii_txc_0(eth_l3_txc), + .xgmii_rxd_0(eth_l3_rxd), + .xgmii_rxc_0(eth_l3_rxc), + .xgmii_txd_1(eth_l5_txd), + .xgmii_txc_1(eth_l5_txc), + .xgmii_rxd_1(eth_l5_rxd), + .xgmii_rxc_1(eth_l5_rxc), + .xgmii_txd_2(eth_l1_txd), + .xgmii_txc_2(eth_l1_txc), + .xgmii_rxd_2(eth_l1_rxd), + .xgmii_rxc_2(eth_l1_rxc), + .xgmii_txd_3(eth_l7_txd), + .xgmii_txc_3(eth_l7_txc), + .xgmii_rxd_3(eth_l7_rxd), + .xgmii_rxc_3(eth_l7_rxc) +); + +// Quad F X1Y2 +eth_gth_phy_quad +eth_gth_phy_quad_F_inst ( + /* + * Clock and reset + */ + .clk156(clk_156mhz), + .rst156(rst_156mhz), + .dclk(sys_clk_int), + .dclk_reset(sys_rst), + .txclk156(), + + .gth_reset(gth_reset), + .gth_reset_done(gth_reset_done_F), + + /* + * Transciever pins + */ + .refclk_p(gth_quad_F_refclk_p), + .refclk_n(gth_quad_F_refclk_n), + .txn_0(gth_quad_F_txn_0), + .txp_0(gth_quad_F_txp_0), + .rxn_0(gth_quad_F_rxn_0), + .rxp_0(gth_quad_F_rxp_0), + .txn_1(gth_quad_F_txn_1), + .txp_1(gth_quad_F_txp_1), + .rxn_1(gth_quad_F_rxn_1), + .rxp_1(gth_quad_F_rxp_1), + .txn_2(gth_quad_F_txn_2), + .txp_2(gth_quad_F_txp_2), + .rxn_2(gth_quad_F_rxn_2), + .rxp_2(gth_quad_F_rxp_2), + .txn_3(gth_quad_F_txn_3), + .txp_3(gth_quad_F_txp_3), + .rxn_3(gth_quad_F_rxn_3), + .rxp_3(gth_quad_F_rxp_3), + + /* + * XGMII interfaces + */ + .xgmii_txd_0(eth_l8_txd), + .xgmii_txc_0(eth_l8_txc), + .xgmii_rxd_0(eth_l8_rxd), + .xgmii_rxc_0(eth_l8_rxc), + .xgmii_txd_1(eth_l9_txd), + .xgmii_txc_1(eth_l9_txc), + .xgmii_rxd_1(eth_l9_rxd), + .xgmii_rxc_1(eth_l9_rxc), + .xgmii_txd_2(eth_l11_txd), + .xgmii_txc_2(eth_l11_txc), + .xgmii_rxd_2(eth_l11_rxd), + .xgmii_rxc_2(eth_l11_rxc), + .xgmii_txd_3(eth_l10_txd), + .xgmii_txc_3(eth_l10_txc), + .xgmii_rxd_3(eth_l10_rxd), + .xgmii_rxc_3(eth_l10_rxc) +); + + +fpga_core +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk_156mhz), + .rst(rst_156mhz), + /* + * GPIO + */ + .sw(sw_int), + .jp(jp_int), + .led(led_int), + /* + * Silicon Labs CP2102 USB UART + */ + .uart_rst(uart_rst_int), + .uart_suspend(uart_suspend_int), + .uart_ri(uart_ri_int), + .uart_dcd(uart_dcd_int), + .uart_dtr(uart_dtr_int), + .uart_dsr(uart_dsr_int), + .uart_txd(uart_txd_int), + .uart_rxd(uart_rxd_int), + .uart_rts(uart_rts_int), + .uart_cts(uart_cts_int), + /* + * AirMax I/O + */ + .amh_right_mdc(amh_right_mdc_int), + .amh_right_mdio_i(amh_right_mdio_i_int), + .amh_right_mdio_o(amh_right_mdio_o_int), + .amh_right_mdio_t(amh_right_mdio_t_int), + .amh_left_mdc(amh_left_mdc_int), + .amh_left_mdio_i(amh_left_mdio_i_int), + .amh_left_mdio_o(amh_left_mdio_o_int), + .amh_left_mdio_t(amh_left_mdio_t_int), + /* + * 10G Ethernet XGMII + */ + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v new file mode 100644 index 00000000..232fc9c1 --- /dev/null +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -0,0 +1,733 @@ +/* + +Copyright (c) 2016 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 + +module fpga_core +( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + input wire clk, + input wire rst, + /* + * GPIO + */ + input wire [1:0] sw, + input wire [3:0] jp, + output wire [3:0] led, + /* + * Silicon Labs CP2102 USB UART + */ + output wire uart_rst, + input wire uart_suspend, + output wire uart_ri, + output wire uart_dcd, + input wire uart_dtr, + output wire uart_dsr, + input wire uart_txd, + output wire uart_rxd, + input wire uart_rts, + output wire uart_cts, + /* + * AirMax I/O + */ + output wire amh_right_mdc, + input wire amh_right_mdio_i, + output wire amh_right_mdio_o, + output wire amh_right_mdio_t, + output wire amh_left_mdc, + input wire amh_left_mdio_i, + output wire amh_left_mdio_o, + output wire amh_left_mdio_t, + /* + * 10G Ethernet + */ + output wire [63:0] eth_r0_txd, + output wire [7:0] eth_r0_txc, + input wire [63:0] eth_r0_rxd, + input wire [7:0] eth_r0_rxc, + output wire [63:0] eth_r1_txd, + output wire [7:0] eth_r1_txc, + input wire [63:0] eth_r1_rxd, + input wire [7:0] eth_r1_rxc, + output wire [63:0] eth_r2_txd, + output wire [7:0] eth_r2_txc, + input wire [63:0] eth_r2_rxd, + input wire [7:0] eth_r2_rxc, + output wire [63:0] eth_r3_txd, + output wire [7:0] eth_r3_txc, + input wire [63:0] eth_r3_rxd, + input wire [7:0] eth_r3_rxc, + output wire [63:0] eth_r4_txd, + output wire [7:0] eth_r4_txc, + input wire [63:0] eth_r4_rxd, + input wire [7:0] eth_r4_rxc, + output wire [63:0] eth_r5_txd, + output wire [7:0] eth_r5_txc, + input wire [63:0] eth_r5_rxd, + input wire [7:0] eth_r5_rxc, + output wire [63:0] eth_r6_txd, + output wire [7:0] eth_r6_txc, + input wire [63:0] eth_r6_rxd, + input wire [7:0] eth_r6_rxc, + output wire [63:0] eth_r7_txd, + output wire [7:0] eth_r7_txc, + input wire [63:0] eth_r7_rxd, + input wire [7:0] eth_r7_rxc, + output wire [63:0] eth_r8_txd, + output wire [7:0] eth_r8_txc, + input wire [63:0] eth_r8_rxd, + input wire [7:0] eth_r8_rxc, + output wire [63:0] eth_r9_txd, + output wire [7:0] eth_r9_txc, + input wire [63:0] eth_r9_rxd, + input wire [7:0] eth_r9_rxc, + output wire [63:0] eth_r10_txd, + output wire [7:0] eth_r10_txc, + input wire [63:0] eth_r10_rxd, + input wire [7:0] eth_r10_rxc, + output wire [63:0] eth_r11_txd, + output wire [7:0] eth_r11_txc, + input wire [63:0] eth_r11_rxd, + input wire [7:0] eth_r11_rxc, + output wire [63:0] eth_l0_txd, + output wire [7:0] eth_l0_txc, + input wire [63:0] eth_l0_rxd, + input wire [7:0] eth_l0_rxc, + output wire [63:0] eth_l1_txd, + output wire [7:0] eth_l1_txc, + input wire [63:0] eth_l1_rxd, + input wire [7:0] eth_l1_rxc, + output wire [63:0] eth_l2_txd, + output wire [7:0] eth_l2_txc, + input wire [63:0] eth_l2_rxd, + input wire [7:0] eth_l2_rxc, + output wire [63:0] eth_l3_txd, + output wire [7:0] eth_l3_txc, + input wire [63:0] eth_l3_rxd, + input wire [7:0] eth_l3_rxc, + output wire [63:0] eth_l4_txd, + output wire [7:0] eth_l4_txc, + input wire [63:0] eth_l4_rxd, + input wire [7:0] eth_l4_rxc, + output wire [63:0] eth_l5_txd, + output wire [7:0] eth_l5_txc, + input wire [63:0] eth_l5_rxd, + input wire [7:0] eth_l5_rxc, + output wire [63:0] eth_l6_txd, + output wire [7:0] eth_l6_txc, + input wire [63:0] eth_l6_rxd, + input wire [7:0] eth_l6_rxc, + output wire [63:0] eth_l7_txd, + output wire [7:0] eth_l7_txc, + input wire [63:0] eth_l7_rxd, + input wire [7:0] eth_l7_rxc, + output wire [63:0] eth_l8_txd, + output wire [7:0] eth_l8_txc, + input wire [63:0] eth_l8_rxd, + input wire [7:0] eth_l8_rxc, + output wire [63:0] eth_l9_txd, + output wire [7:0] eth_l9_txc, + input wire [63:0] eth_l9_rxd, + input wire [7:0] eth_l9_rxc, + output wire [63:0] eth_l10_txd, + output wire [7:0] eth_l10_txc, + input wire [63:0] eth_l10_rxd, + input wire [7:0] eth_l10_rxc, + output wire [63:0] eth_l11_txd, + output wire [7:0] eth_l11_txc, + input wire [63:0] eth_l11_rxd, + input wire [7:0] eth_l11_rxc +); + +// UART +assign uart_rst = 1'b1; +assign uart_txd = 1'b1; + +// AirMax I/O +assign amh_right_mdc = 1'b1; +assign amh_right_mdio_o = 1'b1; +assign amh_right_mdio_t = 1'b1; +assign amh_left_mdc = 1'b1; +assign amh_left_mdio_o = 1'b1; +assign amh_left_mdio_t = 1'b1; + +// 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_tdata; +wire [7:0] rx_eth_payload_tkeep; +wire rx_eth_payload_tvalid; +wire rx_eth_payload_tready; +wire rx_eth_payload_tlast; +wire rx_eth_payload_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_tdata; +wire [7:0] tx_eth_payload_tkeep; +wire tx_eth_payload_tvalid; +wire tx_eth_payload_tready; +wire tx_eth_payload_tlast; +wire tx_eth_payload_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_tdata; +wire [7:0] rx_ip_payload_tkeep; +wire rx_ip_payload_tvalid; +wire rx_ip_payload_tready; +wire rx_ip_payload_tlast; +wire rx_ip_payload_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_tdata; +wire [7:0] tx_ip_payload_tkeep; +wire tx_ip_payload_tvalid; +wire tx_ip_payload_tready; +wire tx_ip_payload_tlast; +wire tx_ip_payload_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_tdata; +wire [7:0] rx_udp_payload_tkeep; +wire rx_udp_payload_tvalid; +wire rx_udp_payload_tready; +wire rx_udp_payload_tlast; +wire rx_udp_payload_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_tdata; +wire [7:0] tx_udp_payload_tkeep; +wire tx_udp_payload_tvalid; +wire tx_udp_payload_tready; +wire tx_udp_payload_tlast; +wire tx_udp_payload_tuser; + +wire [63:0] rx_fifo_udp_payload_tdata; +wire [7:0] rx_fifo_udp_payload_tkeep; +wire rx_fifo_udp_payload_tvalid; +wire rx_fifo_udp_payload_tready; +wire rx_fifo_udp_payload_tlast; +wire rx_fifo_udp_payload_tuser; + +wire [63:0] tx_fifo_udp_payload_tdata; +wire [7:0] tx_fifo_udp_payload_tkeep; +wire tx_fifo_udp_payload_tvalid; +wire tx_fifo_udp_payload_tready; +wire tx_fifo_udp_payload_tlast; +wire tx_fifo_udp_payload_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_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_tdata = 0; +assign tx_ip_payload_tkeep = 0; +assign tx_ip_payload_tvalid = 0; +assign tx_ip_payload_tlast = 0; +assign tx_ip_payload_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_tvalid) begin + if ((~match_cond_reg & ~no_match_reg) | + (rx_udp_payload_tvalid & rx_udp_payload_tready & rx_udp_payload_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_tdata = rx_udp_payload_tdata; +//assign tx_udp_payload_tkeep = rx_udp_payload_tkeep; +//assign tx_udp_payload_tvalid = rx_udp_payload_tvalid; +//assign rx_udp_payload_tready = tx_udp_payload_tready; +//assign tx_udp_payload_tlast = rx_udp_payload_tlast; +//assign tx_udp_payload_tuser = rx_udp_payload_tuser; + +assign tx_udp_payload_tdata = tx_fifo_udp_payload_tdata; +assign tx_udp_payload_tkeep = tx_fifo_udp_payload_tkeep; +assign tx_udp_payload_tvalid = tx_fifo_udp_payload_tvalid; +assign tx_fifo_udp_payload_tready = tx_udp_payload_tready; +assign tx_udp_payload_tlast = tx_fifo_udp_payload_tlast; +assign tx_udp_payload_tuser = tx_fifo_udp_payload_tuser; + +assign rx_fifo_udp_payload_tdata = rx_udp_payload_tdata; +assign rx_fifo_udp_payload_tkeep = rx_udp_payload_tkeep; +assign rx_fifo_udp_payload_tvalid = rx_udp_payload_tvalid & match_cond_reg; +assign rx_udp_payload_tready = (rx_fifo_udp_payload_tready & match_cond_reg) | no_match_reg; +assign rx_fifo_udp_payload_tlast = rx_udp_payload_tlast; +assign rx_fifo_udp_payload_tuser = rx_udp_payload_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_tvalid; + if (tx_udp_payload_tvalid & ~valid_last) begin + led_reg <= tx_udp_payload_tdata; + end + end +end + +//assign led = sw; +assign led = led_reg; + +assign eth_r0_txd = 64'h0707070707070707; +assign eth_r0_txc = 8'hff; +assign eth_r1_txd = 64'h0707070707070707; +assign eth_r1_txc = 8'hff; +assign eth_r2_txd = 64'h0707070707070707; +assign eth_r2_txc = 8'hff; +assign eth_r3_txd = 64'h0707070707070707; +assign eth_r3_txc = 8'hff; +assign eth_r4_txd = 64'h0707070707070707; +assign eth_r4_txc = 8'hff; +assign eth_r5_txd = 64'h0707070707070707; +assign eth_r5_txc = 8'hff; +assign eth_r6_txd = 64'h0707070707070707; +assign eth_r6_txc = 8'hff; +assign eth_r7_txd = 64'h0707070707070707; +assign eth_r7_txc = 8'hff; +assign eth_r8_txd = 64'h0707070707070707; +assign eth_r8_txc = 8'hff; +assign eth_r9_txd = 64'h0707070707070707; +assign eth_r9_txc = 8'hff; +assign eth_r10_txd = 64'h0707070707070707; +assign eth_r10_txc = 8'hff; +assign eth_r11_txd = 64'h0707070707070707; +assign eth_r11_txc = 8'hff; + +//assign eth_l0_txd = 64'h0707070707070707; +//assign eth_l0_txc = 8'hff; +assign eth_l1_txd = 64'h0707070707070707; +assign eth_l1_txc = 8'hff; +assign eth_l2_txd = 64'h0707070707070707; +assign eth_l2_txc = 8'hff; +assign eth_l3_txd = 64'h0707070707070707; +assign eth_l3_txc = 8'hff; +assign eth_l4_txd = 64'h0707070707070707; +assign eth_l4_txc = 8'hff; +assign eth_l5_txd = 64'h0707070707070707; +assign eth_l5_txc = 8'hff; +assign eth_l6_txd = 64'h0707070707070707; +assign eth_l6_txc = 8'hff; +assign eth_l7_txd = 64'h0707070707070707; +assign eth_l7_txc = 8'hff; +assign eth_l8_txd = 64'h0707070707070707; +assign eth_l8_txc = 8'hff; +assign eth_l9_txd = 64'h0707070707070707; +assign eth_l9_txc = 8'hff; +assign eth_l10_txd = 64'h0707070707070707; +assign eth_l10_txc = 8'hff; +assign eth_l11_txd = 64'h0707070707070707; +assign eth_l11_txc = 8'hff; + +eth_mac_10g_fifo #( + .ENABLE_PADDING(1), + .ENABLE_DIC(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_ADDR_WIDTH(9), + .RX_FIFO_ADDR_WIDTH(9) +) +eth_mac_10g_fifo_inst ( + .rx_clk(clk), + .rx_rst(rst), + .tx_clk(clk), + .tx_rst(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(eth_l0_rxd), + .xgmii_rxc(eth_l0_rxc), + .xgmii_txd(eth_l0_txd), + .xgmii_txc(eth_l0_txc), + + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + + .ifg_delay(8'd12) +); + +eth_axis_rx_64 +eth_axis_rx_inst ( + .clk(clk), + .rst(rst), + // AXI input + .input_axis_tdata(rx_axis_tdata), + .input_axis_tkeep(rx_axis_tkeep), + .input_axis_tvalid(rx_axis_tvalid), + .input_axis_tready(rx_axis_tready), + .input_axis_tlast(rx_axis_tlast), + .input_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .output_eth_hdr_valid(rx_eth_hdr_valid), + .output_eth_hdr_ready(rx_eth_hdr_ready), + .output_eth_dest_mac(rx_eth_dest_mac), + .output_eth_src_mac(rx_eth_src_mac), + .output_eth_type(rx_eth_type), + .output_eth_payload_tdata(rx_eth_payload_tdata), + .output_eth_payload_tkeep(rx_eth_payload_tkeep), + .output_eth_payload_tvalid(rx_eth_payload_tvalid), + .output_eth_payload_tready(rx_eth_payload_tready), + .output_eth_payload_tlast(rx_eth_payload_tlast), + .output_eth_payload_tuser(rx_eth_payload_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx_64 +eth_axis_tx_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(tx_eth_hdr_valid), + .input_eth_hdr_ready(tx_eth_hdr_ready), + .input_eth_dest_mac(tx_eth_dest_mac), + .input_eth_src_mac(tx_eth_src_mac), + .input_eth_type(tx_eth_type), + .input_eth_payload_tdata(tx_eth_payload_tdata), + .input_eth_payload_tkeep(tx_eth_payload_tkeep), + .input_eth_payload_tvalid(tx_eth_payload_tvalid), + .input_eth_payload_tready(tx_eth_payload_tready), + .input_eth_payload_tlast(tx_eth_payload_tlast), + .input_eth_payload_tuser(tx_eth_payload_tuser), + // AXI output + .output_axis_tdata(tx_axis_tdata), + .output_axis_tkeep(tx_axis_tkeep), + .output_axis_tvalid(tx_axis_tvalid), + .output_axis_tready(tx_axis_tready), + .output_axis_tlast(tx_axis_tlast), + .output_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete_64 #( + .UDP_CHECKSUM_ENABLE(0) +) +udp_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(rx_eth_hdr_valid), + .input_eth_hdr_ready(rx_eth_hdr_ready), + .input_eth_dest_mac(rx_eth_dest_mac), + .input_eth_src_mac(rx_eth_src_mac), + .input_eth_type(rx_eth_type), + .input_eth_payload_tdata(rx_eth_payload_tdata), + .input_eth_payload_tkeep(rx_eth_payload_tkeep), + .input_eth_payload_tvalid(rx_eth_payload_tvalid), + .input_eth_payload_tready(rx_eth_payload_tready), + .input_eth_payload_tlast(rx_eth_payload_tlast), + .input_eth_payload_tuser(rx_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(tx_eth_hdr_valid), + .output_eth_hdr_ready(tx_eth_hdr_ready), + .output_eth_dest_mac(tx_eth_dest_mac), + .output_eth_src_mac(tx_eth_src_mac), + .output_eth_type(tx_eth_type), + .output_eth_payload_tdata(tx_eth_payload_tdata), + .output_eth_payload_tkeep(tx_eth_payload_tkeep), + .output_eth_payload_tvalid(tx_eth_payload_tvalid), + .output_eth_payload_tready(tx_eth_payload_tready), + .output_eth_payload_tlast(tx_eth_payload_tlast), + .output_eth_payload_tuser(tx_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(tx_ip_hdr_valid), + .input_ip_hdr_ready(tx_ip_hdr_ready), + .input_ip_dscp(tx_ip_dscp), + .input_ip_ecn(tx_ip_ecn), + .input_ip_length(tx_ip_length), + .input_ip_ttl(tx_ip_ttl), + .input_ip_protocol(tx_ip_protocol), + .input_ip_source_ip(tx_ip_source_ip), + .input_ip_dest_ip(tx_ip_dest_ip), + .input_ip_payload_tdata(tx_ip_payload_tdata), + .input_ip_payload_tkeep(tx_ip_payload_tkeep), + .input_ip_payload_tvalid(tx_ip_payload_tvalid), + .input_ip_payload_tready(tx_ip_payload_tready), + .input_ip_payload_tlast(tx_ip_payload_tlast), + .input_ip_payload_tuser(tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(rx_ip_hdr_valid), + .output_ip_hdr_ready(rx_ip_hdr_ready), + .output_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(rx_ip_eth_src_mac), + .output_ip_eth_type(rx_ip_eth_type), + .output_ip_version(rx_ip_version), + .output_ip_ihl(rx_ip_ihl), + .output_ip_dscp(rx_ip_dscp), + .output_ip_ecn(rx_ip_ecn), + .output_ip_length(rx_ip_length), + .output_ip_identification(rx_ip_identification), + .output_ip_flags(rx_ip_flags), + .output_ip_fragment_offset(rx_ip_fragment_offset), + .output_ip_ttl(rx_ip_ttl), + .output_ip_protocol(rx_ip_protocol), + .output_ip_header_checksum(rx_ip_header_checksum), + .output_ip_source_ip(rx_ip_source_ip), + .output_ip_dest_ip(rx_ip_dest_ip), + .output_ip_payload_tdata(rx_ip_payload_tdata), + .output_ip_payload_tkeep(rx_ip_payload_tkeep), + .output_ip_payload_tvalid(rx_ip_payload_tvalid), + .output_ip_payload_tready(rx_ip_payload_tready), + .output_ip_payload_tlast(rx_ip_payload_tlast), + .output_ip_payload_tuser(rx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(tx_udp_hdr_valid), + .input_udp_hdr_ready(tx_udp_hdr_ready), + .input_udp_ip_dscp(tx_udp_ip_dscp), + .input_udp_ip_ecn(tx_udp_ip_ecn), + .input_udp_ip_ttl(tx_udp_ip_ttl), + .input_udp_ip_source_ip(tx_udp_ip_source_ip), + .input_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .input_udp_source_port(tx_udp_source_port), + .input_udp_dest_port(tx_udp_dest_port), + .input_udp_length(tx_udp_length), + .input_udp_checksum(tx_udp_checksum), + .input_udp_payload_tdata(tx_udp_payload_tdata), + .input_udp_payload_tkeep(tx_udp_payload_tkeep), + .input_udp_payload_tvalid(tx_udp_payload_tvalid), + .input_udp_payload_tready(tx_udp_payload_tready), + .input_udp_payload_tlast(tx_udp_payload_tlast), + .input_udp_payload_tuser(tx_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(rx_udp_hdr_valid), + .output_udp_hdr_ready(rx_udp_hdr_ready), + .output_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .output_udp_eth_src_mac(rx_udp_eth_src_mac), + .output_udp_eth_type(rx_udp_eth_type), + .output_udp_ip_version(rx_udp_ip_version), + .output_udp_ip_ihl(rx_udp_ip_ihl), + .output_udp_ip_dscp(rx_udp_ip_dscp), + .output_udp_ip_ecn(rx_udp_ip_ecn), + .output_udp_ip_length(rx_udp_ip_length), + .output_udp_ip_identification(rx_udp_ip_identification), + .output_udp_ip_flags(rx_udp_ip_flags), + .output_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .output_udp_ip_ttl(rx_udp_ip_ttl), + .output_udp_ip_protocol(rx_udp_ip_protocol), + .output_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .output_udp_ip_source_ip(rx_udp_ip_source_ip), + .output_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .output_udp_source_port(rx_udp_source_port), + .output_udp_dest_port(rx_udp_dest_port), + .output_udp_length(rx_udp_length), + .output_udp_checksum(rx_udp_checksum), + .output_udp_payload_tdata(rx_udp_payload_tdata), + .output_udp_payload_tkeep(rx_udp_payload_tkeep), + .output_udp_payload_tvalid(rx_udp_payload_tvalid), + .output_udp_payload_tready(rx_udp_payload_tready), + .output_udp_payload_tlast(rx_udp_payload_tlast), + .output_udp_payload_tuser(rx_udp_payload_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_64 #( + .ADDR_WIDTH(10), + .DATA_WIDTH(64) +) +udp_payload_fifo ( + .clk(clk), + .rst(rst), + + // AXI input + .input_axis_tdata(rx_fifo_udp_payload_tdata), + .input_axis_tkeep(rx_fifo_udp_payload_tkeep), + .input_axis_tvalid(rx_fifo_udp_payload_tvalid), + .input_axis_tready(rx_fifo_udp_payload_tready), + .input_axis_tlast(rx_fifo_udp_payload_tlast), + .input_axis_tuser(rx_fifo_udp_payload_tuser), + + // AXI output + .output_axis_tdata(tx_fifo_udp_payload_tdata), + .output_axis_tkeep(tx_fifo_udp_payload_tkeep), + .output_axis_tvalid(tx_fifo_udp_payload_tvalid), + .output_axis_tready(tx_fifo_udp_payload_tready), + .output_axis_tlast(tx_fifo_udp_payload_tlast), + .output_axis_tuser(tx_fifo_udp_payload_tuser) +); + +endmodule diff --git a/example/HXT100G/fpga/rtl/gth_i2c_init.v b/example/HXT100G/fpga/rtl/gth_i2c_init.v new file mode 100644 index 00000000..c92e2136 --- /dev/null +++ b/example/HXT100G/fpga/rtl/gth_i2c_init.v @@ -0,0 +1,508 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * gth_i2c_init + */ +module gth_i2c_init ( + input wire clk, + input wire rst, + + /* + * I2C master interface + */ + output wire [6:0] cmd_address, + output wire cmd_start, + output wire cmd_read, + output wire cmd_write, + output wire cmd_write_multiple, + output wire cmd_stop, + output wire cmd_valid, + input wire cmd_ready, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * Status + */ + output wire busy, + + /* + * Configuration + */ + input wire start +); + +/* + +Generic module for I2C bus initialization. Good for use when multiple devices +on an I2C bus must be initialized on system start without intervention of a +general-purpose processor. + +Copy this file and change init_data and INIT_DATA_LEN as needed. + +This module can be used in two modes: simple device initalization, or multiple +device initialization. In multiple device mode, the same initialization sequence +can be performed on multiple different device addresses. + +To use single device mode, only use the start write to address and write data commands. +The module will generate the I2C commands in sequential order. Terminate the list +with a 0 entry. + +To use the multiple device mode, use the start data and start address block commands +to set up lists of initialization data and device addresses. The module enters +multiple device mode upon seeing a start data block command. The module stores the +offset of the start of the data block and then skips ahead until it reaches a start +address block command. The module will store the offset to the address block and +read the first address in the block. Then it will jump back to the data block +and execute it, substituting the stored address for each current address write +command. Upon reaching the start address block command, the module will read out the +next address and start again at the top of the data block. If the module encounters +a start data block command while looking for an address, then it will store a new data +offset and then look for a start address block command. Terminate the list with a 0 +entry. Normal address commands will operate normally inside a data block. + +Commands: + +00 0000000 : stop +00 0000001 : exit multiple device mode +00 0000011 : start write to current address +00 0001000 : start address block +00 0001001 : start data block +01 aaaaaaa : start write to address +1 dddddddd : write 8-bit data + +Examples + +write 0x11223344 to register 0x0004 on device at 0x50 + +01 1010000 start write to 0x50 +1 00000000 write address 0x0004 +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +0 00000000 stop + +write 0x11223344 to register 0x0004 on devices at 0x50, 0x51, 0x52, and 0x53 + +00 0001001 start data block +00 0000011 start write to current address +1 00000100 +1 00010001 write data 0x11223344 +1 00100010 +1 00110011 +1 01000100 +00 0001000 start address block +01 1010000 address 0x50 +01 1010000 address 0x51 +01 1010000 address 0x52 +01 1010000 address 0x53 +00 0000000 stop + +*/ + +// init_data ROM +localparam INIT_DATA_LEN = 68; + +reg [8:0] init_data [INIT_DATA_LEN-1:0]; + +initial begin + // init clock mux registers + init_data[0] = {2'b00, 7'b0001001}; // start data block + init_data[1] = {2'b00, 7'b0000011}; // start write to current address + init_data[2] = {1'b1, 8'd2}; // select PLL bandwidth + //init_data[3] = {1'b1, 8'hA2}; + init_data[3] = {1'b1, 8'hA0}; + init_data[4] = {2'b00, 7'b0000011}; // start write to current address + init_data[5] = {1'b1, 8'd3}; // disable outputs during ICAL + //init_data[6] = {1'b1, 8'h15}; + init_data[6] = {1'b1, 8'h10}; + init_data[7] = {2'b00, 7'b0000011}; // start write to current address + init_data[8] = {1'b1, 8'd5}; // set CLKOUT1 and CLKOUT2 to LVPECL + init_data[9] = {1'b1, 8'hED}; + init_data[10] = {2'b00, 7'b0000011}; // start write to current address + init_data[11] = {1'b1, 8'd6}; // set CLKOUT3 to LVPECL and CLKOUT4 to LVDS + //init_data[12] = {1'b1, 8'h2D}; + init_data[12] = {1'b1, 8'h3D}; + init_data[13] = {2'b00, 7'b0000011}; // start write to current address + init_data[14] = {1'b1, 8'd7}; // set CLKOUT5 to to LVDS + //init_data[15] = {1'b1, 8'h0A}; + init_data[15] = {1'b1, 8'h3A}; + init_data[16] = {2'b00, 7'b0000011}; // start write to current address + init_data[17] = {1'b1, 8'd20}; // enable LOL output + init_data[18] = {1'b1, 8'h3E}; + init_data[19] = {2'b00, 7'b0000011}; // start write to current address + init_data[20] = {1'b1, 8'd25}; // N1_HS + init_data[21] = {1'b1, 8'h40}; + init_data[22] = {2'b00, 7'b0000011}; // start write to current address + init_data[23] = {1'b1, 8'd27}; // NC1_LS + init_data[24] = {1'b1, 8'h05}; + init_data[25] = {2'b00, 7'b0000011}; // start write to current address + init_data[26] = {1'b1, 8'd30}; // NC2_LS + init_data[27] = {1'b1, 8'h05}; + init_data[28] = {2'b00, 7'b0000011}; // start write to current address + init_data[29] = {1'b1, 8'd33}; // NC3_LS + init_data[30] = {1'b1, 8'h05}; + init_data[31] = {2'b00, 7'b0000011}; // start write to current address + init_data[32] = {1'b1, 8'd36}; // NC4_LS + init_data[33] = {1'b1, 8'h05}; + init_data[34] = {2'b00, 7'b0000011}; // start write to current address + init_data[35] = {1'b1, 8'd39}; // NC5_LS + init_data[36] = {1'b1, 8'h05}; + init_data[37] = {2'b00, 7'b0000011}; // start write to current address + init_data[38] = {1'b1, 8'd40}; // N2_HS + init_data[39] = {1'b1, 8'hA0}; + init_data[40] = {2'b00, 7'b0000011}; // start write to current address + init_data[41] = {1'b1, 8'd41}; // N2_LS + init_data[42] = {1'b1, 8'h01}; + init_data[43] = {2'b00, 7'b0000011}; // start write to current address + init_data[44] = {1'b1, 8'd42}; // N2_LS + init_data[45] = {1'b1, 8'h3B}; + init_data[46] = {2'b00, 7'b0000011}; // start write to current address + init_data[47] = {1'b1, 8'd45}; // N31 + init_data[48] = {1'b1, 8'h4E}; + init_data[49] = {2'b00, 7'b0000011}; // start write to current address + init_data[50] = {1'b1, 8'd48}; // N32 + init_data[51] = {1'b1, 8'h4E}; + init_data[52] = {2'b00, 7'b0000011}; // start write to current address + init_data[53] = {1'b1, 8'd51}; // N33 + init_data[54] = {1'b1, 8'h4E}; + init_data[55] = {2'b00, 7'b0000011}; // start write to current address + init_data[56] = {1'b1, 8'd54}; // N34 + init_data[57] = {1'b1, 8'h4E}; + init_data[58] = {2'b00, 7'b0000011}; // start write to current address + init_data[59] = {1'b1, 8'd141}; // Zero independent skew + init_data[60] = {1'b1, 8'h00}; + init_data[61] = {2'b00, 7'b0000011}; // start write to current address + init_data[62] = {1'b1, 8'd136}; // Soft reset + init_data[63] = {1'b1, 8'h40}; + init_data[64] = {2'b00, 7'b0001000}; // start address block + init_data[65] = {2'b01, 7'b1101001}; // first clock mux + init_data[66] = {2'b01, 7'b1101000}; // second clock mux + init_data[67] = 9'd0; // stop +end + +localparam [3:0] + STATE_IDLE = 3'd0, + STATE_RUN = 3'd1, + STATE_TABLE_1 = 3'd2, + STATE_TABLE_2 = 3'd3, + STATE_TABLE_3 = 3'd4; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +parameter AW = $clog2(INIT_DATA_LEN); + +reg [8:0] init_data_reg = 9'd0; + +reg [AW-1:0] address_reg = {AW{1'b0}}, address_next; +reg [AW-1:0] address_ptr_reg = {AW{1'b0}}, address_ptr_next; +reg [AW-1:0] data_ptr_reg = {AW{1'b0}}, data_ptr_next; + +reg [6:0] cur_address_reg = 7'd0, cur_address_next; + +reg [6:0] cmd_address_reg = 7'd0, cmd_address_next; +reg cmd_start_reg = 1'b0, cmd_start_next; +reg cmd_write_reg = 1'b0, cmd_write_next; +reg cmd_stop_reg = 1'b0, cmd_stop_next; +reg cmd_valid_reg = 1'b0, cmd_valid_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; + +reg start_flag_reg = 1'b0, start_flag_next; + +reg busy_reg = 1'b0; + +assign cmd_address = cmd_address_reg; +assign cmd_start = cmd_start_reg; +assign cmd_read = 1'b0; +assign cmd_write = cmd_write_reg; +assign cmd_write_multiple = 1'b0; +assign cmd_stop = cmd_stop_reg; +assign cmd_valid = cmd_valid_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = 1'b1; + +assign busy = busy_reg; + +always @* begin + state_next = STATE_IDLE; + + address_next = address_reg; + address_ptr_next = address_ptr_reg; + data_ptr_next = data_ptr_reg; + + cur_address_next = cur_address_reg; + + cmd_address_next = cmd_address_reg; + cmd_start_next = cmd_start_reg & ~(cmd_valid & cmd_ready); + cmd_write_next = cmd_write_reg & ~(cmd_valid & cmd_ready); + cmd_stop_next = cmd_stop_reg & ~(cmd_valid & cmd_ready); + cmd_valid_next = cmd_valid_reg & ~cmd_ready; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + + start_flag_next = start_flag_reg; + + if (cmd_valid | data_out_valid) begin + // wait for output registers to clear + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // wait for start signal + if (~start_flag_reg & start) begin + address_next = {AW{1'b0}}; + start_flag_next = 1'b1; + state_next = STATE_RUN; + end else begin + state_next = STATE_IDLE; + end + end + STATE_RUN: begin + // process commands + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_RUN; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_RUN; + end + end + STATE_TABLE_1: begin + // find address table start + if (init_data_reg == 9'b000001000) begin + // address table start + address_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end + end + STATE_TABLE_2: begin + // find next address + if (init_data_reg[8:7] == 2'b01) begin + // write address command + // store address and move to data table + cur_address_next = init_data_reg[6:0]; + address_ptr_next = address_reg + 1; + address_next = data_ptr_reg; + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_2; + end + end + STATE_TABLE_3: begin + // process data table with selected address + if (init_data_reg[8] == 1'b1) begin + // write data + cmd_write_next = 1'b1; + cmd_stop_next = 1'b0; + cmd_valid_next = 1'b1; + + data_out_next = init_data_reg[7:0]; + data_out_valid_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg[8:7] == 2'b01) begin + // write address + cmd_address_next = init_data_reg[6:0]; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000000011) begin + // write current address + cmd_address_next = cur_address_reg; + cmd_start_next = 1'b1; + + address_next = address_reg + 1; + + state_next = STATE_TABLE_3; + end else if (init_data_reg == 9'b000001001) begin + // data table start + data_ptr_next = address_reg + 1; + address_next = address_reg + 1; + state_next = STATE_TABLE_1; + end else if (init_data_reg == 9'b000001000) begin + // address table start + address_next = address_ptr_reg; + state_next = STATE_TABLE_2; + end else if (init_data_reg == 9'd1) begin + // exit mode + address_next = address_reg + 1; + state_next = STATE_RUN; + end else if (init_data_reg == 9'd0) begin + // stop + cmd_start_next = 1'b0; + cmd_write_next = 1'b0; + cmd_stop_next = 1'b1; + cmd_valid_next = 1'b1; + + state_next = STATE_IDLE; + end else begin + // invalid command, skip + address_next = address_reg + 1; + state_next = STATE_TABLE_3; + end + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + + init_data_reg <= 9'd0; + + address_reg <= {AW{1'b0}}; + address_ptr_reg <= {AW{1'b0}}; + data_ptr_reg <= {AW{1'b0}}; + + cur_address_reg <= 7'd0; + + cmd_valid_reg <= 1'b0; + + data_out_valid_reg <= 1'b0; + + start_flag_reg <= 1'b0; + + busy_reg <= 1'b0; + end else begin + state_reg <= state_next; + + // read init_data ROM + init_data_reg <= init_data[address_next]; + + address_reg <= address_next; + address_ptr_reg <= address_ptr_next; + data_ptr_reg <= data_ptr_next; + + cur_address_reg <= cur_address_next; + + cmd_valid_reg <= cmd_valid_next; + + data_out_valid_reg <= data_out_valid_next; + + start_flag_reg <= start & start_flag_next; + + busy_reg <= (state_reg != STATE_IDLE); + end + + cmd_address_reg <= cmd_address_next; + cmd_start_reg <= cmd_start_next; + cmd_write_reg <= cmd_write_next; + cmd_stop_reg <= cmd_stop_next; + + data_out_reg <= data_out_next; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/i2c_master.v b/example/HXT100G/fpga/rtl/i2c_master.v new file mode 100644 index 00000000..4a6b945c --- /dev/null +++ b/example/HXT100G/fpga/rtl/i2c_master.v @@ -0,0 +1,895 @@ +/* + +Copyright (c) 2015-2016 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 + +/* + * I2C master + */ +module i2c_master ( + input wire clk, + input wire rst, + + /* + * Host interface + */ + input wire [6:0] cmd_address, + input wire cmd_start, + input wire cmd_read, + input wire cmd_write, + input wire cmd_write_multiple, + input wire cmd_stop, + input wire cmd_valid, + output wire cmd_ready, + + input wire [7:0] data_in, + input wire data_in_valid, + output wire data_in_ready, + input wire data_in_last, + + output wire [7:0] data_out, + output wire data_out_valid, + input wire data_out_ready, + output wire data_out_last, + + /* + * I2C interface + */ + input wire scl_i, + output wire scl_o, + output wire scl_t, + input wire sda_i, + output wire sda_o, + output wire sda_t, + + /* + * Status + */ + output wire busy, + output wire bus_control, + output wire bus_active, + output wire missed_ack, + + /* + * Configuration + */ + input wire [15:0] prescale, + input wire stop_on_idle +); + +/* + +I2C + +Read + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_\_R___A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A____/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Write + __ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ +sda \__/_6_X_5_X_4_X_3_X_2_X_1_X_0_/_W_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_\_A_/_7_X_6_X_5_X_4_X_3_X_2_X_1_X_0_/_N_\__/ + ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ +scl ST \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ SP + +Commands: + +read + read data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with write or different address + set stop to issue a stop condition after reading current byte + if stop is set with read command, then data_out_last will be set + +write + write data byte + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing current byte + +write multiple + write multiple data bytes (until data_in_last) + set start to force generation of a start condition + start is implied when bus is inactive or active with read or different address + set stop to issue a stop condition after writing block + +stop + issue stop condition if bus is active + +Status: + +busy + module is communicating over the bus + +bus_control + module has control of bus in active state + +bus_active + bus is active, not necessarily controlled by this module + +missed_ack + strobed when a slave ack is missed + +Parameters: + +prescale + set prescale to 1/4 of the minimum clock period in units + of input clk cycles (prescale = Fclk / (FI2Cclk * 4)) + +stop_on_idle + automatically issue stop when command input is not valid + +Example of interfacing with tristate pins: +(this will work for any tristate bus) + +assign scl_i = scl_pin; +assign scl_pin = scl_t ? 1'bz : scl_o; +assign sda_i = sda_pin; +assign sda_pin = sda_t ? 1'bz : sda_o; + +Equivalent code that does not use *_t connections: +(we can get away with this because I2C is open-drain) + +assign scl_i = scl_pin; +assign scl_pin = scl_o ? 1'bz : 1'b0; +assign sda_i = sda_pin; +assign sda_pin = sda_o ? 1'bz : 1'b0; + +Example of two interconnected I2C devices: + +assign scl_1_i = scl_1_o & scl_2_o; +assign scl_2_i = scl_1_o & scl_2_o; +assign sda_1_i = sda_1_o & sda_2_o; +assign sda_2_i = sda_1_o & sda_2_o; + +Example of two I2C devices sharing the same pins: + +assign scl_1_i = scl_pin; +assign scl_2_i = scl_pin; +assign scl_pin = (scl_1_o & scl_2_o) ? 1'bz : 1'b0; +assign sda_1_i = sda_pin; +assign sda_2_i = sda_pin; +assign sda_pin = (sda_1_o & sda_2_o) ? 1'bz : 1'b0; + +Notes: + +scl_o should not be connected directly to scl_i, only via AND logic or a tristate +I/O pin. This would prevent devices from stretching the clock period. + +*/ + +localparam [4:0] + STATE_IDLE = 4'd0, + STATE_ACTIVE_WRITE = 4'd1, + STATE_ACTIVE_READ = 4'd2, + STATE_START_WAIT = 4'd3, + STATE_START = 4'd4, + STATE_ADDRESS_1 = 4'd5, + STATE_ADDRESS_2 = 4'd6, + STATE_WRITE_1 = 4'd7, + STATE_WRITE_2 = 4'd8, + STATE_WRITE_3 = 4'd9, + STATE_READ = 4'd10, + STATE_STOP = 4'd11; + +reg [4:0] state_reg = STATE_IDLE, state_next; + +localparam [4:0] + PHY_STATE_IDLE = 5'd0, + PHY_STATE_ACTIVE = 5'd1, + PHY_STATE_REPEATED_START_1 = 5'd2, + PHY_STATE_REPEATED_START_2 = 5'd3, + PHY_STATE_START_1 = 5'd4, + PHY_STATE_START_2 = 5'd5, + PHY_STATE_WRITE_BIT_1 = 5'd6, + PHY_STATE_WRITE_BIT_2 = 5'd7, + PHY_STATE_WRITE_BIT_3 = 5'd8, + PHY_STATE_READ_BIT_1 = 5'd9, + PHY_STATE_READ_BIT_2 = 5'd10, + PHY_STATE_READ_BIT_3 = 5'd11, + PHY_STATE_READ_BIT_4 = 5'd12, + PHY_STATE_STOP_1 = 5'd13, + PHY_STATE_STOP_2 = 5'd14, + PHY_STATE_STOP_3 = 5'd15; + +reg [4:0] phy_state_reg = STATE_IDLE, phy_state_next; + +reg phy_start_bit; +reg phy_stop_bit; +reg phy_write_bit; +reg phy_read_bit; +reg phy_release_bus; + +reg phy_tx_data; + +reg phy_rx_data_reg = 1'b0, phy_rx_data_next; + +reg [6:0] addr_reg = 7'd0, addr_next; +reg [7:0] data_reg = 8'd0, data_next; +reg last_reg = 1'b0, last_next; + +reg mode_read_reg = 1'b0, mode_read_next; +reg mode_write_multiple_reg = 1'b0, mode_write_multiple_next; +reg mode_stop_reg = 1'b0, mode_stop_next; + +reg [16:0] delay_reg = 16'd0, delay_next; +reg delay_scl_reg = 1'b0, delay_scl_next; +reg delay_sda_reg = 1'b0, delay_sda_next; + +reg [3:0] bit_count_reg = 4'd0, bit_count_next; + +reg cmd_ready_reg = 1'b0, cmd_ready_next; + +reg data_in_ready_reg = 1'b0, data_in_ready_next; + +reg [7:0] data_out_reg = 8'd0, data_out_next; +reg data_out_valid_reg = 1'b0, data_out_valid_next; +reg data_out_last_reg = 1'b0, data_out_last_next; + +reg scl_i_reg = 1'b1; +reg sda_i_reg = 1'b1; + +reg scl_o_reg = 1'b1, scl_o_next; +reg sda_o_reg = 1'b1, sda_o_next; + +reg last_scl_i_reg = 1'b1; +reg last_sda_i_reg = 1'b1; + +reg busy_reg = 1'b0; +reg bus_active_reg = 1'b0; +reg bus_control_reg = 1'b0, bus_control_next; +reg missed_ack_reg = 1'b0, missed_ack_next; + +assign cmd_ready = cmd_ready_reg; + +assign data_in_ready = data_in_ready_reg; + +assign data_out = data_out_reg; +assign data_out_valid = data_out_valid_reg; +assign data_out_last = data_out_last_reg; + +assign scl_o = scl_o_reg; +assign scl_t = scl_o_reg; +assign sda_o = sda_o_reg; +assign sda_t = sda_o_reg; + +assign busy = busy_reg; +assign bus_active = bus_active_reg; +assign bus_control = bus_control_reg; +assign missed_ack = missed_ack_reg; + +wire scl_posedge = scl_i_reg & ~last_scl_i_reg; +wire scl_negedge = ~scl_i_reg & last_scl_i_reg; +wire sda_posedge = sda_i_reg & ~last_sda_i_reg; +wire sda_negedge = ~sda_i_reg & last_sda_i_reg; + +wire start_bit = sda_negedge & scl_i_reg; +wire stop_bit = sda_posedge & scl_i_reg; + +always @* begin + state_next = STATE_IDLE; + + phy_start_bit = 1'b0; + phy_stop_bit = 1'b0; + phy_write_bit = 1'b0; + phy_read_bit = 1'b0; + phy_tx_data = 1'b0; + phy_release_bus = 1'b0; + + addr_next = addr_reg; + data_next = data_reg; + last_next = last_reg; + + mode_read_next = mode_read_reg; + mode_write_multiple_next = mode_write_multiple_reg; + mode_stop_next = mode_stop_reg; + + bit_count_next = bit_count_reg; + + cmd_ready_next = 1'b0; + + data_in_ready_next = 1'b0; + + data_out_next = data_out_reg; + data_out_valid_next = data_out_valid_reg & ~data_out_ready; + data_out_last_next = data_out_last_reg; + + missed_ack_next = 1'b0; + + // generate delays + if (phy_state_reg != PHY_STATE_IDLE && phy_state_reg != PHY_STATE_ACTIVE) begin + // wait for phy operation + state_next = state_reg; + end else begin + // process states + case (state_reg) + STATE_IDLE: begin + // line idle + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + // start bit + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end else begin + // invalid or unspecified - ignore + state_next = STATE_IDLE; + end + end else begin + state_next = STATE_IDLE; + end + end + STATE_ACTIVE_WRITE: begin + // line active with current address and read/write mode + cmd_ready_next = 1'b1; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_read) begin + // address or mode mismatch or forced start - repeated start + + // repeated start bit + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end else begin + // address and mode match + + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_WRITE; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + state_next = STATE_ACTIVE_WRITE; + end + end + end + STATE_ACTIVE_READ: begin + // line active to current address + cmd_ready_next = ~data_out_valid; + + if (cmd_ready & cmd_valid) begin + // command valid + if (cmd_read ^ (cmd_write | cmd_write_multiple)) begin + // read or write command + addr_next = cmd_address; + mode_read_next = cmd_read; + mode_write_multiple_next = cmd_write_multiple; + mode_stop_next = cmd_stop; + + cmd_ready_next = 1'b0; + + if (cmd_start || cmd_address != addr_reg || cmd_write) begin + // address or mode mismatch or forced start - repeated start + + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // repeated start bit + state_next = STATE_START; + end else begin + // address and mode match + + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b0; + // start next read + bit_count_next = 4'd8; + data_next = 8'd0; + state_next = STATE_READ; + end + end else if (cmd_stop && !(cmd_read || cmd_write || cmd_write_multiple)) begin + // stop command + // write nack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + // invalid or unspecified - ignore + state_next = STATE_ACTIVE_READ; + end + end else begin + if (stop_on_idle & cmd_ready & ~cmd_valid) begin + // no waiting command and stop_on_idle selected, issue stop condition + // write ack for previous read + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + // send stop bit + state_next = STATE_STOP; + end else begin + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_START_WAIT: begin + // wait for bus idle + + if (bus_active) begin + state_next = STATE_START_WAIT; + end else begin + // bus is idle, take control + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + end + STATE_START: begin + // send start bit + + phy_start_bit = 1'b1; + bit_count_next = 4'd8; + state_next = STATE_ADDRESS_1; + end + STATE_ADDRESS_1: begin + // send address + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 1) begin + // send address + phy_write_bit = 1'b1; + phy_tx_data = addr_reg[bit_count_reg-2]; + state_next = STATE_ADDRESS_1; + end else if (bit_count_reg > 0) begin + // send read/write bit + phy_write_bit = 1'b1; + phy_tx_data = mode_read_reg; + state_next = STATE_ADDRESS_1; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_ADDRESS_2; + end + end + STATE_ADDRESS_2: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_read_reg) begin + // start read + bit_count_next = 4'd8; + data_next = 1'b0; + state_next = STATE_READ; + end else begin + // start write + data_in_ready_next = 1'b1; + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_1: begin + data_in_ready_next = 1'b1; + + if (data_in_ready & data_in_valid) begin + // got data, start write + data_next = data_in; + last_next = data_in_last; + bit_count_next = 4'd8; + data_in_ready_next = 1'b0; + state_next = STATE_WRITE_2; + end else begin + // wait for data + state_next = STATE_WRITE_1; + end + end + STATE_WRITE_2: begin + // send data + bit_count_next = bit_count_reg - 1; + if (bit_count_reg > 0) begin + // write data bit + phy_write_bit = 1'b1; + phy_tx_data = data_reg[bit_count_reg-1]; + state_next = STATE_WRITE_2; + end else begin + // read ack bit + phy_read_bit = 1'b1; + state_next = STATE_WRITE_3; + end + end + STATE_WRITE_3: begin + // read ack bit + missed_ack_next = phy_rx_data_reg; + + if (mode_write_multiple_reg && !last_reg) begin + // more to write + state_next = STATE_WRITE_1; + end else if (mode_stop_reg) begin + // last cycle and stop selected + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end else begin + // otherwise, return to bus active state + state_next = STATE_ACTIVE_WRITE; + end + end + STATE_READ: begin + // read data + + bit_count_next = bit_count_reg - 1; + data_next = {data_reg[6:0], phy_rx_data_reg}; + if (bit_count_reg > 0) begin + // read next bit + phy_read_bit = 1'b1; + state_next = STATE_READ; + end else begin + // output data word + data_out_next = data_next; + data_out_valid_next = 1'b1; + data_out_last_next = 1'b0; + if (mode_stop_reg) begin + // send nack and stop + data_out_last_next = 1'b1; + phy_write_bit = 1'b1; + phy_tx_data = 1'b1; + state_next = STATE_STOP; + end else begin + // return to bus active state + state_next = STATE_ACTIVE_READ; + end + end + end + STATE_STOP: begin + // send stop bit + phy_stop_bit = 1'b1; + state_next = STATE_IDLE; + end + endcase + end +end + +always @* begin + phy_state_next = PHY_STATE_IDLE; + + phy_rx_data_next = phy_rx_data_reg; + + delay_next = delay_reg; + delay_scl_next = delay_scl_reg; + delay_sda_next = delay_sda_reg; + + scl_o_next = scl_o_reg; + sda_o_next = sda_o_reg; + + bus_control_next = bus_control_reg; + + if (phy_release_bus) begin + // release bus and return to idle state + sda_o_next = 1'b1; + scl_o_next = 1'b1; + delay_scl_next = 1'b0; + delay_sda_next = 1'b0; + delay_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end else if (delay_scl_reg) begin + // wait for SCL to match command + delay_scl_next = scl_o_reg & ~scl_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_sda_reg) begin + // wait for SDA to match command + delay_sda_next = sda_o_reg & ~sda_i_reg; + phy_state_next = phy_state_reg; + end else if (delay_reg > 0) begin + // time delay + delay_next = delay_reg - 1; + phy_state_next = phy_state_reg; + end else begin + case (phy_state_reg) + PHY_STATE_IDLE: begin + // bus idle - wait for start command + sda_o_next = 1'b1; + scl_o_next = 1'b1; + if (phy_start_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end else begin + phy_state_next = PHY_STATE_IDLE; + end + end + PHY_STATE_ACTIVE: begin + // bus active + if (phy_start_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_1; + end else if (phy_write_bit) begin + sda_o_next = phy_tx_data; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_1; + end else if (phy_read_bit) begin + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_1; + end else if (phy_stop_bit) begin + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_1; + end else begin + phy_state_next = PHY_STATE_ACTIVE; + end + end + PHY_STATE_REPEATED_START_1: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_REPEATED_START_2; + end + PHY_STATE_REPEATED_START_2: begin + // generate repeated start bit + // ______ + // sda XXX/ \_______ + // _______ + // scl ______/ \___ + // + + sda_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_1; + end + PHY_STATE_START_1: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_START_2; + end + PHY_STATE_START_2: begin + // generate start bit + // ___ + // sda \_______ + // _______ + // scl \___ + // + + bus_control_next = 1'b1; + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_WRITE_BIT_1: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale << 1; + phy_state_next = PHY_STATE_WRITE_BIT_2; + end + PHY_STATE_WRITE_BIT_2: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_WRITE_BIT_3; + end + PHY_STATE_WRITE_BIT_3: begin + // write bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_READ_BIT_1: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_2; + end + PHY_STATE_READ_BIT_2: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_rx_data_next = sda_i_reg; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_3; + end + PHY_STATE_READ_BIT_3: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + scl_o_next = 1'b0; + delay_next = prescale; + phy_state_next = PHY_STATE_READ_BIT_4; + end + PHY_STATE_READ_BIT_4: begin + // read bit + // ________ + // sda X________X + // ____ + // scl __/ \__ + + phy_state_next = PHY_STATE_ACTIVE; + end + PHY_STATE_STOP_1: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + scl_o_next = 1'b1; + delay_scl_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_2; + end + PHY_STATE_STOP_2: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + sda_o_next = 1'b1; + delay_next = prescale; + phy_state_next = PHY_STATE_STOP_3; + end + PHY_STATE_STOP_3: begin + // stop bit + // ___ + // sda XXX\_______/ + // _______ + // scl _______/ + + bus_control_next = 1'b0; + phy_state_next = PHY_STATE_IDLE; + end + endcase + end +end + +always @(posedge clk) begin + if (rst) begin + state_reg <= STATE_IDLE; + phy_state_reg <= PHY_STATE_IDLE; + delay_reg <= 16'd0; + delay_scl_reg <= 1'b0; + delay_sda_reg <= 1'b0; + cmd_ready_reg <= 1'b0; + data_in_ready_reg <= 1'b0; + data_out_valid_reg <= 1'b0; + scl_o_reg <= 1'b1; + sda_o_reg <= 1'b1; + busy_reg <= 1'b0; + bus_active_reg <= 1'b0; + bus_control_reg <= 1'b0; + missed_ack_reg <= 1'b0; + end else begin + state_reg <= state_next; + phy_state_reg <= phy_state_next; + + delay_reg <= delay_next; + delay_scl_reg <= delay_scl_next; + delay_sda_reg <= delay_sda_next; + + cmd_ready_reg <= cmd_ready_next; + data_in_ready_reg <= data_in_ready_next; + data_out_valid_reg <= data_out_valid_next; + + scl_o_reg <= scl_o_next; + sda_o_reg <= sda_o_next; + + busy_reg <= !(state_reg == STATE_IDLE || state_reg == STATE_ACTIVE_WRITE || state_reg == STATE_ACTIVE_READ); + + if (start_bit) begin + bus_active_reg <= 1'b1; + end else if (stop_bit) begin + bus_active_reg <= 1'b0; + end else begin + bus_active_reg <= bus_active_reg; + end + + bus_control_reg <= bus_control_next; + missed_ack_reg <= missed_ack_next; + end + + phy_rx_data_reg <= phy_rx_data_next; + + addr_reg <= addr_next; + data_reg <= data_next; + last_reg <= last_next; + + mode_read_reg <= mode_read_next; + mode_write_multiple_reg <= mode_write_multiple_next; + mode_stop_reg <= mode_stop_next; + + bit_count_reg <= bit_count_next; + + data_out_reg <= data_out_next; + data_out_last_reg <= data_out_last_next; + + scl_i_reg <= scl_i; + sda_i_reg <= sda_i; + last_scl_i_reg <= scl_i_reg; + last_sda_i_reg <= sda_i_reg; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/sync_reset.v b/example/HXT100G/fpga/rtl/sync_reset.v new file mode 100644 index 00000000..d74c0337 --- /dev/null +++ b/example/HXT100G/fpga/rtl/sync_reset.v @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2014-2016 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 active-high asynchronous reset signal to a given clock by + * using a pipeline of N registers. + */ +module sync_reset #( + parameter N=2 // depth of synchronizer +)( + input wire clk, + input wire rst, + output wire sync_reset_out +); + +reg [N-1:0] sync_reg = {N{1'b1}}; + +assign sync_reset_out = sync_reg[N-1]; + +always @(posedge clk) begin + if (rst) + sync_reg <= {N{1'b1}}; + else + sync_reg <= {sync_reg[N-2:0], 1'b0}; +end + +endmodule diff --git a/example/HXT100G/fpga/rtl/sync_signal.v b/example/HXT100G/fpga/rtl/sync_signal.v new file mode 100644 index 00000000..5afcd717 --- /dev/null +++ b/example/HXT100G/fpga/rtl/sync_signal.v @@ -0,0 +1,58 @@ +/* + +Copyright (c) 2014-2016 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/example/HXT100G/fpga/tb/arp_ep.py b/example/HXT100G/fpga/tb/arp_ep.py new file mode 120000 index 00000000..7b3d3ed9 --- /dev/null +++ b/example/HXT100G/fpga/tb/arp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/arp_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/axis_ep.py b/example/HXT100G/fpga/tb/axis_ep.py new file mode 120000 index 00000000..385bb030 --- /dev/null +++ b/example/HXT100G/fpga/tb/axis_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/eth_ep.py b/example/HXT100G/fpga/tb/eth_ep.py new file mode 120000 index 00000000..bac19fee --- /dev/null +++ b/example/HXT100G/fpga/tb/eth_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/ip_ep.py b/example/HXT100G/fpga/tb/ip_ep.py new file mode 120000 index 00000000..6dfa928a --- /dev/null +++ b/example/HXT100G/fpga/tb/ip_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py new file mode 100755 index 00000000..ffad6660 --- /dev/null +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -0,0 +1,1117 @@ +#!/usr/bin/env python +""" + +Copyright (c) 2016 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 + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +import eth_ep +import arp_ep +import udp_ep +import xgmii_ep + +module = 'fpga_core' + +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/eth_mac_10g_rx.v") +srcs.append("../lib/eth/rtl/eth_mac_10g_tx.v") +srcs.append("../lib/eth/rtl/eth_crc_8.v") +srcs.append("../lib/eth/rtl/eth_crc_16.v") +srcs.append("../lib/eth/rtl/eth_crc_24.v") +srcs.append("../lib/eth/rtl/eth_crc_32.v") +srcs.append("../lib/eth/rtl/eth_crc_40.v") +srcs.append("../lib/eth/rtl/eth_crc_48.v") +srcs.append("../lib/eth/rtl/eth_crc_56.v") +srcs.append("../lib/eth/rtl/eth_crc_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/udp_complete_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_64_2.v") +srcs.append("../lib/eth/rtl/ip_mux_64_2.v") +srcs.append("../lib/eth/rtl/arp_64.v") +srcs.append("../lib/eth/rtl/arp_cache.v") +srcs.append("../lib/eth/rtl/arp_eth_rx_64.v") +srcs.append("../lib/eth/rtl/arp_eth_tx_64.v") +srcs.append("../lib/eth/rtl/eth_arb_mux_64_2.v") +srcs.append("../lib/eth/rtl/eth_mux_64_2.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_64.v") +srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo_64.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_fpga_core(clk, + rst, + current_test, + + sw, + jp, + led, + + uart_rst, + uart_suspend, + uart_ri, + uart_dcd, + uart_dtr, + uart_dsr, + uart_txd, + uart_rxd, + uart_rts, + uart_cts, + + amh_right_mdc, + amh_right_mdio_i, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_i, + amh_left_mdio_o, + amh_left_mdio_t, + + eth_r0_txd, + eth_r0_txc, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_txd, + eth_r1_txc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_txd, + eth_r2_txc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_txd, + eth_r3_txc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_txd, + eth_r4_txc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_txd, + eth_r5_txc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_txd, + eth_r6_txc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_txd, + eth_r7_txc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_txd, + eth_r8_txc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_txd, + eth_r9_txc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_txd, + eth_r10_txc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_txd, + eth_r11_txc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_txd, + eth_l0_txc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_txd, + eth_l1_txc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_txd, + eth_l2_txc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_txd, + eth_l3_txc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_txd, + eth_l4_txc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_txd, + eth_l5_txc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_txd, + eth_l6_txc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_txd, + eth_l7_txc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_txd, + eth_l8_txc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_txd, + eth_l9_txc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_txd, + eth_l10_txc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_txd, + eth_l11_txc, + eth_l11_rxd, + eth_l11_rxc): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + sw=sw, + jp=jp, + led=led, + + uart_rst=uart_rst, + uart_suspend=uart_suspend, + uart_ri=uart_ri, + uart_dcd=uart_dcd, + uart_dtr=uart_dtr, + uart_dsr=uart_dsr, + uart_txd=uart_txd, + uart_rxd=uart_rxd, + uart_rts=uart_rts, + uart_cts=uart_cts, + + amh_right_mdc=amh_right_mdc, + amh_right_mdio_i=amh_right_mdio_i, + amh_right_mdio_o=amh_right_mdio_o, + amh_right_mdio_t=amh_right_mdio_t, + amh_left_mdc=amh_left_mdc, + amh_left_mdio_i=amh_left_mdio_i, + amh_left_mdio_o=amh_left_mdio_o, + amh_left_mdio_t=amh_left_mdio_t, + + eth_r0_txd=eth_r0_txd, + eth_r0_txc=eth_r0_txc, + eth_r0_rxd=eth_r0_rxd, + eth_r0_rxc=eth_r0_rxc, + eth_r1_txd=eth_r1_txd, + eth_r1_txc=eth_r1_txc, + eth_r1_rxd=eth_r1_rxd, + eth_r1_rxc=eth_r1_rxc, + eth_r2_txd=eth_r2_txd, + eth_r2_txc=eth_r2_txc, + eth_r2_rxd=eth_r2_rxd, + eth_r2_rxc=eth_r2_rxc, + eth_r3_txd=eth_r3_txd, + eth_r3_txc=eth_r3_txc, + eth_r3_rxd=eth_r3_rxd, + eth_r3_rxc=eth_r3_rxc, + eth_r4_txd=eth_r4_txd, + eth_r4_txc=eth_r4_txc, + eth_r4_rxd=eth_r4_rxd, + eth_r4_rxc=eth_r4_rxc, + eth_r5_txd=eth_r5_txd, + eth_r5_txc=eth_r5_txc, + eth_r5_rxd=eth_r5_rxd, + eth_r5_rxc=eth_r5_rxc, + eth_r6_txd=eth_r6_txd, + eth_r6_txc=eth_r6_txc, + eth_r6_rxd=eth_r6_rxd, + eth_r6_rxc=eth_r6_rxc, + eth_r7_txd=eth_r7_txd, + eth_r7_txc=eth_r7_txc, + eth_r7_rxd=eth_r7_rxd, + eth_r7_rxc=eth_r7_rxc, + eth_r8_txd=eth_r8_txd, + eth_r8_txc=eth_r8_txc, + eth_r8_rxd=eth_r8_rxd, + eth_r8_rxc=eth_r8_rxc, + eth_r9_txd=eth_r9_txd, + eth_r9_txc=eth_r9_txc, + eth_r9_rxd=eth_r9_rxd, + eth_r9_rxc=eth_r9_rxc, + eth_r10_txd=eth_r10_txd, + eth_r10_txc=eth_r10_txc, + eth_r10_rxd=eth_r10_rxd, + eth_r10_rxc=eth_r10_rxc, + eth_r11_txd=eth_r11_txd, + eth_r11_txc=eth_r11_txc, + eth_r11_rxd=eth_r11_rxd, + eth_r11_rxc=eth_r11_rxc, + eth_l0_txd=eth_l0_txd, + eth_l0_txc=eth_l0_txc, + eth_l0_rxd=eth_l0_rxd, + eth_l0_rxc=eth_l0_rxc, + eth_l1_txd=eth_l1_txd, + eth_l1_txc=eth_l1_txc, + eth_l1_rxd=eth_l1_rxd, + eth_l1_rxc=eth_l1_rxc, + eth_l2_txd=eth_l2_txd, + eth_l2_txc=eth_l2_txc, + eth_l2_rxd=eth_l2_rxd, + eth_l2_rxc=eth_l2_rxc, + eth_l3_txd=eth_l3_txd, + eth_l3_txc=eth_l3_txc, + eth_l3_rxd=eth_l3_rxd, + eth_l3_rxc=eth_l3_rxc, + eth_l4_txd=eth_l4_txd, + eth_l4_txc=eth_l4_txc, + eth_l4_rxd=eth_l4_rxd, + eth_l4_rxc=eth_l4_rxc, + eth_l5_txd=eth_l5_txd, + eth_l5_txc=eth_l5_txc, + eth_l5_rxd=eth_l5_rxd, + eth_l5_rxc=eth_l5_rxc, + eth_l6_txd=eth_l6_txd, + eth_l6_txc=eth_l6_txc, + eth_l6_rxd=eth_l6_rxd, + eth_l6_rxc=eth_l6_rxc, + eth_l7_txd=eth_l7_txd, + eth_l7_txc=eth_l7_txc, + eth_l7_rxd=eth_l7_rxd, + eth_l7_rxc=eth_l7_rxc, + eth_l8_txd=eth_l8_txd, + eth_l8_txc=eth_l8_txc, + eth_l8_rxd=eth_l8_rxd, + eth_l8_rxc=eth_l8_rxc, + eth_l9_txd=eth_l9_txd, + eth_l9_txc=eth_l9_txc, + eth_l9_rxd=eth_l9_rxd, + eth_l9_rxc=eth_l9_rxc, + eth_l10_txd=eth_l10_txd, + eth_l10_txc=eth_l10_txc, + eth_l10_rxd=eth_l10_rxd, + eth_l10_rxc=eth_l10_rxc, + eth_l11_txd=eth_l11_txd, + eth_l11_txc=eth_l11_txc, + eth_l11_rxd=eth_l11_rxd, + eth_l11_rxc=eth_l11_rxc) + +def bench(): + + # Parameters + + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + sw = Signal(intbv(0)[2:]) + jp = Signal(intbv(0)[4:]) + uart_suspend = Signal(bool(0)) + uart_dtr = Signal(bool(0)) + uart_txd = Signal(bool(0)) + uart_rts = Signal(bool(0)) + amh_right_mdio_i = Signal(bool(0)) + amh_left_mdio_i = Signal(bool(0)) + eth_r0_rxd = Signal(intbv(0)[64:]) + eth_r0_rxc = Signal(intbv(0)[8:]) + eth_r1_rxd = Signal(intbv(0)[64:]) + eth_r1_rxc = Signal(intbv(0)[8:]) + eth_r2_rxd = Signal(intbv(0)[64:]) + eth_r2_rxc = Signal(intbv(0)[8:]) + eth_r3_rxd = Signal(intbv(0)[64:]) + eth_r3_rxc = Signal(intbv(0)[8:]) + eth_r4_rxd = Signal(intbv(0)[64:]) + eth_r4_rxc = Signal(intbv(0)[8:]) + eth_r5_rxd = Signal(intbv(0)[64:]) + eth_r5_rxc = Signal(intbv(0)[8:]) + eth_r6_rxd = Signal(intbv(0)[64:]) + eth_r6_rxc = Signal(intbv(0)[8:]) + eth_r7_rxd = Signal(intbv(0)[64:]) + eth_r7_rxc = Signal(intbv(0)[8:]) + eth_r8_rxd = Signal(intbv(0)[64:]) + eth_r8_rxc = Signal(intbv(0)[8:]) + eth_r9_rxd = Signal(intbv(0)[64:]) + eth_r9_rxc = Signal(intbv(0)[8:]) + eth_r10_rxd = Signal(intbv(0)[64:]) + eth_r10_rxc = Signal(intbv(0)[8:]) + eth_r11_rxd = Signal(intbv(0)[64:]) + eth_r11_rxc = Signal(intbv(0)[8:]) + eth_l0_rxd = Signal(intbv(0)[64:]) + eth_l0_rxc = Signal(intbv(0)[8:]) + eth_l1_rxd = Signal(intbv(0)[64:]) + eth_l1_rxc = Signal(intbv(0)[8:]) + eth_l2_rxd = Signal(intbv(0)[64:]) + eth_l2_rxc = Signal(intbv(0)[8:]) + eth_l3_rxd = Signal(intbv(0)[64:]) + eth_l3_rxc = Signal(intbv(0)[8:]) + eth_l4_rxd = Signal(intbv(0)[64:]) + eth_l4_rxc = Signal(intbv(0)[8:]) + eth_l5_rxd = Signal(intbv(0)[64:]) + eth_l5_rxc = Signal(intbv(0)[8:]) + eth_l6_rxd = Signal(intbv(0)[64:]) + eth_l6_rxc = Signal(intbv(0)[8:]) + eth_l7_rxd = Signal(intbv(0)[64:]) + eth_l7_rxc = Signal(intbv(0)[8:]) + eth_l8_rxd = Signal(intbv(0)[64:]) + eth_l8_rxc = Signal(intbv(0)[8:]) + eth_l9_rxd = Signal(intbv(0)[64:]) + eth_l9_rxc = Signal(intbv(0)[8:]) + eth_l10_rxd = Signal(intbv(0)[64:]) + eth_l10_rxc = Signal(intbv(0)[8:]) + eth_l11_rxd = Signal(intbv(0)[64:]) + eth_l11_rxc = Signal(intbv(0)[8:]) + + # Outputs + led = Signal(intbv(0)[4:]) + uart_rst = Signal(bool(0)) + uart_ri = Signal(bool(0)) + uart_dcd = Signal(bool(0)) + uart_dsr = Signal(bool(0)) + uart_rxd = Signal(bool(1)) + uart_cts = Signal(bool(0)) + amh_right_mdc = Signal(bool(1)) + amh_right_mdio_o = Signal(bool(1)) + amh_right_mdio_t = Signal(bool(1)) + amh_left_mdc = Signal(bool(1)) + amh_left_mdio_o = Signal(bool(1)) + amh_left_mdio_t = Signal(bool(1)) + eth_r0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r0_txc = Signal(intbv(0xff)[8:]) + eth_r1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r1_txc = Signal(intbv(0xff)[8:]) + eth_r2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r2_txc = Signal(intbv(0xff)[8:]) + eth_r3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r3_txc = Signal(intbv(0xff)[8:]) + eth_r4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r4_txc = Signal(intbv(0xff)[8:]) + eth_r5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r5_txc = Signal(intbv(0xff)[8:]) + eth_r6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r6_txc = Signal(intbv(0xff)[8:]) + eth_r7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r7_txc = Signal(intbv(0xff)[8:]) + eth_r8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r8_txc = Signal(intbv(0xff)[8:]) + eth_r9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r9_txc = Signal(intbv(0xff)[8:]) + eth_r10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r10_txc = Signal(intbv(0xff)[8:]) + eth_r11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_r11_txc = Signal(intbv(0xff)[8:]) + eth_l0_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l0_txc = Signal(intbv(0xff)[8:]) + eth_l1_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l1_txc = Signal(intbv(0xff)[8:]) + eth_l2_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l2_txc = Signal(intbv(0xff)[8:]) + eth_l3_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l3_txc = Signal(intbv(0xff)[8:]) + eth_l4_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l4_txc = Signal(intbv(0xff)[8:]) + eth_l5_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l5_txc = Signal(intbv(0xff)[8:]) + eth_l6_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l6_txc = Signal(intbv(0xff)[8:]) + eth_l7_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l7_txc = Signal(intbv(0xff)[8:]) + eth_l8_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l8_txc = Signal(intbv(0xff)[8:]) + eth_l9_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l9_txc = Signal(intbv(0xff)[8:]) + eth_l10_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l10_txc = Signal(intbv(0xff)[8:]) + eth_l11_txd = Signal(intbv(0x0707070707070707)[64:]) + eth_l11_txc = Signal(intbv(0xff)[8:]) + + # sources and sinks + eth_r0_source_queue = Queue() + eth_r0_sink_queue = Queue() + eth_r1_source_queue = Queue() + eth_r1_sink_queue = Queue() + eth_r2_source_queue = Queue() + eth_r2_sink_queue = Queue() + eth_r3_source_queue = Queue() + eth_r3_sink_queue = Queue() + eth_r4_source_queue = Queue() + eth_r4_sink_queue = Queue() + eth_r5_source_queue = Queue() + eth_r5_sink_queue = Queue() + eth_r6_source_queue = Queue() + eth_r6_sink_queue = Queue() + eth_r7_source_queue = Queue() + eth_r7_sink_queue = Queue() + eth_r8_source_queue = Queue() + eth_r8_sink_queue = Queue() + eth_r9_source_queue = Queue() + eth_r9_sink_queue = Queue() + eth_r10_source_queue = Queue() + eth_r10_sink_queue = Queue() + eth_r11_source_queue = Queue() + eth_r11_sink_queue = Queue() + eth_l0_source_queue = Queue() + eth_l0_sink_queue = Queue() + eth_l1_source_queue = Queue() + eth_l1_sink_queue = Queue() + eth_l2_source_queue = Queue() + eth_l2_sink_queue = Queue() + eth_l3_source_queue = Queue() + eth_l3_sink_queue = Queue() + eth_l4_source_queue = Queue() + eth_l4_sink_queue = Queue() + eth_l5_source_queue = Queue() + eth_l5_sink_queue = Queue() + eth_l6_source_queue = Queue() + eth_l6_sink_queue = Queue() + eth_l7_source_queue = Queue() + eth_l7_sink_queue = Queue() + eth_l8_source_queue = Queue() + eth_l8_sink_queue = Queue() + eth_l9_source_queue = Queue() + eth_l9_sink_queue = Queue() + eth_l10_source_queue = Queue() + eth_l10_sink_queue = Queue() + eth_l11_source_queue = Queue() + eth_l11_sink_queue = Queue() + + eth_r0_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r0_rxd, + txc=eth_r0_rxc, + fifo=eth_r0_source_queue, + name='eth_r0_source') + + eth_r0_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r0_txd, + rxc=eth_r0_txc, + fifo=eth_r0_sink_queue, + name='eth_r0_sink') + + eth_r1_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r1_rxd, + txc=eth_r1_rxc, + fifo=eth_r1_source_queue, + name='eth_r1_source') + + eth_r1_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r1_txd, + rxc=eth_r1_txc, + fifo=eth_r1_sink_queue, + name='eth_r1_sink') + + eth_r2_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r2_rxd, + txc=eth_r2_rxc, + fifo=eth_r2_source_queue, + name='eth_r2_source') + + eth_r2_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r2_txd, + rxc=eth_r2_txc, + fifo=eth_r2_sink_queue, + name='eth_r2_sink') + + eth_r3_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r3_rxd, + txc=eth_r3_rxc, + fifo=eth_r3_source_queue, + name='eth_r3_source') + + eth_r3_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r3_txd, + rxc=eth_r3_txc, + fifo=eth_r3_sink_queue, + name='eth_r3_sink') + + eth_r4_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r4_rxd, + txc=eth_r4_rxc, + fifo=eth_r4_source_queue, + name='eth_r4_source') + + eth_r4_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r4_txd, + rxc=eth_r4_txc, + fifo=eth_r4_sink_queue, + name='eth_r4_sink') + + eth_r5_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r5_rxd, + txc=eth_r5_rxc, + fifo=eth_r5_source_queue, + name='eth_r5_source') + + eth_r5_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r5_txd, + rxc=eth_r5_txc, + fifo=eth_r5_sink_queue, + name='eth_r5_sink') + + eth_r6_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r6_rxd, + txc=eth_r6_rxc, + fifo=eth_r6_source_queue, + name='eth_r6_source') + + eth_r6_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r6_txd, + rxc=eth_r6_txc, + fifo=eth_r6_sink_queue, + name='eth_r6_sink') + + eth_r7_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r7_rxd, + txc=eth_r7_rxc, + fifo=eth_r7_source_queue, + name='eth_r7_source') + + eth_r7_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r7_txd, + rxc=eth_r7_txc, + fifo=eth_r7_sink_queue, + name='eth_r7_sink') + + eth_r8_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r8_rxd, + txc=eth_r8_rxc, + fifo=eth_r8_source_queue, + name='eth_r8_source') + + eth_r8_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r8_txd, + rxc=eth_r8_txc, + fifo=eth_r8_sink_queue, + name='eth_r8_sink') + + eth_r9_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r9_rxd, + txc=eth_r9_rxc, + fifo=eth_r9_source_queue, + name='eth_r9_source') + + eth_r9_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r9_txd, + rxc=eth_r9_txc, + fifo=eth_r9_sink_queue, + name='eth_r9_sink') + + eth_r10_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r10_rxd, + txc=eth_r10_rxc, + fifo=eth_r10_source_queue, + name='eth_r10_source') + + eth_r10_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r10_txd, + rxc=eth_r10_txc, + fifo=eth_r10_sink_queue, + name='eth_r10_sink') + + eth_r11_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_r11_rxd, + txc=eth_r11_rxc, + fifo=eth_r11_source_queue, + name='eth_r11_source') + + eth_r11_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_r11_txd, + rxc=eth_r11_txc, + fifo=eth_r11_sink_queue, + name='eth_r11_sink') + + eth_l0_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l0_rxd, + txc=eth_l0_rxc, + fifo=eth_l0_source_queue, + name='eth_l0_source') + + eth_l0_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l0_txd, + rxc=eth_l0_txc, + fifo=eth_l0_sink_queue, + name='eth_l0_sink') + + eth_l1_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l1_rxd, + txc=eth_l1_rxc, + fifo=eth_l1_source_queue, + name='eth_l1_source') + + eth_l1_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l1_txd, + rxc=eth_l1_txc, + fifo=eth_l1_sink_queue, + name='eth_l1_sink') + + eth_l2_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l2_rxd, + txc=eth_l2_rxc, + fifo=eth_l2_source_queue, + name='eth_l2_source') + + eth_l2_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l2_txd, + rxc=eth_l2_txc, + fifo=eth_l2_sink_queue, + name='eth_l2_sink') + + eth_l3_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l3_rxd, + txc=eth_l3_rxc, + fifo=eth_l3_source_queue, + name='eth_l3_source') + + eth_l3_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l3_txd, + rxc=eth_l3_txc, + fifo=eth_l3_sink_queue, + name='eth_l3_sink') + + eth_l4_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l4_rxd, + txc=eth_l4_rxc, + fifo=eth_l4_source_queue, + name='eth_l4_source') + + eth_l4_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l4_txd, + rxc=eth_l4_txc, + fifo=eth_l4_sink_queue, + name='eth_l4_sink') + + eth_l5_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l5_rxd, + txc=eth_l5_rxc, + fifo=eth_l5_source_queue, + name='eth_l5_source') + + eth_l5_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l5_txd, + rxc=eth_l5_txc, + fifo=eth_l5_sink_queue, + name='eth_l5_sink') + + eth_l6_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l6_rxd, + txc=eth_l6_rxc, + fifo=eth_l6_source_queue, + name='eth_l6_source') + + eth_l6_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l6_txd, + rxc=eth_l6_txc, + fifo=eth_l6_sink_queue, + name='eth_l6_sink') + + eth_l7_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l7_rxd, + txc=eth_l7_rxc, + fifo=eth_l7_source_queue, + name='eth_l7_source') + + eth_l7_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l7_txd, + rxc=eth_l7_txc, + fifo=eth_l7_sink_queue, + name='eth_l7_sink') + + eth_l8_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l8_rxd, + txc=eth_l8_rxc, + fifo=eth_l8_source_queue, + name='eth_l8_source') + + eth_l8_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l8_txd, + rxc=eth_l8_txc, + fifo=eth_l8_sink_queue, + name='eth_l8_sink') + + eth_l9_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l9_rxd, + txc=eth_l9_rxc, + fifo=eth_l9_source_queue, + name='eth_l9_source') + + eth_l9_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l9_txd, + rxc=eth_l9_txc, + fifo=eth_l9_sink_queue, + name='eth_l9_sink') + + eth_l10_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l10_rxd, + txc=eth_l10_rxc, + fifo=eth_l10_source_queue, + name='eth_l10_source') + + eth_l10_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l10_txd, + rxc=eth_l10_txc, + fifo=eth_l10_sink_queue, + name='eth_l10_sink') + + eth_l11_source = xgmii_ep.XGMIISource(clk, + rst, + txd=eth_l11_rxd, + txc=eth_l11_rxc, + fifo=eth_l11_source_queue, + name='eth_l11_source') + + eth_l11_sink = xgmii_ep.XGMIISink(clk, + rst, + rxd=eth_l11_txd, + rxc=eth_l11_txc, + fifo=eth_l11_sink_queue, + name='eth_l11_sink') + + # DUT + dut = dut_fpga_core(clk, + rst, + current_test, + + sw, + jp, + led, + + uart_rst, + uart_suspend, + uart_ri, + uart_dcd, + uart_dtr, + uart_dsr, + uart_txd, + uart_rxd, + uart_rts, + uart_cts, + + amh_right_mdc, + amh_right_mdio_i, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_i, + amh_left_mdio_o, + amh_left_mdio_t, + + eth_r0_txd, + eth_r0_txc, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_txd, + eth_r1_txc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_txd, + eth_r2_txc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_txd, + eth_r3_txc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_txd, + eth_r4_txc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_txd, + eth_r5_txc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_txd, + eth_r6_txc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_txd, + eth_r7_txc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_txd, + eth_r8_txc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_txd, + eth_r9_txc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_txd, + eth_r10_txc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_txd, + eth_r11_txc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_txd, + eth_l0_txc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_txd, + eth_l1_txc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_txd, + eth_l2_txc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_txd, + eth_l3_txc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_txd, + eth_l4_txc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_txd, + eth_l5_txc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_txd, + eth_l6_txc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_txd, + eth_l7_txc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_txd, + eth_l8_txc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_txd, + eth_l9_txc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_txd, + eth_l10_txc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_txd, + eth_l11_txc, + eth_l11_rxd, + eth_l11_rxc) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + 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() + + eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data) + + # wait for ARP request packet + while eth_l0_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_l0_sink_queue.get(False) + 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 + + eth_l0_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data) + + while eth_l0_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_l0_sink_queue.get(False) + 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 eth_l0_source_queue.empty() + assert eth_l0_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return (dut, clkgen, check, eth_r0_source, eth_r0_sink, eth_r1_source, eth_r1_sink, eth_r2_source, eth_r2_sink, + eth_r3_source, eth_r3_sink, eth_r4_source, eth_r4_sink, eth_r5_source, eth_r5_sink, + eth_r6_source, eth_r6_sink, eth_r7_source, eth_r7_sink, eth_r8_source, eth_r8_sink, + eth_r9_source, eth_r9_sink, eth_r10_source, eth_r10_sink, eth_r11_source, eth_r11_sink, + eth_l0_source, eth_l0_sink, eth_l1_source, eth_l1_sink, eth_l2_source, eth_l2_sink, + eth_l3_source, eth_l3_sink, eth_l4_source, eth_l4_sink, eth_l5_source, eth_l5_sink, + eth_l6_source, eth_l6_sink, eth_l7_source, eth_l7_sink, eth_l8_source, eth_l8_sink, + eth_l9_source, eth_l9_sink, eth_l10_source, eth_l10_sink, eth_l11_source, eth_l11_sink) + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() diff --git a/example/HXT100G/fpga/tb/test_fpga_core.v b/example/HXT100G/fpga/tb/test_fpga_core.v new file mode 100644 index 00000000..7ce2dfa9 --- /dev/null +++ b/example/HXT100G/fpga/tb/test_fpga_core.v @@ -0,0 +1,412 @@ +/* + +Copyright (c) 2016 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 [1:0] sw = 0; +reg [3:0] jp = 0; +reg uart_suspend = 0; +reg uart_dtr = 0; +reg uart_txd = 0; +reg uart_rts = 0; +reg amh_right_mdio_i = 0; +reg amh_left_mdio_i = 0; +reg [63:0] eth_r0_rxd = 0; +reg [7:0] eth_r0_rxc = 0; +reg [63:0] eth_r1_rxd = 0; +reg [7:0] eth_r1_rxc = 0; +reg [63:0] eth_r2_rxd = 0; +reg [7:0] eth_r2_rxc = 0; +reg [63:0] eth_r3_rxd = 0; +reg [7:0] eth_r3_rxc = 0; +reg [63:0] eth_r4_rxd = 0; +reg [7:0] eth_r4_rxc = 0; +reg [63:0] eth_r5_rxd = 0; +reg [7:0] eth_r5_rxc = 0; +reg [63:0] eth_r6_rxd = 0; +reg [7:0] eth_r6_rxc = 0; +reg [63:0] eth_r7_rxd = 0; +reg [7:0] eth_r7_rxc = 0; +reg [63:0] eth_r8_rxd = 0; +reg [7:0] eth_r8_rxc = 0; +reg [63:0] eth_r9_rxd = 0; +reg [7:0] eth_r9_rxc = 0; +reg [63:0] eth_r10_rxd = 0; +reg [7:0] eth_r10_rxc = 0; +reg [63:0] eth_r11_rxd = 0; +reg [7:0] eth_r11_rxc = 0; +reg [63:0] eth_l0_rxd = 0; +reg [7:0] eth_l0_rxc = 0; +reg [63:0] eth_l1_rxd = 0; +reg [7:0] eth_l1_rxc = 0; +reg [63:0] eth_l2_rxd = 0; +reg [7:0] eth_l2_rxc = 0; +reg [63:0] eth_l3_rxd = 0; +reg [7:0] eth_l3_rxc = 0; +reg [63:0] eth_l4_rxd = 0; +reg [7:0] eth_l4_rxc = 0; +reg [63:0] eth_l5_rxd = 0; +reg [7:0] eth_l5_rxc = 0; +reg [63:0] eth_l6_rxd = 0; +reg [7:0] eth_l6_rxc = 0; +reg [63:0] eth_l7_rxd = 0; +reg [7:0] eth_l7_rxc = 0; +reg [63:0] eth_l8_rxd = 0; +reg [7:0] eth_l8_rxc = 0; +reg [63:0] eth_l9_rxd = 0; +reg [7:0] eth_l9_rxc = 0; +reg [63:0] eth_l10_rxd = 0; +reg [7:0] eth_l10_rxc = 0; +reg [63:0] eth_l11_rxd = 0; +reg [7:0] eth_l11_rxc = 0; + +// Outputs +wire [3:0] led; +wire uart_rst; +wire uart_ri; +wire uart_dcd; +wire uart_dsr; +wire uart_rxd; +wire uart_cts; +wire amh_right_mdc; +wire amh_right_mdio_o; +wire amh_right_mdio_t; +wire amh_left_mdc; +wire amh_left_mdio_o; +wire amh_left_mdio_t; +wire [63:0] eth_r0_txd; +wire [7:0] eth_r0_txc; +wire [63:0] eth_r1_txd; +wire [7:0] eth_r1_txc; +wire [63:0] eth_r2_txd; +wire [7:0] eth_r2_txc; +wire [63:0] eth_r3_txd; +wire [7:0] eth_r3_txc; +wire [63:0] eth_r4_txd; +wire [7:0] eth_r4_txc; +wire [63:0] eth_r5_txd; +wire [7:0] eth_r5_txc; +wire [63:0] eth_r6_txd; +wire [7:0] eth_r6_txc; +wire [63:0] eth_r7_txd; +wire [7:0] eth_r7_txc; +wire [63:0] eth_r8_txd; +wire [7:0] eth_r8_txc; +wire [63:0] eth_r9_txd; +wire [7:0] eth_r9_txc; +wire [63:0] eth_r10_txd; +wire [7:0] eth_r10_txc; +wire [63:0] eth_r11_txd; +wire [7:0] eth_r11_txc; +wire [63:0] eth_l0_txd; +wire [7:0] eth_l0_txc; +wire [63:0] eth_l1_txd; +wire [7:0] eth_l1_txc; +wire [63:0] eth_l2_txd; +wire [7:0] eth_l2_txc; +wire [63:0] eth_l3_txd; +wire [7:0] eth_l3_txc; +wire [63:0] eth_l4_txd; +wire [7:0] eth_l4_txc; +wire [63:0] eth_l5_txd; +wire [7:0] eth_l5_txc; +wire [63:0] eth_l6_txd; +wire [7:0] eth_l6_txc; +wire [63:0] eth_l7_txd; +wire [7:0] eth_l7_txc; +wire [63:0] eth_l8_txd; +wire [7:0] eth_l8_txc; +wire [63:0] eth_l9_txd; +wire [7:0] eth_l9_txc; +wire [63:0] eth_l10_txd; +wire [7:0] eth_l10_txc; +wire [63:0] eth_l11_txd; +wire [7:0] eth_l11_txc; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + sw, + jp, + uart_suspend, + uart_dtr, + uart_txd, + uart_rts, + amh_right_mdio_i, + amh_left_mdio_i, + eth_r0_rxd, + eth_r0_rxc, + eth_r1_rxd, + eth_r1_rxc, + eth_r2_rxd, + eth_r2_rxc, + eth_r3_rxd, + eth_r3_rxc, + eth_r4_rxd, + eth_r4_rxc, + eth_r5_rxd, + eth_r5_rxc, + eth_r6_rxd, + eth_r6_rxc, + eth_r7_rxd, + eth_r7_rxc, + eth_r8_rxd, + eth_r8_rxc, + eth_r9_rxd, + eth_r9_rxc, + eth_r10_rxd, + eth_r10_rxc, + eth_r11_rxd, + eth_r11_rxc, + eth_l0_rxd, + eth_l0_rxc, + eth_l1_rxd, + eth_l1_rxc, + eth_l2_rxd, + eth_l2_rxc, + eth_l3_rxd, + eth_l3_rxc, + eth_l4_rxd, + eth_l4_rxc, + eth_l5_rxd, + eth_l5_rxc, + eth_l6_rxd, + eth_l6_rxc, + eth_l7_rxd, + eth_l7_rxc, + eth_l8_rxd, + eth_l8_rxc, + eth_l9_rxd, + eth_l9_rxc, + eth_l10_rxd, + eth_l10_rxc, + eth_l11_rxd, + eth_l11_rxc); + $to_myhdl(led, + uart_rst, + uart_ri, + uart_dcd, + uart_dsr, + uart_rxd, + uart_cts, + amh_right_mdc, + amh_right_mdio_o, + amh_right_mdio_t, + amh_left_mdc, + amh_left_mdio_o, + amh_left_mdio_t, + eth_r0_txd, + eth_r0_txc, + eth_r1_txd, + eth_r1_txc, + eth_r2_txd, + eth_r2_txc, + eth_r3_txd, + eth_r3_txc, + eth_r4_txd, + eth_r4_txc, + eth_r5_txd, + eth_r5_txc, + eth_r6_txd, + eth_r6_txc, + eth_r7_txd, + eth_r7_txc, + eth_r8_txd, + eth_r8_txc, + eth_r9_txd, + eth_r9_txc, + eth_r10_txd, + eth_r10_txc, + eth_r11_txd, + eth_r11_txc, + eth_l0_txd, + eth_l0_txc, + eth_l1_txd, + eth_l1_txc, + eth_l2_txd, + eth_l2_txc, + eth_l3_txd, + eth_l3_txc, + eth_l4_txd, + eth_l4_txc, + eth_l5_txd, + eth_l5_txc, + eth_l6_txd, + eth_l6_txc, + eth_l7_txd, + eth_l7_txc, + eth_l8_txd, + eth_l8_txc, + eth_l9_txd, + eth_l9_txc, + eth_l10_txd, + eth_l10_txc, + eth_l11_txd, + eth_l11_txc); + + // dump file + $dumpfile("test_fpga_core.lxt"); + $dumpvars(0, test_fpga_core); +end + +fpga_core +UUT ( + .clk(clk), + .rst(rst), + .sw(sw), + .jp(jp), + .led(led), + .uart_rst(uart_rst), + .uart_suspend(uart_suspend), + .uart_ri(uart_ri), + .uart_dcd(uart_dcd), + .uart_dtr(uart_dtr), + .uart_dsr(uart_dsr), + .uart_txd(uart_txd), + .uart_rxd(uart_rxd), + .uart_rts(uart_rts), + .uart_cts(uart_cts), + .amh_right_mdc(amh_right_mdc), + .amh_right_mdio_i(amh_right_mdio_i), + .amh_right_mdio_o(amh_right_mdio_o), + .amh_right_mdio_t(amh_right_mdio_t), + .amh_left_mdc(amh_left_mdc), + .amh_left_mdio_i(amh_left_mdio_i), + .amh_left_mdio_o(amh_left_mdio_o), + .amh_left_mdio_t(amh_left_mdio_t), + .eth_r0_txd(eth_r0_txd), + .eth_r0_txc(eth_r0_txc), + .eth_r0_rxd(eth_r0_rxd), + .eth_r0_rxc(eth_r0_rxc), + .eth_r1_txd(eth_r1_txd), + .eth_r1_txc(eth_r1_txc), + .eth_r1_rxd(eth_r1_rxd), + .eth_r1_rxc(eth_r1_rxc), + .eth_r2_txd(eth_r2_txd), + .eth_r2_txc(eth_r2_txc), + .eth_r2_rxd(eth_r2_rxd), + .eth_r2_rxc(eth_r2_rxc), + .eth_r3_txd(eth_r3_txd), + .eth_r3_txc(eth_r3_txc), + .eth_r3_rxd(eth_r3_rxd), + .eth_r3_rxc(eth_r3_rxc), + .eth_r4_txd(eth_r4_txd), + .eth_r4_txc(eth_r4_txc), + .eth_r4_rxd(eth_r4_rxd), + .eth_r4_rxc(eth_r4_rxc), + .eth_r5_txd(eth_r5_txd), + .eth_r5_txc(eth_r5_txc), + .eth_r5_rxd(eth_r5_rxd), + .eth_r5_rxc(eth_r5_rxc), + .eth_r6_txd(eth_r6_txd), + .eth_r6_txc(eth_r6_txc), + .eth_r6_rxd(eth_r6_rxd), + .eth_r6_rxc(eth_r6_rxc), + .eth_r7_txd(eth_r7_txd), + .eth_r7_txc(eth_r7_txc), + .eth_r7_rxd(eth_r7_rxd), + .eth_r7_rxc(eth_r7_rxc), + .eth_r8_txd(eth_r8_txd), + .eth_r8_txc(eth_r8_txc), + .eth_r8_rxd(eth_r8_rxd), + .eth_r8_rxc(eth_r8_rxc), + .eth_r9_txd(eth_r9_txd), + .eth_r9_txc(eth_r9_txc), + .eth_r9_rxd(eth_r9_rxd), + .eth_r9_rxc(eth_r9_rxc), + .eth_r10_txd(eth_r10_txd), + .eth_r10_txc(eth_r10_txc), + .eth_r10_rxd(eth_r10_rxd), + .eth_r10_rxc(eth_r10_rxc), + .eth_r11_txd(eth_r11_txd), + .eth_r11_txc(eth_r11_txc), + .eth_r11_rxd(eth_r11_rxd), + .eth_r11_rxc(eth_r11_rxc), + .eth_l0_txd(eth_l0_txd), + .eth_l0_txc(eth_l0_txc), + .eth_l0_rxd(eth_l0_rxd), + .eth_l0_rxc(eth_l0_rxc), + .eth_l1_txd(eth_l1_txd), + .eth_l1_txc(eth_l1_txc), + .eth_l1_rxd(eth_l1_rxd), + .eth_l1_rxc(eth_l1_rxc), + .eth_l2_txd(eth_l2_txd), + .eth_l2_txc(eth_l2_txc), + .eth_l2_rxd(eth_l2_rxd), + .eth_l2_rxc(eth_l2_rxc), + .eth_l3_txd(eth_l3_txd), + .eth_l3_txc(eth_l3_txc), + .eth_l3_rxd(eth_l3_rxd), + .eth_l3_rxc(eth_l3_rxc), + .eth_l4_txd(eth_l4_txd), + .eth_l4_txc(eth_l4_txc), + .eth_l4_rxd(eth_l4_rxd), + .eth_l4_rxc(eth_l4_rxc), + .eth_l5_txd(eth_l5_txd), + .eth_l5_txc(eth_l5_txc), + .eth_l5_rxd(eth_l5_rxd), + .eth_l5_rxc(eth_l5_rxc), + .eth_l6_txd(eth_l6_txd), + .eth_l6_txc(eth_l6_txc), + .eth_l6_rxd(eth_l6_rxd), + .eth_l6_rxc(eth_l6_rxc), + .eth_l7_txd(eth_l7_txd), + .eth_l7_txc(eth_l7_txc), + .eth_l7_rxd(eth_l7_rxd), + .eth_l7_rxc(eth_l7_rxc), + .eth_l8_txd(eth_l8_txd), + .eth_l8_txc(eth_l8_txc), + .eth_l8_rxd(eth_l8_rxd), + .eth_l8_rxc(eth_l8_rxc), + .eth_l9_txd(eth_l9_txd), + .eth_l9_txc(eth_l9_txc), + .eth_l9_rxd(eth_l9_rxd), + .eth_l9_rxc(eth_l9_rxc), + .eth_l10_txd(eth_l10_txd), + .eth_l10_txc(eth_l10_txc), + .eth_l10_rxd(eth_l10_rxd), + .eth_l10_rxc(eth_l10_rxc), + .eth_l11_txd(eth_l11_txd), + .eth_l11_txc(eth_l11_txc), + .eth_l11_rxd(eth_l11_rxd), + .eth_l11_rxc(eth_l11_rxc) +); + +endmodule diff --git a/example/HXT100G/fpga/tb/udp_ep.py b/example/HXT100G/fpga/tb/udp_ep.py new file mode 120000 index 00000000..073c5d3c --- /dev/null +++ b/example/HXT100G/fpga/tb/udp_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/example/HXT100G/fpga/tb/xgmii_ep.py b/example/HXT100G/fpga/tb/xgmii_ep.py new file mode 120000 index 00000000..63b6d356 --- /dev/null +++ b/example/HXT100G/fpga/tb/xgmii_ep.py @@ -0,0 +1 @@ +../lib/eth/tb/xgmii_ep.py \ No newline at end of file