Add example design for VCU108 board

This commit is contained in:
Alex Forencich 2016-07-05 11:52:28 -04:00
parent 1f52bf826d
commit 5afe1d7e1e
21 changed files with 2025 additions and 0 deletions

View File

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

View File

@ -0,0 +1,25 @@
# Verilog Ethernet VCU108 Example Design
## Introduction
This example design targets the Xilinx VCU108 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: xcvu095-ffva2104-2-e
PHY: Marvell M88E1111
## How to build
Run make to build. Ensure that the Xilinx Vivado toolchain components are
in PATH.
## How to test
Run make program to program the VCU108 board with Vivado. Then run
netcat -u 192.168.1.128 1234 to open a UDP connection to port 1234. Any text
entered into netcat will be echoed back after pressing enter.

View File

@ -0,0 +1,118 @@
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - space-separated list of source files
# INC_FILES - space-separated list of include files
# XDC_FILES - space-separated list of timing constraint files
# XCI_FILES - space-separated list of IP XCI files
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: clean fpga
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit
.SECONDARY:
CONFIG ?= config.mk
-include ../$(CONFIG)
SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES))
INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES))
XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES))
ifdef XDC_FILES
XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES))
else
XDC_FILES_REL = $(FPGA_TOP).xdc
endif
###################################################################
# Main Targets
#
# all: build everything
# clean: remove output files and project files
###################################################################
all: fpga
fpga: $(FPGA_TOP).bit
tmpclean:
-rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
-rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
clean: tmpclean
-rm -rf *.bit program.tcl
distclean: clean
-rm -rf rev
###################################################################
# Target implementations
###################################################################
# Vivado project file
%.xpr: Makefile $(XCI_FILES_REL)
rm -rf defines.v
touch defines.v
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl
echo "add_files -fileset sources_1 defines.v" >> create_project.tcl
for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done
for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done
for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done
echo "exit" >> create_project.tcl
vivado -mode batch -source create_project.tcl
# synthesis run
%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
echo "open_project $*.xpr" > run_synth.tcl
echo "reset_run synth_1" >> run_synth.tcl
echo "launch_runs synth_1" >> run_synth.tcl
echo "wait_on_run synth_1" >> run_synth.tcl
echo "exit" >> run_synth.tcl
vivado -mode batch -source run_synth.tcl
# implementation run
%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp
echo "open_project $*.xpr" > run_impl.tcl
echo "reset_run impl_1" >> run_impl.tcl
echo "launch_runs impl_1" >> run_impl.tcl
echo "wait_on_run impl_1" >> run_impl.tcl
echo "exit" >> run_impl.tcl
vivado -mode batch -source run_impl.tcl
# bit file
%.bit: %.runs/impl_1/%_routed.dcp
echo "open_project $*.xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force $*.bit" >> generate_bit.tcl
echo "exit" >> generate_bit.tcl
vivado -mode batch -source generate_bit.tcl
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";

View File

@ -0,0 +1,4 @@
# Ethernet constraints
set_property LOC BITSLICE_RX_TX_X1Y35 [get_cells -hier -filter {name =~ */lvds_transceiver_mw/serdes_1_to_10_ser8_i/idelay_cal}]
#set_false_path -to [get_pins -hier -filter {name =~ *idelayctrl_inst/RST} -include_replicated_objects ]

View File

