Add 10G reference design for HXT100G

This commit is contained in:
Alex Forencich 2016-01-25 19:11:42 -08:00
parent 5eb0d9f578
commit f36256c541
26 changed files with 6393 additions and 0 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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) $@

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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";

View File

@ -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

View File

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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
../lib/eth/tb/arp_ep.py

View File

@ -0,0 +1 @@
../lib/eth/tb/axis_ep.py

View File

@ -0,0 +1 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1 @@
../lib/eth/tb/ip_ep.py

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -0,0 +1 @@
../lib/eth/tb/udp_ep.py

View File

@ -0,0 +1 @@
../lib/eth/tb/xgmii_ep.py