@ -0,0 +1,77 @@
# XDC constraints for the Xilinx VCU108 board
# part: xcvu095-ffva2104-2-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
# System clocks
# 300 MHz
#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p]
#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n]
#create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p]
#set_clock_groups -asynchronous -group clk_300mhz_1
#set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p]
#set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n]
#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p]
#set_clock_groups -asynchronous -group clk_300mhz_2
# 125 MHz
set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p]
set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n]
create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
set_clock_groups -asynchronous -group clk_125mhz
# 90 MHz
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
#set_clock_groups -asynchronous -group clk_90mhz
# LEDs
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}]
set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}]
set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}]
set_property -dict {LOC AY35 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}]
set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}]
# Reset button
set_property -dict {LOC E36 IOSTANDARD LVCMOS12} [get_ports reset]
# Push buttons
set_property -dict {LOC E34 IOSTANDARD LVCMOS12} [get_ports btnu]
set_property -dict {LOC M22 IOSTANDARD LVCMOS12} [get_ports btnl]
set_property -dict {LOC D9 IOSTANDARD LVCMOS12} [get_ports btnd]
set_property -dict {LOC A10 IOSTANDARD LVCMOS12} [get_ports btnr]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS12} [get_ports btnc]
# DIP switches
set_property -dict {LOC BC40 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {LOC C37 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {LOC C38 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
# UART
set_property -dict {LOC BE24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd]
set_property -dict {LOC BC24 IOSTANDARD LVCMOS18} [get_ports uart_rxd]
set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts]
set_property -dict {LOC BD22 IOSTANDARD LVCMOS18} [get_ports uart_cts]
# Gigabit Ethernet SGMII PHY
set_property -dict {LOC AR24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_p]
set_property -dict {LOC AT24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_n]
set_property -dict {LOC AR23 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_p]
set_property -dict {LOC AR22 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_n]
set_property -dict {LOC AT22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_p]
set_property -dict {LOC AU22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_n]
set_property -dict {LOC AU21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n]
set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n]
#set_property -dict {LOC AV24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio]
#set_property -dict {LOC AV21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc]
create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p]
set_clock_groups -asynchronous -group phy_sgmii_clk

View File

@ -0,0 +1,60 @@
# FPGA settings
FPGA_PART = xcvu095-ffva2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = VirtexUltrascale
# 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 += lib/eth/rtl/eth_mac_1g_fifo.v
SYN_FILES += lib/eth/rtl/eth_mac_1g.v
SYN_FILES += lib/eth/rtl/eth_mac_1g_rx.v
SYN_FILES += lib/eth/rtl/eth_mac_1g_tx.v
SYN_FILES += lib/eth/rtl/lfsr.v
SYN_FILES += lib/eth/rtl/eth_axis_rx.v
SYN_FILES += lib/eth/rtl/eth_axis_tx.v
SYN_FILES += lib/eth/rtl/udp_complete.v
SYN_FILES += lib/eth/rtl/udp.v
SYN_FILES += lib/eth/rtl/udp_ip_rx.v
SYN_FILES += lib/eth/rtl/udp_ip_tx.v
SYN_FILES += lib/eth/rtl/ip_complete.v
SYN_FILES += lib/eth/rtl/ip.v
SYN_FILES += lib/eth/rtl/ip_eth_rx.v
SYN_FILES += lib/eth/rtl/ip_eth_tx.v
SYN_FILES += lib/eth/rtl/ip_arb_mux_2.v
SYN_FILES += lib/eth/rtl/ip_mux_2.v
SYN_FILES += lib/eth/rtl/arp.v
SYN_FILES += lib/eth/rtl/arp_cache.v
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
SYN_FILES += lib/eth/rtl/eth_arb_mux_2.v
SYN_FILES += lib/eth/rtl/eth_mux_2.v
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_frame_fifo.v
# XDC files
XDC_FILES = fpga.xdc
XDC_FILES += eth.xdc
# IP
XCI_FILES = ip/gig_ethernet_pcs_pma_0.xci
include ../common/vivado.mk
program: #$(FPGA_TOP).bit
echo "open_hw" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl
echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl
echo "exit" >> program.tcl
vivado -mode batch -source program.tcl

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>xilinx.com</spirit:vendor>
<spirit:library>xci</spirit:library>
<spirit:name>unknown</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:componentInstances>
<spirit:componentInstance>
<spirit:instanceName>gig_ethernet_pcs_pma_0</spirit:instanceName>
<spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="gig_ethernet_pcs_pma" spirit:version="15.2"/>
<spirit:configurableElementValues>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_EMAC_IF_TEMAC">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PHYADDR">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.EXAMPLE_SIMULATION">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_1588">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_RxLane0_Placement">DIFF_PAIR_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_RxLane1_Placement">DIFF_PAIR_1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_RxNibbleBitslice0Used">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_TxLane0_Placement">DIFF_PAIR_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_TxLane1_Placement">DIFF_PAIR_1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_architecture">virtexu</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_component_name">gig_ethernet_pcs_pma_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_drpclkrate">50.0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_dynamic_switching">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_elaboration_transient_dir">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_enable_tx_userclk_reset_port">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_family">virtexu</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gt_dmonitorout_width">17</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gt_drpaddr_width">9</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gt_rxmonitorout_width">7</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gt_txdiffctrl_width">4</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gt_type">GTH</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_gtinex">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_has_an">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_has_ext_mdio">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_has_mdio">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_is_2_5g">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_is_sgmii">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_num_of_lanes">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_refclkrate">125</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_rx_gmii_clk_src">TXOUTCLK</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_sgmii_fabric_buffer">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_sgmii_phy_mode">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_sub_core_name">gig_ethernet_pcs_pma_0_gt</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_support_level">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_transceiver_type">GTHE3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_transceivercontrol">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_tx_in_upper_nibble">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_use_lvds">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_use_tbi">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_use_transceiver">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.c_xdevicefamily">xcvu095</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.characterization">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.gt_rx_byte_width">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Auto_Negotiation">true</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.C_PHYADDR">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">gig_ethernet_pcs_pma_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.DIFFCLK_BOARD_INTERFACE">Custom</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.DrpClkRate">50.0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.EMAC_IF_TEMAC">TEMAC</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ETHERNET_BOARD_INTERFACE">Custom</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.EXAMPLE_SIMULATION">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Enable_1588">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Enable_1588_1step">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Ext_Management_Interface">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.GT_Type">GTH</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.GTinEx">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.LvdsRefClk">625</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.MDIO_BOARD_INTERFACE">Custom</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Management_Interface">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.MaxDataRate">1G</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.NumOfLanes">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Physical_Interface">LVDS</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RefClkRate">125</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RxGmiiClkSrc">TXOUTCLK</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RxLane0_Placement">DIFF_PAIR_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RxLane1_Placement">DIFF_PAIR_1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RxNibbleBitslice0Used">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.SGMII_Mode">10_100_1000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.SGMII_PHY_Mode">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Standard">SGMII</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.SupportLevel">Include_Shared_Logic_in_Core</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Timer_Format">Time_of_day</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TransceiverControl">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TxLane0_Placement">DIFF_PAIR_0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TxLane1_Placement">DIFF_PAIR_1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Tx_In_Upper_Nibble">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.USE_BOARD_FLOW">false</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">virtexu</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xcvu095</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">ffva2104</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VERILOG</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-2</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE">E</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPCONTEXT">IP_Flow</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SELECTEDSIMMODEL"/>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SHAREDDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2016.2</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">OUT_OF_CONTEXT</spirit:configurableElementValue>
</spirit:configurableElementValues>
<spirit:vendorExtensions>
<xilinx:componentInstanceExtensions>
<xilinx:configElementInfos>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.Auto_Negotiation" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.GTinEx" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.LvdsRefClk" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.Management_Interface" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MaxDataRate" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.Physical_Interface" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.SGMII_PHY_Mode" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.Standard" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.SupportLevel" xilinx:valueSource="user"/>
</xilinx:configElementInfos>
</xilinx:componentInstanceExtensions>
</spirit:vendorExtensions>
</spirit:componentInstance>
</spirit:componentInstances>
</spirit:design>

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 or posedge rst) begin
if (rst) begin
cnt_reg <= 0;
state <= 0;
for (k = 0; k < WIDTH; k = k + 1) begin
debounce_reg[k] <= 0;
end
end else begin
if (cnt_reg < RATE) begin
cnt_reg <= cnt_reg + 24'd1;
end else begin
cnt_reg <= 24'd0;
end
if (cnt_reg == 24'd0) begin
for (k = 0; k < WIDTH; k = k + 1) begin
debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]};
end
end
for (k = 0; k < WIDTH; k = k + 1) begin
if (|debounce_reg[k] == 0) begin
state[k] <= 0;
end else if (&debounce_reg[k] == 1) begin
state[k] <= 1;
end else begin
state[k] <= state[k];
end
end
end
end
endmodule

View File

@ -0,0 +1,345 @@
/*
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 1ns / 1ps
/*
* FPGA top-level module
*/
module fpga (
/*
* Clock: 125MHz LVDS
* Reset: Push button, active low
*/
input wire clk_125mhz_p,
input wire clk_125mhz_n,
input wire reset,
/*
* GPIO
*/
input wire btnu,
input wire btnl,
input wire btnd,
input wire btnr,
input wire btnc,
input wire [3:0] sw,
output wire [7:0] led,
/*
* Ethernet: 1000BASE-T SGMII
*/
input wire phy_sgmii_rx_p,
input wire phy_sgmii_rx_n,
output wire phy_sgmii_tx_p,
output wire phy_sgmii_tx_n,
input wire phy_sgmii_clk_p,
input wire phy_sgmii_clk_n,
output wire phy_reset_n,
input wire phy_int_n,
/*
* UART: 500000 bps, 8N1
*/
input wire uart_rxd,
output wire uart_txd,
output wire uart_rts,
input wire uart_cts
);
// Clock and reset
wire clk_125mhz_ibufg;
wire clk_125mhz_mmcm_out;
// Internal 125 MHz clock
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = reset;
wire mmcm_locked;
wire mmcm_clkfb;
IBUFGDS #(
.DIFF_TERM("FALSE"),
.IBUF_LOW_PWR("FALSE")
)
clk_125mhz_ibufg_inst (
.O (clk_125mhz_ibufg),
.I (clk_125mhz_p),
.IB (clk_125mhz_n)
);
// MMCM instance
// 125 MHz in, 125 MHz out
// PFD range: 10 MHz to 500 MHz
// VCO range: 600 MHz to 1440 MHz
// M = 5, D = 1 sets Fvco = 625 MHz (in range)
// Divide by 5 to get output frequency of 125 MHz
MMCME3_BASE #(
.BANDWIDTH("OPTIMIZED"),
.CLKOUT0_DIVIDE_F(5),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
.CLKFBOUT_MULT_F(5),
.CLKFBOUT_PHASE(0),
.DIVCLK_DIVIDE(1),
.REF_JITTER1(0.010),
.CLKIN1_PERIOD(8.0),
.STARTUP_WAIT("FALSE"),
.CLKOUT4_CASCADE("FALSE")
)
clk_mmcm_inst (
.CLKIN1(clk_125mhz_ibufg),
.CLKFBIN(mmcm_clkfb),
.RST(mmcm_rst),
.PWRDWN(1'b0),
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
.CLKOUT1(),
.CLKOUT1B(),
.CLKOUT2(),
.CLKOUT2B(),
.CLKOUT3(),
.CLKOUT3B(),
.CLKOUT4(),
.CLKOUT5(),
.CLKOUT6(),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.sync_reset_out(rst_125mhz_int)
);
// GPIO
wire btnu_int;
wire btnl_int;
wire btnd_int;
wire btnr_int;
wire btnc_int;
wire [3:0] sw_int;
debounce_switch #(
.WIDTH(9),
.N(4),
.RATE(125000)
)
debounce_switch_inst (
.clk(clk_125mhz_int),
.rst(rst_125mhz_int),
.in({btnu,
btnl,
btnd,
btnr,
btnc,
sw}),
.out({btnu_int,
btnl_int,
btnd_int,
btnr_int,
btnc_int,
sw_int})
);
wire uart_rxd_int;
wire uart_cts_int;
sync_signal #(
.WIDTH(2),
.N(2)
)
sync_signal_inst (
.clk(clk_125mhz_int),
.in({uart_rxd, uart_cts}),
.out({uart_rxd_int, uart_cts_int})
);
// SGMII interface to PHY
wire phy_gmii_clk_int;
wire phy_gmii_rst_int;
wire [7:0] phy_gmii_txd_int;
wire phy_gmii_tx_en_int;
wire phy_gmii_tx_er_int;
wire [7:0] phy_gmii_rxd_int;
wire phy_gmii_rx_dv_int;
wire phy_gmii_rx_er_int;
wire [15:0] status_vector;
wire [4:0] pcspma_config_vector = {
1'b1, // autonegotiation enable
1'b0, // isolate
1'b0, // power down
1'b0, // loopback enable
1'b0 // unidirectional enable
};
wire [15:0] pcspma_an_config_vector = {
1'b1, // SGMII link status
1'b1, // SGMII Acknowledge
2'b01, // full duplex
2'b10, // SGMII speed
1'b0, // reserved
2'b00, // pause frames - SGMII reserved
1'b0, // reserved
1'b0, // full duplex - SGMII reserved
4'b0000, // reserved
1'b1 // SGMII
};
gig_ethernet_pcs_pma_0
eth_pcspma (
// SGMII
.txp (phy_sgmii_tx_p),
.txn (phy_sgmii_tx_n),
.rxp (phy_sgmii_rx_p),
.rxn (phy_sgmii_rx_n),
// Ref clock from PHY
.refclk625_p (phy_sgmii_clk_p),
.refclk625_n (phy_sgmii_clk_n),
// async reset
.reset (rst_125mhz_int),
// clock and reset outputs
.clk125_out (phy_gmii_clk_int),
.clk625_out (),
.clk312_out (),
.rst_125_out (phy_gmii_rst_int),
.idelay_rdy_out (),
.mmcm_locked_out (),
// MAC clocking
.sgmii_clk_r (),
.sgmii_clk_f (),
.sgmii_clk_en (), // need to pass through to MAC
// Speed control
.speed_is_10_100 (1'b0),
.speed_is_100 (1'b0),
// Internal GMII
.gmii_txd (phy_gmii_txd_int),
.gmii_tx_en (phy_gmii_tx_en_int),
.gmii_tx_er (phy_gmii_tx_er_int),
.gmii_rxd (phy_gmii_rxd_int),
.gmii_rx_dv (phy_gmii_rx_dv_int),
.gmii_rx_er (phy_gmii_rx_er_int),
.gmii_isolate (),
// Configuration
.configuration_vector (pcspma_config_vector),
.an_interrupt (),
.an_adv_config_vector (pcspma_an_config_vector),
.an_restart_config (1'b0),
// Status
.status_vector (status_vector),
.signal_detect (1'b1)
);
wire [7:0] led_int;
// SGMII interface debug:
// SW12:4 (sw[0]) off for payload byte, on for status vector
// SW12:3 (sw[1]) off for LSB of status vector, on for MSB
assign led = sw[0] ? (sw[1] ? status_vector[15:8] : status_vector[7:0]) : led_int;
fpga_core
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk(clk_125mhz_int),
.rst(rst_125mhz_int),
/*
* GPIO
*/
.btnu(btnu_int),
.btnl(btnl_int),
.btnd(btnd_int),
.btnr(btnr_int),
.btnc(btnc_int),
.sw(sw_int),
.led(led_int),
/*
* Ethernet: 1000BASE-T SGMII
*/
.phy_gmii_clk(phy_gmii_clk_int),
.phy_gmii_rst(phy_gmii_rst_int),
.phy_gmii_rxd(phy_gmii_rxd_int),
.phy_gmii_rx_dv(phy_gmii_rx_dv_int),
.phy_gmii_rx_er(phy_gmii_rx_er_int),
.phy_gmii_txd(phy_gmii_txd_int),
.phy_gmii_tx_en(phy_gmii_tx_en_int),
.phy_gmii_tx_er(phy_gmii_tx_er_int),
.phy_reset_n(phy_reset_n),
.phy_int_n(phy_int_n),
/*
* UART: 115200 bps, 8N1
*/
.uart_rxd(uart_rxd_int),
.uart_txd(uart_txd),
.uart_rts(uart_rts),
.uart_cts(uart_cts_int)
);
endmodule

View File

@ -0,0 +1,558 @@
/*
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 1ns / 1ps
/*
* FPGA core logic
*/
module fpga_core #
(
parameter TARGET = "XILINX"
)
(
/*
* Clock: 125MHz
* Synchronous reset
*/
input wire clk,
input wire rst,
/*
* GPIO
*/
input wire btnu,
input wire btnl,
input wire btnd,
input wire btnr,
input wire btnc,
input wire [3:0] sw,
output wire [7:0] led,
/*
* Ethernet: 1000BASE-T SGMII
*/
input wire phy_gmii_clk,
input wire phy_gmii_rst,
input wire [7:0] phy_gmii_rxd,
input wire phy_gmii_rx_dv,
input wire phy_gmii_rx_er,
output wire [7:0] phy_gmii_txd,
output wire phy_gmii_tx_en,
output wire phy_gmii_tx_er,
output wire phy_reset_n,
input wire phy_int_n,
/*
* UART: 115200 bps, 8N1
*/
input wire uart_rxd,
output wire uart_txd,
output wire uart_rts,
input wire uart_cts
);
// AXI between MAC and Ethernet modules
wire [7:0] rx_axis_tdata;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;
wire [7:0] tx_axis_tdata;
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 [7:0] rx_eth_payload_tdata;
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 [7:0] tx_eth_payload_tdata;
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 [7:0] rx_ip_payload_tdata;
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 [7:0] tx_ip_payload_tdata;
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 [7:0] rx_udp_payload_tdata;
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 [7:0] tx_udp_payload_tdata;
wire tx_udp_payload_tvalid;
wire tx_udp_payload_tready;
wire tx_udp_payload_tlast;
wire tx_udp_payload_tuser;
wire [7:0] rx_fifo_udp_payload_tdata;
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 [7:0] tx_fifo_udp_payload_tdata;
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_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_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_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_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 phy_reset_n = ~rst;
assign uart_txd = 0;
assign uart_rts = 0;
eth_mac_1g_fifo #(
.ENABLE_PADDING(1),
.MIN_FRAME_LENGTH(64),
.TX_FIFO_ADDR_WIDTH(12),
.RX_FIFO_ADDR_WIDTH(12)
)
eth_mac_1g_fifo_inst (
.rx_clk(phy_gmii_clk),
.rx_rst(phy_gmii_rst),
.tx_clk(phy_gmii_clk),
.tx_rst(phy_gmii_rst),
.logic_clk(clk),
.logic_rst(rst),
.tx_axis_tdata(tx_axis_tdata),
.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_tvalid(rx_axis_tvalid),
.rx_axis_tready(rx_axis_tready),
.rx_axis_tlast(rx_axis_tlast),
.rx_axis_tuser(rx_axis_tuser),
.gmii_rxd(phy_gmii_rxd),
.gmii_rx_dv(phy_gmii_rx_dv),
.gmii_rx_er(phy_gmii_rx_er),
.gmii_txd(phy_gmii_txd),
.gmii_tx_en(phy_gmii_tx_en),
.gmii_tx_er(phy_gmii_tx_er),
.rx_error_bad_frame(rx_error_bad_frame),
.rx_error_bad_fcs(rx_error_bad_fcs),
.ifg_delay(12)
);
eth_axis_rx
eth_axis_rx_inst (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(rx_axis_tdata),
.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_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
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_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_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 #(
.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_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_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_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_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_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_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(0)
);
axis_fifo #(
.ADDR_WIDTH(12),
.DATA_WIDTH(8)
)
udp_payload_fifo (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(rx_fifo_udp_payload_tdata),
.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_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,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 or posedge rst) 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/gmii_ep.py

View File

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

View File

@ -0,0 +1,353 @@
#!/usr/bin/env python
"""
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.
"""
from myhdl import *
import os
try:
from queue import Queue
except ImportError:
from Queue import Queue
import eth_ep
import arp_ep
import udp_ep
import gmii_ep
module = 'fpga_core'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("../lib/eth/rtl/eth_mac_1g_fifo.v")
srcs.append("../lib/eth/rtl/eth_mac_1g.v")
srcs.append("../lib/eth/rtl/eth_mac_1g_rx.v")
srcs.append("../lib/eth/rtl/eth_mac_1g_tx.v")
srcs.append("../lib/eth/rtl/lfsr.v")
srcs.append("../lib/eth/rtl/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete.v")
srcs.append("../lib/eth/rtl/udp.v")
srcs.append("../lib/eth/rtl/udp_ip_rx.v")
srcs.append("../lib/eth/rtl/udp_ip_tx.v")
srcs.append("../lib/eth/rtl/ip_complete.v")
srcs.append("../lib/eth/rtl/ip.v")
srcs.append("../lib/eth/rtl/ip_eth_rx.v")
srcs.append("../lib/eth/rtl/ip_eth_tx.v")
srcs.append("../lib/eth/rtl/ip_arb_mux_2.v")
srcs.append("../lib/eth/rtl/ip_mux_2.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux_2.v")
srcs.append("../lib/eth/rtl/eth_mux_2.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_frame_fifo.v")
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_fpga_core(clk,
rst,
current_test,
btnu,
btnl,
btnd,
btnr,
btnc,
sw,
led,
phy_gmii_clk,
phy_gmii_rst,
phy_gmii_rxd,
phy_gmii_rx_dv,
phy_gmii_rx_er,
phy_gmii_txd,
phy_gmii_tx_en,
phy_gmii_tx_er,
phy_reset_n,
phy_int_n,
uart_rxd,
uart_txd,
uart_rts,
uart_cts):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
btnu=btnu,
btnl=btnl,
btnd=btnd,
btnr=btnr,
btnc=btnc,
sw=sw,
led=led,
phy_gmii_clk=phy_gmii_clk,
phy_gmii_rst=phy_gmii_rst,
phy_gmii_rxd=phy_gmii_rxd,
phy_gmii_rx_dv=phy_gmii_rx_dv,
phy_gmii_rx_er=phy_gmii_rx_er,
phy_gmii_txd=phy_gmii_txd,
phy_gmii_tx_en=phy_gmii_tx_en,
phy_gmii_tx_er=phy_gmii_tx_er,
phy_reset_n=phy_reset_n,
phy_int_n=phy_int_n,
uart_rxd=uart_rxd,
uart_txd=uart_txd,
uart_rts=uart_rts,
uart_cts=uart_cts)
def bench():
# Parameters
TARGET = "SIM"
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
btnu = Signal(bool(0))
btnl = Signal(bool(0))
btnd = Signal(bool(0))
btnr = Signal(bool(0))
btnc = Signal(bool(0))
sw = Signal(intbv(0)[3:])
phy_gmii_clk = Signal(bool(0))
phy_gmii_rst = Signal(bool(0))
phy_gmii_rxd = Signal(intbv(0)[8:])
phy_gmii_rx_dv = Signal(bool(0))
phy_gmii_rx_er = Signal(bool(0))
phy_int_n = Signal(bool(1))
uart_rxd = Signal(bool(0))
uart_cts = Signal(bool(0))
# Outputs
led = Signal(intbv(0)[8:])
phy_gmii_txd = Signal(intbv(0)[8:])
phy_gmii_tx_en = Signal(bool(0))
phy_gmii_tx_er = Signal(bool(0))
phy_reset_n = Signal(bool(0))
uart_txd = Signal(bool(0))
uart_rts = Signal(bool(0))
# sources and sinks
gmii_source_queue = Queue()
gmii_sink_queue = Queue()
gmii_source = gmii_ep.GMIISource(phy_gmii_clk,
phy_gmii_rst,
txd=phy_gmii_rxd,
tx_en=phy_gmii_rx_dv,
tx_er=phy_gmii_rx_er,
fifo=gmii_source_queue,
name='gmii_source')
gmii_sink = gmii_ep.GMIISink(phy_gmii_clk,
phy_gmii_rst,
rxd=phy_gmii_txd,
rx_dv=phy_gmii_tx_en,
rx_er=phy_gmii_tx_er,
fifo=gmii_sink_queue,
name='gmii_sink')
# DUT
dut = dut_fpga_core(clk,
rst,
current_test,
btnu,
btnl,
btnd,
btnr,
btnc,
sw,
led,
phy_gmii_clk,
phy_gmii_rst,
phy_gmii_rxd,
phy_gmii_rx_dv,
phy_gmii_rx_er,
phy_gmii_txd,
phy_gmii_tx_en,
phy_gmii_tx_er,
phy_reset_n,
phy_int_n,
uart_rxd,
uart_txd,
uart_rts,
uart_cts)
@always(delay(4))
def clkgen():
clk.next = not clk
phy_gmii_clk.next = not phy_gmii_clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
phy_gmii_rst.next = 1
yield clk.posedge
rst.next = 0
phy_gmii_rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
# testbench stimulus
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
test_frame.ip_length = None
test_frame.ip_identification = 0
test_frame.ip_flags = 2
test_frame.ip_fragment_offset = 0
test_frame.ip_ttl = 64
test_frame.ip_protocol = 0x11
test_frame.ip_header_checksum = None
test_frame.ip_source_ip = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while gmii_sink_queue.empty():
yield clk.posedge
rx_frame = gmii_sink_queue.get(False)
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
gmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while gmii_sink_queue.empty():
yield clk.posedge
rx_frame = gmii_sink_queue.get(False)
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert gmii_source_queue.empty()
assert gmii_sink_queue.empty()
yield delay(100)
raise StopSimulation
return dut, gmii_source, gmii_sink, clkgen, check
def test_bench():
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -0,0 +1,128 @@
/*
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
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
parameter TARGET = "SIM";
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg btnu = 0;
reg btnl = 0;
reg btnd = 0;
reg btnr = 0;
reg btnc = 0;
reg [3:0] sw = 0;
reg phy_gmii_clk = 0;
reg phy_gmii_rst = 0;
reg [7:0] phy_gmii_rxd = 0;
reg phy_gmii_rx_dv = 0;
reg phy_gmii_rx_er = 0;
reg phy_int_n = 1;
reg uart_rxd = 0;
reg uart_cts = 0;
// Outputs
wire [7:0] led;
wire phy_tx_clk;
wire [7:0] phy_gmii_txd;
wire phy_gmii_tx_en;
wire phy_gmii_tx_er;
wire phy_reset_n;
wire uart_txd;
wire uart_rts;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
btnu,
btnl,
btnd,
btnr,
btnc,
sw,
phy_gmii_clk,
phy_gmii_rst,
phy_gmii_rxd,
phy_gmii_rx_dv,
phy_gmii_rx_er,
phy_int_n,
uart_rxd,
uart_cts);
$to_myhdl(led,
phy_gmii_txd,
phy_gmii_tx_en,
phy_gmii_tx_er,
phy_reset_n,
uart_txd,
uart_rts);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core #(
.TARGET(TARGET)
)
UUT (
.clk(clk),
.rst(rst),
.btnu(btnu),
.btnl(btnl),
.btnd(btnd),
.btnr(btnr),
.btnc(btnc),
.sw(sw),
.led(led),
.phy_gmii_clk(phy_gmii_clk),
.phy_gmii_rst(phy_gmii_rst),
.phy_gmii_rxd(phy_gmii_rxd),
.phy_gmii_rx_dv(phy_gmii_rx_dv),
.phy_gmii_rx_er(phy_gmii_rx_er),
.phy_gmii_txd(phy_gmii_txd),
.phy_gmii_tx_en(phy_gmii_tx_en),
.phy_gmii_tx_er(phy_gmii_tx_er),
.phy_reset_n(phy_reset_n),
.phy_int_n(phy_int_n),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd),
.uart_rts(uart_rts),
.uart_cts(uart_cts)
);
endmodule

View File

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