mirror of
https://github.com/alexforencich/verilog-ethernet.git
synced 2025-01-14 06:43:18 +08:00
Add DE2-115 example design
This commit is contained in:
parent
3b06f86dcf
commit
3898cf21ed
25
example/DE2-115/fpga/Makefile
Normal file
25
example/DE2-115/fpga/Makefile
Normal 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:
|
||||
#program commands
|
25
example/DE2-115/fpga/README.md
Normal file
25
example/DE2-115/fpga/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Verilog Ethernet DE2-115 Example Design
|
||||
|
||||
## Introduction
|
||||
|
||||
This example design targets the Terasic DE2-115 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: EP4CE115F29C7
|
||||
PHY: Marvell Alaska 88E1111
|
||||
|
||||
## How to build
|
||||
|
||||
Run make to build. Ensure that the Altera Quartus toolchain components are
|
||||
in PATH.
|
||||
|
||||
## How to test
|
||||
|
||||
Run make program to program the board with the Altera software. 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.
|
||||
|
||||
|
141
example/DE2-115/fpga/common/quartus.mk
Normal file
141
example/DE2-115/fpga/common/quartus.mk
Normal file
@ -0,0 +1,141 @@
|
||||
###################################################################
|
||||
#
|
||||
# Altera FPGA Makefile
|
||||
#
|
||||
# Alex Forencich
|
||||
#
|
||||
###################################################################
|
||||
#
|
||||
# Parameters:
|
||||
# FPGA_TOP - Top module name
|
||||
# FPGA_FAMILY - FPGA family (e.g. Stratix V)
|
||||
# FPGA_DEVICE - FPGA device (e.g. 5SGXEA7N2F45C2)
|
||||
# SYN_FILES - space-separated list of source files
|
||||
# QSF_FILES - space-separated list of settings files
|
||||
# SDC_FILES - space-separated list of timing constraint files
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# FPGA_TOP = fpga
|
||||
# FPGA_FAMILY = "Stratix V"
|
||||
# FPGA_DEVICE = 5SGXEA7N2F45C2
|
||||
# SYN_FILES = rtl/fpga.v rtl/clocks.v
|
||||
# QSF_FILES = fpga.qsf
|
||||
# SDC_FILES = fpga.sdc
|
||||
# include ../common/altera.mk
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# phony targets
|
||||
.PHONY: clean fpga
|
||||
|
||||
# output files to hang on to
|
||||
.PRECIOUS: %.sof %.map.rpt %.fit.rpt %.asm.rpt %.sta.rpt
|
||||
|
||||
# any project specific settings
|
||||
-include ../config.mk
|
||||
|
||||
SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES))
|
||||
|
||||
ifdef QSF_FILES
|
||||
QSF_FILES_REL = $(patsubst %, ../%, $(QSF_FILES))
|
||||
else
|
||||
QSF_FILES_REL = ../$(FPGA_TOP).qsf
|
||||
endif
|
||||
|
||||
SDC_FILES_REL = $(patsubst %, ../%, $(SDC_FILES))
|
||||
|
||||
ASSIGNMENT_FILES = $(FPGA_TOP).qpf $(FPGA_TOP).qsf
|
||||
|
||||
###################################################################
|
||||
# Main Targets
|
||||
#
|
||||
# all: build everything
|
||||
# clean: remove output files and database
|
||||
###################################################################
|
||||
|
||||
all: fpga
|
||||
|
||||
fpga: $(FPGA_TOP).sof
|
||||
|
||||
clean:
|
||||
rm -rf *.rpt *.summary *.smsg *.chg smart.log *.htm *.eqn *.pin *.sof *.pof *.qsf *.qpf *.jdi *.sld *.txt db incremental_db reconfig_mif
|
||||
|
||||
map: smart.log $(PROJECT).map.rpt
|
||||
fit: smart.log $(PROJECT).fit.rpt
|
||||
asm: smart.log $(PROJECT).asm.rpt
|
||||
sta: smart.log $(PROJECT).sta.rpt
|
||||
smart: smart.log
|
||||
|
||||
###################################################################
|
||||
# Executable Configuration
|
||||
###################################################################
|
||||
|
||||
MAP_ARGS = --family=$(FPGA_FAMILY)
|
||||
FIT_ARGS = --part=$(FPGA_DEVICE)
|
||||
ASM_ARGS =
|
||||
STA_ARGS =
|
||||
|
||||
###################################################################
|
||||
# Target implementations
|
||||
###################################################################
|
||||
|
||||
STAMP = echo done >
|
||||
|
||||
%.map.rpt: map.chg $(SYN_FILES_REL)
|
||||
quartus_map $(MAP_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.fit.rpt: fit.chg %.map.rpt
|
||||
quartus_fit $(FIT_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.sta.rpt: sta.chg %.fit.rpt
|
||||
quartus_sta $(STA_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.asm.rpt: asm.chg %.sta.rpt
|
||||
quartus_asm $(ASM_ARGS) $(FPGA_TOP)
|
||||
mkdir -p rev
|
||||
EXT=sof; COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
|
||||
do let COUNT=COUNT+1; done; \
|
||||
cp $*.$$EXT rev/$*_rev$$COUNT.$$EXT; \
|
||||
echo "Output: rev/$*_rev$$COUNT.$$EXT";
|
||||
|
||||
%.sof: smart.log %.asm.rpt
|
||||
|
||||
|
||||
smart.log: $(ASSIGNMENT_FILES)
|
||||
quartus_sh --determine_smart_action $(FPGA_TOP) > smart.log
|
||||
|
||||
###################################################################
|
||||
# Project initialization
|
||||
###################################################################
|
||||
|
||||
$(ASSIGNMENT_FILES): $(QSF_FILES_REL) $(SYN_FILES_REL)
|
||||
rm -f $(FPGA_TOP).qsf
|
||||
quartus_sh --prepare -f $(FPGA_FAMILY) -d $(FPGA_DEVICE) -t $(FPGA_TOP) $(FPGA_TOP)
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo "# Source files" >> $(FPGA_TOP).qsf
|
||||
for x in $(SYN_FILES_REL); do \
|
||||
case $${x##*.} in \
|
||||
v|V) echo set_global_assignment -name VERILOG_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
vhd|VHD) echo set_global_assignment -name VHDL_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
qip|QIP) echo set_global_assignment -name QIP_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
*) echo set_global_assignment -name SOURCE_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
esac; \
|
||||
done
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo "# SDC files" >> $(FPGA_TOP).qsf
|
||||
for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE $$x >> $(FPGA_TOP).qsf; done
|
||||
for x in $(QSF_FILES_REL); do printf "\n#\n# Included QSF file $$x\n#\n" >> $(FPGA_TOP).qsf; cat $$x >> $(FPGA_TOP).qsf; done
|
||||
|
||||
map.chg:
|
||||
$(STAMP) map.chg
|
||||
fit.chg:
|
||||
$(STAMP) fit.chg
|
||||
sta.chg:
|
||||
$(STAMP) sta.chg
|
||||
asm.chg:
|
||||
$(STAMP) asm.chg
|
||||
|
||||
|
1201
example/DE2-115/fpga/fpga.qsf
Normal file
1201
example/DE2-115/fpga/fpga.qsf
Normal file
File diff suppressed because it is too large
Load Diff
75
example/DE2-115/fpga/fpga.sdc
Normal file
75
example/DE2-115/fpga/fpga.sdc
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
create_clock -period 20.00 -name {CLOCK_50} [get_ports {CLOCK_50}]
|
||||
create_clock -period 20.00 -name {CLOCK2_50} [get_ports {CLOCK2_50}]
|
||||
create_clock -period 20.00 -name {CLOCK3_50} [get_ports {CLOCK3_50}]
|
||||
create_clock -period 40.00 -name {ENETCLK_25} [get_ports {ENETCLK_25}]
|
||||
|
||||
set_clock_groups -asynchronous -group [get_clocks {CLOCK_50}]
|
||||
set_clock_groups -asynchronous -group [get_clocks {CLOCK2_50}]
|
||||
set_clock_groups -asynchronous -group [get_clocks {CLOCK3_50}]
|
||||
set_clock_groups -asynchronous -group [get_clocks {ENETCLK_25}]
|
||||
|
||||
create_clock -period "40.000 ns" -name {altera_reserved_tck} {altera_reserved_tck}
|
||||
set_clock_groups -asynchronous -group [get_clocks {altera_reserved_tck}]
|
||||
|
||||
#JTAG Signal Constraints
|
||||
#constrain the TDI TMS and TDO ports -- (modified from timequest SDC cookbook)
|
||||
set_input_delay -clock altera_reserved_tck 5 [get_ports altera_reserved_tdi]
|
||||
set_input_delay -clock altera_reserved_tck 5 [get_ports altera_reserved_tms]
|
||||
set_output_delay -clock altera_reserved_tck -clock_fall -fall -max 5 [get_ports altera_reserved_tdo]
|
||||
|
||||
# Ethernet MDIO interface
|
||||
set_output_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet0_mdc}]
|
||||
set_input_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet0_mdio}]
|
||||
set_output_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet0_mdio}]
|
||||
|
||||
set_output_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet1_mdc}]
|
||||
set_input_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet1_mdio}]
|
||||
set_output_delay -clock [get_clocks CLOCK_50] 2 [get_ports {enet1_mdio}]
|
||||
|
||||
set_false_path -from [get_ports {KEY[*]}] -to *
|
||||
set_false_path -from [get_ports {SW[*]}] -to *
|
||||
set_false_path -from * -to [get_ports {LEDG[*]}]
|
||||
set_false_path -from * -to [get_ports {LEDR[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX0[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX1[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX2[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX3[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX4[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX5[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX6[*]}]
|
||||
set_false_path -from * -to [get_ports {HEX7[*]}]
|
||||
|
||||
set_false_path -from [get_ports ENET0_INT_N] -to *
|
||||
set_false_path -from * -to [get_ports ENET0_RST_N]
|
||||
|
||||
set_false_path -from [get_ports ENET1_INT_N] -to *
|
||||
set_false_path -from * -to [get_ports ENET1_RST_N]
|
||||
|
||||
|
||||
derive_pll_clocks
|
||||
derive_clock_uncertainty
|
||||
|
||||
|
||||
source ../lib/eth/syn/eth_mac_1g_rgmii.sdc
|
||||
source ../lib/eth/syn/rgmii_phy_if.sdc
|
||||
source ../lib/eth/syn/rgmii_io.sdc
|
||||
source ../lib/eth/lib/axis/syn/sync_reset.sdc
|
||||
source ../lib/eth/lib/axis/syn/axis_async_fifo.sdc
|
||||
|
||||
# clocking infrastructure
|
||||
constrain_sync_reset_inst "sync_reset_inst"
|
||||
|
||||
# ENET0 RGMII MAC
|
||||
constrain_eth_mac_1g_rgmii_inst "core_inst|eth_mac_inst|eth_mac_1g_rgmii_inst"
|
||||
constrain_axis_async_fifo_inst "core_inst|eth_mac_inst|rx_fifo|fifo_inst"
|
||||
constrain_axis_async_fifo_inst "core_inst|eth_mac_inst|tx_fifo|fifo_inst"
|
||||
|
||||
# ENET0 RGMII interface
|
||||
constrain_rgmii_input_pins "enet0" "ENET0_RX_CLK" "ENET0_RX_DV ENET0_RX_D*"
|
||||
constrain_rgmii_output_pins "enet0" "altpll_component|auto_generated|pll1|clk[0]" "ENET0_GTX_CLK" "ENET0_TX_EN ENET0_TX_D*"
|
||||
|
||||
# ENET1 RGMII interface
|
||||
constrain_rgmii_input_pins "enet1" "ENET1_RX_CLK" "ENET1_RX_DV ENET1_RX_D*"
|
||||
constrain_rgmii_output_pins "enet1" "altpll_component|auto_generated|pll1|clk[0]" "ENET1_GTX_CLK" "ENET1_TX_EN ENET1_TX_D*"
|
||||
|
59
example/DE2-115/fpga/fpga/Makefile
Normal file
59
example/DE2-115/fpga/fpga/Makefile
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
# FPGA settings
|
||||
FPGA_TOP = fpga
|
||||
FPGA_FAMILY = "Cyclone IV E"
|
||||
FPGA_DEVICE = EP4CE115F29C7
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = rtl/fpga.v
|
||||
SYN_FILES += rtl/fpga_core.v
|
||||
SYN_FILES += rtl/debounce_switch.v
|
||||
SYN_FILES += rtl/sync_signal.v
|
||||
SYN_FILES += rtl/hex_display.v
|
||||
SYN_FILES += lib/eth/rtl/iddr.v
|
||||
SYN_FILES += lib/eth/rtl/oddr.v
|
||||
SYN_FILES += lib/eth/rtl/ssio_ddr_in.v
|
||||
SYN_FILES += lib/eth/rtl/ssio_ddr_out.v
|
||||
SYN_FILES += lib/eth/rtl/rgmii_phy_if.v
|
||||
SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii_fifo.v
|
||||
SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii.v
|
||||
SYN_FILES += lib/eth/rtl/eth_mac_1g.v
|
||||
SYN_FILES += lib/eth/rtl/axis_gmii_rx.v
|
||||
SYN_FILES += lib/eth/rtl/axis_gmii_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_checksum_gen.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.v
|
||||
SYN_FILES += lib/eth/rtl/ip_mux.v
|
||||
SYN_FILES += lib/eth/rtl/arp.v
|
||||
SYN_FILES += lib/eth/rtl/arp_cache.v
|
||||
SYN_FILES += lib/eth/rtl/arp_eth_rx.v
|
||||
SYN_FILES += lib/eth/rtl/arp_eth_tx.v
|
||||
SYN_FILES += lib/eth/rtl/eth_arb_mux.v
|
||||
SYN_FILES += lib/eth/rtl/eth_mux.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
|
||||
SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v
|
||||
|
||||
# QSF files
|
||||
QSF_FILES = fpga.qsf
|
||||
|
||||
# SDC files
|
||||
SDC_FILES = fpga.sdc
|
||||
|
||||
include ../common/quartus.mk
|
||||
|
||||
program: fpga
|
||||
quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof"
|
1
example/DE2-115/fpga/lib/eth
Symbolic link
1
example/DE2-115/fpga/lib/eth
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../
|
89
example/DE2-115/fpga/rtl/debounce_switch.v
Normal file
89
example/DE2-115/fpga/rtl/debounce_switch.v
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog-2001
|
||||
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
/*
|
||||
* Synchronizes switch and button inputs with a slow sampled shift register
|
||||
*/
|
||||
module debounce_switch #(
|
||||
parameter WIDTH=1, // width of the input and output signals
|
||||
parameter N=3, // length of shift register
|
||||
parameter RATE=125000 // clock division factor
|
||||
)(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire [WIDTH-1:0] in,
|
||||
output wire [WIDTH-1:0] out
|
||||
);
|
||||
|
||||
reg [23:0] cnt_reg = 24'd0;
|
||||
|
||||
reg [N-1:0] debounce_reg[WIDTH-1:0];
|
||||
|
||||
reg [WIDTH-1:0] state;
|
||||
|
||||
/*
|
||||
* The synchronized output is the state register
|
||||
*/
|
||||
assign out = state;
|
||||
|
||||
integer k;
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
cnt_reg <= 0;
|
||||
state <= 0;
|
||||
|
||||
for (k = 0; k < WIDTH; k = k + 1) begin
|
||||
debounce_reg[k] <= 0;
|
||||
end
|
||||
end else begin
|
||||
if (cnt_reg < RATE) begin
|
||||
cnt_reg <= cnt_reg + 24'd1;
|
||||
end else begin
|
||||
cnt_reg <= 24'd0;
|
||||
end
|
||||
|
||||
if (cnt_reg == 24'd0) begin
|
||||
for (k = 0; k < WIDTH; k = k + 1) begin
|
||||
debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]};
|
||||
end
|
||||
end
|
||||
|
||||
for (k = 0; k < WIDTH; k = k + 1) begin
|
||||
if (|debounce_reg[k] == 0) begin
|
||||
state[k] <= 0;
|
||||
end else if (&debounce_reg[k] == 1) begin
|
||||
state[k] <= 1;
|
||||
end else begin
|
||||
state[k] <= state[k];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
263
example/DE2-115/fpga/rtl/fpga.v
Normal file
263
example/DE2-115/fpga/rtl/fpga.v
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* FPGA top-level module
|
||||
*/
|
||||
module fpga (
|
||||
/*
|
||||
* Clock: 125MHz
|
||||
*/
|
||||
input wire CLOCK_50,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
input wire [3:0] KEY,
|
||||
input wire [17:0] SW,
|
||||
output wire [8:0] LEDG,
|
||||
output wire [17:0] LEDR,
|
||||
output wire [6:0] HEX0,
|
||||
output wire [6:0] HEX1,
|
||||
output wire [6:0] HEX2,
|
||||
output wire [6:0] HEX3,
|
||||
output wire [6:0] HEX4,
|
||||
output wire [6:0] HEX5,
|
||||
output wire [6:0] HEX6,
|
||||
output wire [6:0] HEX7,
|
||||
output wire [35:0] GPIO,
|
||||
|
||||
/*
|
||||
* Ethernet: 1000BASE-T RGMII
|
||||
*/
|
||||
output wire ENET0_GTX_CLK,
|
||||
output wire [3:0] ENET0_TX_DATA,
|
||||
output wire ENET0_TX_EN,
|
||||
input wire ENET0_RX_CLK,
|
||||
input wire [3:0] ENET0_RX_DATA,
|
||||
input wire ENET0_RX_DV,
|
||||
output wire ENET0_RST_N,
|
||||
input wire ENET0_INT_N,
|
||||
|
||||
output wire ENET1_GTX_CLK,
|
||||
output wire [3:0] ENET1_TX_DATA,
|
||||
output wire ENET1_TX_EN,
|
||||
input wire ENET1_RX_CLK,
|
||||
input wire [3:0] ENET1_RX_DATA,
|
||||
input wire ENET1_RX_DV,
|
||||
output wire ENET1_RST_N,
|
||||
input wire ENET1_INT_N
|
||||
);
|
||||
|
||||
// Clock and reset
|
||||
|
||||
// Internal 125 MHz clock
|
||||
wire clk_int;
|
||||
wire rst_int;
|
||||
|
||||
wire pll_rst = ~KEY[3];
|
||||
wire pll_locked;
|
||||
|
||||
wire clk90_int;
|
||||
|
||||
altpll #(
|
||||
.bandwidth_type("AUTO"),
|
||||
.clk0_divide_by(2),
|
||||
.clk0_duty_cycle(50),
|
||||
.clk0_multiply_by(5),
|
||||
.clk0_phase_shift("0"),
|
||||
.clk1_divide_by(2),
|
||||
.clk1_duty_cycle(50),
|
||||
.clk1_multiply_by(5),
|
||||
.clk1_phase_shift("2000"),
|
||||
.compensate_clock("CLK0"),
|
||||
.inclk0_input_frequency(20000),
|
||||
.intended_device_family("Cyclone IV E"),
|
||||
.operation_mode("NORMAL"),
|
||||
.pll_type("AUTO"),
|
||||
.port_activeclock("PORT_UNUSED"),
|
||||
.port_areset("PORT_USED"),
|
||||
.port_clkbad0("PORT_UNUSED"),
|
||||
.port_clkbad1("PORT_UNUSED"),
|
||||
.port_clkloss("PORT_UNUSED"),
|
||||
.port_clkswitch("PORT_UNUSED"),
|
||||
.port_configupdate("PORT_UNUSED"),
|
||||
.port_fbin("PORT_UNUSED"),
|
||||
.port_inclk0("PORT_USED"),
|
||||
.port_inclk1("PORT_UNUSED"),
|
||||
.port_locked("PORT_USED"),
|
||||
.port_pfdena("PORT_UNUSED"),
|
||||
.port_phasecounterselect("PORT_UNUSED"),
|
||||
.port_phasedone("PORT_UNUSED"),
|
||||
.port_phasestep("PORT_UNUSED"),
|
||||
.port_phaseupdown("PORT_UNUSED"),
|
||||
.port_pllena("PORT_UNUSED"),
|
||||
.port_scanaclr("PORT_UNUSED"),
|
||||
.port_scanclk("PORT_UNUSED"),
|
||||
.port_scanclkena("PORT_UNUSED"),
|
||||
.port_scandata("PORT_UNUSED"),
|
||||
.port_scandataout("PORT_UNUSED"),
|
||||
.port_scandone("PORT_UNUSED"),
|
||||
.port_scanread("PORT_UNUSED"),
|
||||
.port_scanwrite("PORT_UNUSED"),
|
||||
.port_clk0("PORT_USED"),
|
||||
.port_clk1("PORT_USED"),
|
||||
.port_clk2("PORT_UNUSED"),
|
||||
.port_clk3("PORT_UNUSED"),
|
||||
.port_clk4("PORT_UNUSED"),
|
||||
.port_clk5("PORT_UNUSED"),
|
||||
.port_clkena0("PORT_UNUSED"),
|
||||
.port_clkena1("PORT_UNUSED"),
|
||||
.port_clkena2("PORT_UNUSED"),
|
||||
.port_clkena3("PORT_UNUSED"),
|
||||
.port_clkena4("PORT_UNUSED"),
|
||||
.port_clkena5("PORT_UNUSED"),
|
||||
.port_extclk0("PORT_UNUSED"),
|
||||
.port_extclk1("PORT_UNUSED"),
|
||||
.port_extclk2("PORT_UNUSED"),
|
||||
.port_extclk3("PORT_UNUSED"),
|
||||
.self_reset_on_loss_lock("ON"),
|
||||
.width_clock(5)
|
||||
)
|
||||
altpll_component (
|
||||
.areset(pll_rst),
|
||||
.inclk({1'b0, CLOCK_50}),
|
||||
.clk({clk90_int, clk_int}),
|
||||
.locked(pll_locked),
|
||||
.activeclock(),
|
||||
.clkbad(),
|
||||
.clkena({6{1'b1}}),
|
||||
.clkloss(),
|
||||
.clkswitch(1'b0),
|
||||
.configupdate(1'b0),
|
||||
.enable0(),
|
||||
.enable1(),
|
||||
.extclk(),
|
||||
.extclkena({4{1'b1}}),
|
||||
.fbin(1'b1),
|
||||
.fbmimicbidir(),
|
||||
.fbout(),
|
||||
.fref(),
|
||||
.icdrclk(),
|
||||
.pfdena(1'b1),
|
||||
.phasecounterselect({4{1'b1}}),
|
||||
.phasedone(),
|
||||
.phasestep(1'b1),
|
||||
.phaseupdown(1'b1),
|
||||
.pllena(1'b1),
|
||||
.scanaclr(1'b0),
|
||||
.scanclk(1'b0),
|
||||
.scanclkena(1'b1),
|
||||
.scandata(1'b0),
|
||||
.scandataout(),
|
||||
.scandone(),
|
||||
.scanread(1'b0),
|
||||
.scanwrite(1'b0),
|
||||
.sclkout0(),
|
||||
.sclkout1(),
|
||||
.vcooverrange(),
|
||||
.vcounderrange()
|
||||
);
|
||||
|
||||
sync_reset #(
|
||||
.N(4)
|
||||
)
|
||||
sync_reset_inst (
|
||||
.clk(clk_int),
|
||||
.rst(~pll_locked),
|
||||
.out(rst_int)
|
||||
);
|
||||
|
||||
// GPIO
|
||||
wire [3:0] btn_int;
|
||||
wire [17:0] sw_int;
|
||||
|
||||
debounce_switch #(
|
||||
.WIDTH(4+18),
|
||||
.N(4),
|
||||
.RATE(125000)
|
||||
)
|
||||
debounce_switch_inst (
|
||||
.clk(clk_int),
|
||||
.rst(rst_int),
|
||||
.in({~KEY,
|
||||
SW}),
|
||||
.out({btn_int,
|
||||
sw_int})
|
||||
);
|
||||
|
||||
fpga_core
|
||||
core_inst (
|
||||
/*
|
||||
* Clock: 125MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
.clk(clk_int),
|
||||
.clk90(clk90_int),
|
||||
.rst(rst_int),
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.btn(btn_int),
|
||||
.sw(sw_int),
|
||||
.ledg(LEDG),
|
||||
.ledr(LEDR),
|
||||
.hex0(HEX0),
|
||||
.hex1(HEX1),
|
||||
.hex2(HEX2),
|
||||
.hex3(HEX3),
|
||||
.hex4(HEX4),
|
||||
.hex5(HEX5),
|
||||
.hex6(HEX6),
|
||||
.hex7(HEX7),
|
||||
.gpio(GPIO),
|
||||
|
||||
/*
|
||||
* Ethernet: 1000BASE-T RGMII
|
||||
*/
|
||||
.phy0_rx_clk(ENET0_RX_CLK),
|
||||
.phy0_rxd(ENET0_RX_DATA),
|
||||
.phy0_rx_ctl(ENET0_RX_DV),
|
||||
.phy0_tx_clk(ENET0_GTX_CLK),
|
||||
.phy0_txd(ENET0_TX_DATA),
|
||||
.phy0_tx_ctl(ENET0_TX_EN),
|
||||
.phy0_reset_n(ENET0_RST_N),
|
||||
.phy0_int_n(ENET0_INT_N),
|
||||
|
||||
.phy1_rx_clk(ENET1_RX_CLK),
|
||||
.phy1_rxd(ENET1_RX_DATA),
|
||||
.phy1_rx_ctl(ENET1_RX_DV),
|
||||
.phy1_tx_clk(ENET1_GTX_CLK),
|
||||
.phy1_txd(ENET1_TX_DATA),
|
||||
.phy1_tx_ctl(ENET1_TX_EN),
|
||||
.phy1_reset_n(ENET1_RST_N),
|
||||
.phy1_int_n(ENET1_INT_N)
|
||||
);
|
||||
|
||||
endmodule
|
675
example/DE2-115/fpga/rtl/fpga_core.v
Normal file
675
example/DE2-115/fpga/rtl/fpga_core.v
Normal file
@ -0,0 +1,675 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* FPGA core logic
|
||||
*/
|
||||
module fpga_core #
|
||||
(
|
||||
parameter TARGET = "ALTERA"
|
||||
)
|
||||
(
|
||||
/*
|
||||
* Clock: 125MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
input wire clk,
|
||||
input wire clk90,
|
||||
input wire rst,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
input wire [3:0] btn,
|
||||
input wire [17:0] sw,
|
||||
output wire [8:0] ledg,
|
||||
output wire [17:0] ledr,
|
||||
output wire [6:0] hex0,
|
||||
output wire [6:0] hex1,
|
||||
output wire [6:0] hex2,
|
||||
output wire [6:0] hex3,
|
||||
output wire [6:0] hex4,
|
||||
output wire [6:0] hex5,
|
||||
output wire [6:0] hex6,
|
||||
output wire [6:0] hex7,
|
||||
output wire [35:0] gpio,
|
||||
|
||||
/*
|
||||
* Ethernet: 1000BASE-T RGMII
|
||||
*/
|
||||
input wire phy0_rx_clk,
|
||||
input wire [3:0] phy0_rxd,
|
||||
input wire phy0_rx_ctl,
|
||||
output wire phy0_tx_clk,
|
||||
output wire [3:0] phy0_txd,
|
||||
output wire phy0_tx_ctl,
|
||||
output wire phy0_reset_n,
|
||||
input wire phy0_int_n,
|
||||
|
||||
input wire phy1_rx_clk,
|
||||
input wire [3:0] phy1_rxd,
|
||||
input wire phy1_rx_ctl,
|
||||
output wire phy1_tx_clk,
|
||||
output wire [3:0] phy1_txd,
|
||||
output wire phy1_tx_ctl,
|
||||
output wire phy1_reset_n,
|
||||
input wire phy1_int_n
|
||||
);
|
||||
|
||||
// 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_axis_tdata;
|
||||
wire rx_eth_payload_axis_tvalid;
|
||||
wire rx_eth_payload_axis_tready;
|
||||
wire rx_eth_payload_axis_tlast;
|
||||
wire rx_eth_payload_axis_tuser;
|
||||
|
||||
wire tx_eth_hdr_ready;
|
||||
wire tx_eth_hdr_valid;
|
||||
wire [47:0] tx_eth_dest_mac;
|
||||
wire [47:0] tx_eth_src_mac;
|
||||
wire [15:0] tx_eth_type;
|
||||
wire [7:0] tx_eth_payload_axis_tdata;
|
||||
wire tx_eth_payload_axis_tvalid;
|
||||
wire tx_eth_payload_axis_tready;
|
||||
wire tx_eth_payload_axis_tlast;
|
||||
wire tx_eth_payload_axis_tuser;
|
||||
|
||||
// IP frame connections
|
||||
wire rx_ip_hdr_valid;
|
||||
wire rx_ip_hdr_ready;
|
||||
wire [47:0] rx_ip_eth_dest_mac;
|
||||
wire [47:0] rx_ip_eth_src_mac;
|
||||
wire [15:0] rx_ip_eth_type;
|
||||
wire [3:0] rx_ip_version;
|
||||
wire [3:0] rx_ip_ihl;
|
||||
wire [5:0] rx_ip_dscp;
|
||||
wire [1:0] rx_ip_ecn;
|
||||
wire [15:0] rx_ip_length;
|
||||
wire [15:0] rx_ip_identification;
|
||||
wire [2:0] rx_ip_flags;
|
||||
wire [12:0] rx_ip_fragment_offset;
|
||||
wire [7:0] rx_ip_ttl;
|
||||
wire [7:0] rx_ip_protocol;
|
||||
wire [15:0] rx_ip_header_checksum;
|
||||
wire [31:0] rx_ip_source_ip;
|
||||
wire [31:0] rx_ip_dest_ip;
|
||||
wire [7:0] rx_ip_payload_axis_tdata;
|
||||
wire rx_ip_payload_axis_tvalid;
|
||||
wire rx_ip_payload_axis_tready;
|
||||
wire rx_ip_payload_axis_tlast;
|
||||
wire rx_ip_payload_axis_tuser;
|
||||
|
||||
wire tx_ip_hdr_valid;
|
||||
wire tx_ip_hdr_ready;
|
||||
wire [5:0] tx_ip_dscp;
|
||||
wire [1:0] tx_ip_ecn;
|
||||
wire [15:0] tx_ip_length;
|
||||
wire [7:0] tx_ip_ttl;
|
||||
wire [7:0] tx_ip_protocol;
|
||||
wire [31:0] tx_ip_source_ip;
|
||||
wire [31:0] tx_ip_dest_ip;
|
||||
wire [7:0] tx_ip_payload_axis_tdata;
|
||||
wire tx_ip_payload_axis_tvalid;
|
||||
wire tx_ip_payload_axis_tready;
|
||||
wire tx_ip_payload_axis_tlast;
|
||||
wire tx_ip_payload_axis_tuser;
|
||||
|
||||
// UDP frame connections
|
||||
wire rx_udp_hdr_valid;
|
||||
wire rx_udp_hdr_ready;
|
||||
wire [47:0] rx_udp_eth_dest_mac;
|
||||
wire [47:0] rx_udp_eth_src_mac;
|
||||
wire [15:0] rx_udp_eth_type;
|
||||
wire [3:0] rx_udp_ip_version;
|
||||
wire [3:0] rx_udp_ip_ihl;
|
||||
wire [5:0] rx_udp_ip_dscp;
|
||||
wire [1:0] rx_udp_ip_ecn;
|
||||
wire [15:0] rx_udp_ip_length;
|
||||
wire [15:0] rx_udp_ip_identification;
|
||||
wire [2:0] rx_udp_ip_flags;
|
||||
wire [12:0] rx_udp_ip_fragment_offset;
|
||||
wire [7:0] rx_udp_ip_ttl;
|
||||
wire [7:0] rx_udp_ip_protocol;
|
||||
wire [15:0] rx_udp_ip_header_checksum;
|
||||
wire [31:0] rx_udp_ip_source_ip;
|
||||
wire [31:0] rx_udp_ip_dest_ip;
|
||||
wire [15:0] rx_udp_source_port;
|
||||
wire [15:0] rx_udp_dest_port;
|
||||
wire [15:0] rx_udp_length;
|
||||
wire [15:0] rx_udp_checksum;
|
||||
wire [7:0] rx_udp_payload_axis_tdata;
|
||||
wire rx_udp_payload_axis_tvalid;
|
||||
wire rx_udp_payload_axis_tready;
|
||||
wire rx_udp_payload_axis_tlast;
|
||||
wire rx_udp_payload_axis_tuser;
|
||||
|
||||
wire tx_udp_hdr_valid;
|
||||
wire tx_udp_hdr_ready;
|
||||
wire [5:0] tx_udp_ip_dscp;
|
||||
wire [1:0] tx_udp_ip_ecn;
|
||||
wire [7:0] tx_udp_ip_ttl;
|
||||
wire [31:0] tx_udp_ip_source_ip;
|
||||
wire [31:0] tx_udp_ip_dest_ip;
|
||||
wire [15:0] tx_udp_source_port;
|
||||
wire [15:0] tx_udp_dest_port;
|
||||
wire [15:0] tx_udp_length;
|
||||
wire [15:0] tx_udp_checksum;
|
||||
wire [7:0] tx_udp_payload_axis_tdata;
|
||||
wire tx_udp_payload_axis_tvalid;
|
||||
wire tx_udp_payload_axis_tready;
|
||||
wire tx_udp_payload_axis_tlast;
|
||||
wire tx_udp_payload_axis_tuser;
|
||||
|
||||
wire [7:0] rx_fifo_udp_payload_axis_tdata;
|
||||
wire rx_fifo_udp_payload_axis_tvalid;
|
||||
wire rx_fifo_udp_payload_axis_tready;
|
||||
wire rx_fifo_udp_payload_axis_tlast;
|
||||
wire rx_fifo_udp_payload_axis_tuser;
|
||||
|
||||
wire [7:0] tx_fifo_udp_payload_axis_tdata;
|
||||
wire tx_fifo_udp_payload_axis_tvalid;
|
||||
wire tx_fifo_udp_payload_axis_tready;
|
||||
wire tx_fifo_udp_payload_axis_tlast;
|
||||
wire tx_fifo_udp_payload_axis_tuser;
|
||||
|
||||
// Configuration
|
||||
wire [47:0] local_mac = 48'h02_00_00_00_00_00;
|
||||
wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128};
|
||||
wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1};
|
||||
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
|
||||
|
||||
// IP ports not used
|
||||
assign rx_ip_hdr_ready = 1;
|
||||
assign rx_ip_payload_axis_tready = 1;
|
||||
|
||||
assign tx_ip_hdr_valid = 0;
|
||||
assign tx_ip_dscp = 0;
|
||||
assign tx_ip_ecn = 0;
|
||||
assign tx_ip_length = 0;
|
||||
assign tx_ip_ttl = 0;
|
||||
assign tx_ip_protocol = 0;
|
||||
assign tx_ip_source_ip = 0;
|
||||
assign tx_ip_dest_ip = 0;
|
||||
assign tx_ip_payload_axis_tdata = 0;
|
||||
assign tx_ip_payload_axis_tvalid = 0;
|
||||
assign tx_ip_payload_axis_tlast = 0;
|
||||
assign tx_ip_payload_axis_tuser = 0;
|
||||
|
||||
// Loop back UDP
|
||||
wire match_cond = rx_udp_dest_port == 1234;
|
||||
wire no_match = !match_cond;
|
||||
|
||||
reg match_cond_reg = 0;
|
||||
reg no_match_reg = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
match_cond_reg <= 0;
|
||||
no_match_reg <= 0;
|
||||
end else begin
|
||||
if (rx_udp_payload_axis_tvalid) begin
|
||||
if ((!match_cond_reg && !no_match_reg) ||
|
||||
(rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
|
||||
match_cond_reg <= match_cond;
|
||||
no_match_reg <= no_match;
|
||||
end
|
||||
end else begin
|
||||
match_cond_reg <= 0;
|
||||
no_match_reg <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
|
||||
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
|
||||
assign tx_udp_ip_dscp = 0;
|
||||
assign tx_udp_ip_ecn = 0;
|
||||
assign tx_udp_ip_ttl = 64;
|
||||
assign tx_udp_ip_source_ip = local_ip;
|
||||
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
|
||||
assign tx_udp_source_port = rx_udp_dest_port;
|
||||
assign tx_udp_dest_port = rx_udp_source_port;
|
||||
assign tx_udp_length = rx_udp_length;
|
||||
assign tx_udp_checksum = 0;
|
||||
|
||||
assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
|
||||
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
|
||||
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
|
||||
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
|
||||
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;
|
||||
|
||||
assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
|
||||
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
|
||||
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
|
||||
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
|
||||
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;
|
||||
|
||||
// Place first payload byte onto LEDs
|
||||
reg valid_last = 0;
|
||||
reg [7:0] led_reg = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (tx_udp_payload_axis_tvalid) begin
|
||||
if (!valid_last) begin
|
||||
led_reg <= tx_udp_payload_axis_tdata;
|
||||
valid_last <= 1'b1;
|
||||
end
|
||||
if (tx_udp_payload_axis_tlast) begin
|
||||
valid_last <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (rst) begin
|
||||
led_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// place dest IP onto 7 segment displays
|
||||
reg [31:0] dest_ip_reg = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (tx_udp_hdr_valid) begin
|
||||
dest_ip_reg <= tx_udp_ip_dest_ip;
|
||||
end
|
||||
|
||||
if (rst) begin
|
||||
dest_ip_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_0 (
|
||||
.in(dest_ip_reg[3:0]),
|
||||
.enable(1),
|
||||
.out(hex0)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_1 (
|
||||
.in(dest_ip_reg[7:4]),
|
||||
.enable(1),
|
||||
.out(hex1)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_2 (
|
||||
.in(dest_ip_reg[11:8]),
|
||||
.enable(1),
|
||||
.out(hex2)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_3 (
|
||||
.in(dest_ip_reg[15:12]),
|
||||
.enable(1),
|
||||
.out(hex3)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_4 (
|
||||
.in(dest_ip_reg[19:16]),
|
||||
.enable(1),
|
||||
.out(hex4)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_5 (
|
||||
.in(dest_ip_reg[23:20]),
|
||||
.enable(1),
|
||||
.out(hex5)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_6 (
|
||||
.in(dest_ip_reg[27:24]),
|
||||
.enable(1),
|
||||
.out(hex6)
|
||||
);
|
||||
|
||||
hex_display #(
|
||||
.INVERT(1)
|
||||
)
|
||||
hex_display_7 (
|
||||
.in(dest_ip_reg[31:28]),
|
||||
.enable(1),
|
||||
.out(hex7)
|
||||
);
|
||||
|
||||
//assign led = sw;
|
||||
assign ledg = led_reg;
|
||||
assign ledr = sw;
|
||||
assign phy0_reset_n = ~rst;
|
||||
assign phy1_reset_n = ~rst;
|
||||
|
||||
assign gpio = 0;
|
||||
|
||||
eth_mac_1g_rgmii_fifo #(
|
||||
.TARGET(TARGET),
|
||||
.USE_CLK90("TRUE"),
|
||||
.ENABLE_PADDING(1),
|
||||
.MIN_FRAME_LENGTH(64),
|
||||
.TX_FIFO_DEPTH(4096),
|
||||
.TX_FRAME_FIFO(1),
|
||||
.RX_FIFO_DEPTH(4096),
|
||||
.RX_FRAME_FIFO(1)
|
||||
)
|
||||
eth_mac_inst (
|
||||
.gtx_clk(clk),
|
||||
.gtx_clk90(clk90),
|
||||
.gtx_rst(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),
|
||||
|
||||
.rgmii_rx_clk(phy0_rx_clk),
|
||||
.rgmii_rxd(phy0_rxd),
|
||||
.rgmii_rx_ctl(phy0_rx_ctl),
|
||||
.rgmii_tx_clk(phy0_tx_clk),
|
||||
.rgmii_txd(phy0_txd),
|
||||
.rgmii_tx_ctl(phy0_tx_ctl),
|
||||
|
||||
.tx_fifo_overflow(),
|
||||
.tx_fifo_bad_frame(),
|
||||
.tx_fifo_good_frame(),
|
||||
.rx_error_bad_frame(),
|
||||
.rx_error_bad_fcs(),
|
||||
.rx_fifo_overflow(),
|
||||
.rx_fifo_bad_frame(),
|
||||
.rx_fifo_good_frame(),
|
||||
.speed(),
|
||||
|
||||
.ifg_delay(12)
|
||||
);
|
||||
|
||||
eth_axis_rx
|
||||
eth_axis_rx_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// AXI input
|
||||
.s_axis_tdata(rx_axis_tdata),
|
||||
.s_axis_tvalid(rx_axis_tvalid),
|
||||
.s_axis_tready(rx_axis_tready),
|
||||
.s_axis_tlast(rx_axis_tlast),
|
||||
.s_axis_tuser(rx_axis_tuser),
|
||||
// Ethernet frame output
|
||||
.m_eth_hdr_valid(rx_eth_hdr_valid),
|
||||
.m_eth_hdr_ready(rx_eth_hdr_ready),
|
||||
.m_eth_dest_mac(rx_eth_dest_mac),
|
||||
.m_eth_src_mac(rx_eth_src_mac),
|
||||
.m_eth_type(rx_eth_type),
|
||||
.m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
||||
.m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
||||
.m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
||||
.m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
||||
.m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
||||
// Status signals
|
||||
.busy(),
|
||||
.error_header_early_termination()
|
||||
);
|
||||
|
||||
eth_axis_tx
|
||||
eth_axis_tx_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.s_eth_hdr_valid(tx_eth_hdr_valid),
|
||||
.s_eth_hdr_ready(tx_eth_hdr_ready),
|
||||
.s_eth_dest_mac(tx_eth_dest_mac),
|
||||
.s_eth_src_mac(tx_eth_src_mac),
|
||||
.s_eth_type(tx_eth_type),
|
||||
.s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
||||
.s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
||||
.s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
||||
.s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
||||
.s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
||||
// AXI output
|
||||
.m_axis_tdata(tx_axis_tdata),
|
||||
.m_axis_tvalid(tx_axis_tvalid),
|
||||
.m_axis_tready(tx_axis_tready),
|
||||
.m_axis_tlast(tx_axis_tlast),
|
||||
.m_axis_tuser(tx_axis_tuser),
|
||||
// Status signals
|
||||
.busy()
|
||||
);
|
||||
|
||||
udp_complete
|
||||
udp_complete_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.s_eth_hdr_valid(rx_eth_hdr_valid),
|
||||
.s_eth_hdr_ready(rx_eth_hdr_ready),
|
||||
.s_eth_dest_mac(rx_eth_dest_mac),
|
||||
.s_eth_src_mac(rx_eth_src_mac),
|
||||
.s_eth_type(rx_eth_type),
|
||||
.s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
|
||||
.s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
|
||||
.s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
|
||||
.s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
|
||||
.s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
|
||||
// Ethernet frame output
|
||||
.m_eth_hdr_valid(tx_eth_hdr_valid),
|
||||
.m_eth_hdr_ready(tx_eth_hdr_ready),
|
||||
.m_eth_dest_mac(tx_eth_dest_mac),
|
||||
.m_eth_src_mac(tx_eth_src_mac),
|
||||
.m_eth_type(tx_eth_type),
|
||||
.m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
|
||||
.m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
|
||||
.m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
|
||||
.m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
|
||||
.m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
|
||||
// IP frame input
|
||||
.s_ip_hdr_valid(tx_ip_hdr_valid),
|
||||
.s_ip_hdr_ready(tx_ip_hdr_ready),
|
||||
.s_ip_dscp(tx_ip_dscp),
|
||||
.s_ip_ecn(tx_ip_ecn),
|
||||
.s_ip_length(tx_ip_length),
|
||||
.s_ip_ttl(tx_ip_ttl),
|
||||
.s_ip_protocol(tx_ip_protocol),
|
||||
.s_ip_source_ip(tx_ip_source_ip),
|
||||
.s_ip_dest_ip(tx_ip_dest_ip),
|
||||
.s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
|
||||
.s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
|
||||
.s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
|
||||
.s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
|
||||
.s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
|
||||
// IP frame output
|
||||
.m_ip_hdr_valid(rx_ip_hdr_valid),
|
||||
.m_ip_hdr_ready(rx_ip_hdr_ready),
|
||||
.m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
|
||||
.m_ip_eth_src_mac(rx_ip_eth_src_mac),
|
||||
.m_ip_eth_type(rx_ip_eth_type),
|
||||
.m_ip_version(rx_ip_version),
|
||||
.m_ip_ihl(rx_ip_ihl),
|
||||
.m_ip_dscp(rx_ip_dscp),
|
||||
.m_ip_ecn(rx_ip_ecn),
|
||||
.m_ip_length(rx_ip_length),
|
||||
.m_ip_identification(rx_ip_identification),
|
||||
.m_ip_flags(rx_ip_flags),
|
||||
.m_ip_fragment_offset(rx_ip_fragment_offset),
|
||||
.m_ip_ttl(rx_ip_ttl),
|
||||
.m_ip_protocol(rx_ip_protocol),
|
||||
.m_ip_header_checksum(rx_ip_header_checksum),
|
||||
.m_ip_source_ip(rx_ip_source_ip),
|
||||
.m_ip_dest_ip(rx_ip_dest_ip),
|
||||
.m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
|
||||
.m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
|
||||
.m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
|
||||
.m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
|
||||
.m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
|
||||
// UDP frame input
|
||||
.s_udp_hdr_valid(tx_udp_hdr_valid),
|
||||
.s_udp_hdr_ready(tx_udp_hdr_ready),
|
||||
.s_udp_ip_dscp(tx_udp_ip_dscp),
|
||||
.s_udp_ip_ecn(tx_udp_ip_ecn),
|
||||
.s_udp_ip_ttl(tx_udp_ip_ttl),
|
||||
.s_udp_ip_source_ip(tx_udp_ip_source_ip),
|
||||
.s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
|
||||
.s_udp_source_port(tx_udp_source_port),
|
||||
.s_udp_dest_port(tx_udp_dest_port),
|
||||
.s_udp_length(tx_udp_length),
|
||||
.s_udp_checksum(tx_udp_checksum),
|
||||
.s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
|
||||
.s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
|
||||
.s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
|
||||
.s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
|
||||
.s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
|
||||
// UDP frame output
|
||||
.m_udp_hdr_valid(rx_udp_hdr_valid),
|
||||
.m_udp_hdr_ready(rx_udp_hdr_ready),
|
||||
.m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
|
||||
.m_udp_eth_src_mac(rx_udp_eth_src_mac),
|
||||
.m_udp_eth_type(rx_udp_eth_type),
|
||||
.m_udp_ip_version(rx_udp_ip_version),
|
||||
.m_udp_ip_ihl(rx_udp_ip_ihl),
|
||||
.m_udp_ip_dscp(rx_udp_ip_dscp),
|
||||
.m_udp_ip_ecn(rx_udp_ip_ecn),
|
||||
.m_udp_ip_length(rx_udp_ip_length),
|
||||
.m_udp_ip_identification(rx_udp_ip_identification),
|
||||
.m_udp_ip_flags(rx_udp_ip_flags),
|
||||
.m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
|
||||
.m_udp_ip_ttl(rx_udp_ip_ttl),
|
||||
.m_udp_ip_protocol(rx_udp_ip_protocol),
|
||||
.m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
|
||||
.m_udp_ip_source_ip(rx_udp_ip_source_ip),
|
||||
.m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
|
||||
.m_udp_source_port(rx_udp_source_port),
|
||||
.m_udp_dest_port(rx_udp_dest_port),
|
||||
.m_udp_length(rx_udp_length),
|
||||
.m_udp_checksum(rx_udp_checksum),
|
||||
.m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
|
||||
.m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
|
||||
.m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
|
||||
.m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
|
||||
.m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
|
||||
// Status signals
|
||||
.ip_rx_busy(),
|
||||
.ip_tx_busy(),
|
||||
.udp_rx_busy(),
|
||||
.udp_tx_busy(),
|
||||
.ip_rx_error_header_early_termination(),
|
||||
.ip_rx_error_payload_early_termination(),
|
||||
.ip_rx_error_invalid_header(),
|
||||
.ip_rx_error_invalid_checksum(),
|
||||
.ip_tx_error_payload_early_termination(),
|
||||
.ip_tx_error_arp_failed(),
|
||||
.udp_rx_error_header_early_termination(),
|
||||
.udp_rx_error_payload_early_termination(),
|
||||
.udp_tx_error_payload_early_termination(),
|
||||
// Configuration
|
||||
.local_mac(local_mac),
|
||||
.local_ip(local_ip),
|
||||
.gateway_ip(gateway_ip),
|
||||
.subnet_mask(subnet_mask),
|
||||
.clear_arp_cache(0)
|
||||
);
|
||||
|
||||
axis_fifo #(
|
||||
.DEPTH(8192),
|
||||
.DATA_WIDTH(8),
|
||||
.KEEP_ENABLE(0),
|
||||
.ID_ENABLE(0),
|
||||
.DEST_ENABLE(0),
|
||||
.USER_ENABLE(1),
|
||||
.USER_WIDTH(1),
|
||||
.FRAME_FIFO(0)
|
||||
)
|
||||
udp_payload_fifo (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
// AXI input
|
||||
.s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
|
||||
.s_axis_tkeep(0),
|
||||
.s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
|
||||
.s_axis_tready(rx_fifo_udp_payload_axis_tready),
|
||||
.s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
|
||||
.s_axis_tid(0),
|
||||
.s_axis_tdest(0),
|
||||
.s_axis_tuser(rx_fifo_udp_payload_axis_tuser),
|
||||
|
||||
// AXI output
|
||||
.m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
|
||||
.m_axis_tkeep(),
|
||||
.m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
|
||||
.m_axis_tready(tx_fifo_udp_payload_axis_tready),
|
||||
.m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
|
||||
.m_axis_tid(),
|
||||
.m_axis_tdest(),
|
||||
.m_axis_tuser(tx_fifo_udp_payload_axis_tuser),
|
||||
|
||||
// Status
|
||||
.status_overflow(),
|
||||
.status_bad_frame(),
|
||||
.status_good_frame()
|
||||
);
|
||||
|
||||
endmodule
|
70
example/DE2-115/fpga/rtl/hex_display.v
Normal file
70
example/DE2-115/fpga/rtl/hex_display.v
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* 7 segment display hexadecimal encoding
|
||||
*/
|
||||
module hex_display #(
|
||||
parameter INVERT = 0
|
||||
)
|
||||
(
|
||||
input wire [3:0] in,
|
||||
input wire enable,
|
||||
|
||||
output wire [6:0] out
|
||||
);
|
||||
|
||||
reg [6:0] enc;
|
||||
|
||||
always @* begin
|
||||
enc <= 7'b0000000;
|
||||
if (enable) begin
|
||||
case (in)
|
||||
4'h0: enc <= 7'b0111111;
|
||||
4'h1: enc <= 7'b0000110;
|
||||
4'h2: enc <= 7'b1011011;
|
||||
4'h3: enc <= 7'b1001111;
|
||||
4'h4: enc <= 7'b1100110;
|
||||
4'h5: enc <= 7'b1101101;
|
||||
4'h6: enc <= 7'b1111101;
|
||||
4'h7: enc <= 7'b0000111;
|
||||
4'h8: enc <= 7'b1111111;
|
||||
4'h9: enc <= 7'b1101111;
|
||||
4'ha: enc <= 7'b1110111;
|
||||
4'hb: enc <= 7'b1111100;
|
||||
4'hc: enc <= 7'b0111001;
|
||||
4'hd: enc <= 7'b1011110;
|
||||
4'he: enc <= 7'b1111001;
|
||||
4'hf: enc <= 7'b1110001;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign out = INVERT ? ~enc : enc;
|
||||
|
||||
endmodule
|
58
example/DE2-115/fpga/rtl/sync_signal.v
Normal file
58
example/DE2-115/fpga/rtl/sync_signal.v
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog-2001
|
||||
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
/*
|
||||
* Synchronizes an asyncronous signal to a given clock by using a pipeline of
|
||||
* two registers.
|
||||
*/
|
||||
module sync_signal #(
|
||||
parameter WIDTH=1, // width of the input and output signals
|
||||
parameter N=2 // depth of synchronizer
|
||||
)(
|
||||
input wire clk,
|
||||
input wire [WIDTH-1:0] in,
|
||||
output wire [WIDTH-1:0] out
|
||||
);
|
||||
|
||||
reg [WIDTH-1:0] sync_reg[N-1:0];
|
||||
|
||||
/*
|
||||
* The synchronized output is the last register in the pipeline.
|
||||
*/
|
||||
assign out = sync_reg[N-1];
|
||||
|
||||
integer k;
|
||||
|
||||
always @(posedge clk) begin
|
||||
sync_reg[0] <= in;
|
||||
for (k = 1; k < N; k = k + 1) begin
|
||||
sync_reg[k] <= sync_reg[k-1];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
1
example/DE2-115/fpga/tb/arp_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/arp_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/arp_ep.py
|
1
example/DE2-115/fpga/tb/axis_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/axis_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/axis_ep.py
|
1
example/DE2-115/fpga/tb/eth_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/eth_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/eth_ep.py
|
1
example/DE2-115/fpga/tb/gmii_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/gmii_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/gmii_ep.py
|
1
example/DE2-115/fpga/tb/ip_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/ip_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/ip_ep.py
|
1
example/DE2-115/fpga/tb/rgmii_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/rgmii_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/rgmii_ep.py
|
364
example/DE2-115/fpga/tb/test_fpga_core.py
Executable file
364
example/DE2-115/fpga/tb/test_fpga_core.py
Executable file
@ -0,0 +1,364 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
|
||||
Copyright (c) 2015-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from myhdl import *
|
||||
import os
|
||||
|
||||
import eth_ep
|
||||
import arp_ep
|
||||
import udp_ep
|
||||
import rgmii_ep
|
||||
|
||||
module = 'fpga_core'
|
||||
testbench = 'test_%s' % module
|
||||
|
||||
srcs = []
|
||||
|
||||
srcs.append("../rtl/%s.v" % module)
|
||||
srcs.append("../rtl/hex_display.v")
|
||||
srcs.append("../lib/eth/rtl/iddr.v")
|
||||
srcs.append("../lib/eth/rtl/oddr.v")
|
||||
srcs.append("../lib/eth/rtl/ssio_ddr_in.v")
|
||||
srcs.append("../lib/eth/rtl/ssio_ddr_out.v")
|
||||
srcs.append("../lib/eth/rtl/rgmii_phy_if.v")
|
||||
srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii_fifo.v")
|
||||
srcs.append("../lib/eth/rtl/eth_mac_1g_rgmii.v")
|
||||
srcs.append("../lib/eth/rtl/eth_mac_1g.v")
|
||||
srcs.append("../lib/eth/rtl/axis_gmii_rx.v")
|
||||
srcs.append("../lib/eth/rtl/axis_gmii_tx.v")
|
||||
srcs.append("../lib/eth/rtl/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_checksum_gen.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.v")
|
||||
srcs.append("../lib/eth/rtl/ip_mux.v")
|
||||
srcs.append("../lib/eth/rtl/arp.v")
|
||||
srcs.append("../lib/eth/rtl/arp_cache.v")
|
||||
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
|
||||
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
|
||||
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
|
||||
srcs.append("../lib/eth/rtl/eth_mux.v")
|
||||
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
|
||||
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
|
||||
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
|
||||
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
|
||||
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
|
||||
srcs.append("%s.v" % testbench)
|
||||
|
||||
src = ' '.join(srcs)
|
||||
|
||||
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
|
||||
|
||||
def bench():
|
||||
|
||||
# Parameters
|
||||
TARGET = "SIM"
|
||||
|
||||
# Inputs
|
||||
clk = Signal(bool(0))
|
||||
clk90 = Signal(bool(0))
|
||||
rst = Signal(bool(0))
|
||||
current_test = Signal(intbv(0)[8:])
|
||||
|
||||
btn = Signal(intbv(0)[4:])
|
||||
sw = Signal(intbv(0)[17:])
|
||||
phy0_rx_clk = Signal(bool(0))
|
||||
phy0_rxd = Signal(intbv(0)[4:])
|
||||
phy0_rx_ctl = Signal(bool(0))
|
||||
phy0_int_n = Signal(bool(1))
|
||||
phy1_rx_clk = Signal(bool(0))
|
||||
phy1_rxd = Signal(intbv(0)[4:])
|
||||
phy1_rx_ctl = Signal(bool(0))
|
||||
phy1_int_n = Signal(bool(1))
|
||||
|
||||
# Outputs
|
||||
ledg = Signal(intbv(0)[8:])
|
||||
ledr = Signal(intbv(0)[18:])
|
||||
hex0 = Signal(intbv(0)[7:])
|
||||
hex1 = Signal(intbv(0)[7:])
|
||||
hex2 = Signal(intbv(0)[7:])
|
||||
hex3 = Signal(intbv(0)[7:])
|
||||
hex4 = Signal(intbv(0)[7:])
|
||||
hex5 = Signal(intbv(0)[7:])
|
||||
hex6 = Signal(intbv(0)[7:])
|
||||
hex7 = Signal(intbv(0)[7:])
|
||||
gpio = Signal(intbv(0)[36:])
|
||||
phy0_tx_clk = Signal(bool(0))
|
||||
phy0_txd = Signal(intbv(0)[4:])
|
||||
phy0_tx_ctl = Signal(bool(0))
|
||||
phy0_reset_n = Signal(bool(0))
|
||||
phy1_tx_clk = Signal(bool(0))
|
||||
phy1_txd = Signal(intbv(0)[4:])
|
||||
phy1_tx_ctl = Signal(bool(0))
|
||||
phy1_reset_n = Signal(bool(0))
|
||||
|
||||
# sources and sinks
|
||||
mii_select_0 = Signal(bool(0))
|
||||
|
||||
rgmii_source_0 = rgmii_ep.RGMIISource()
|
||||
|
||||
rgmii_source_0_logic = rgmii_source_0.create_logic(
|
||||
phy0_rx_clk,
|
||||
rst,
|
||||
txd=phy0_rxd,
|
||||
tx_ctl=phy0_rx_ctl,
|
||||
mii_select=mii_select_0,
|
||||
name='rgmii_source_0'
|
||||
)
|
||||
|
||||
rgmii_sink_0 = rgmii_ep.RGMIISink()
|
||||
|
||||
rgmii_sink_0_logic = rgmii_sink_0.create_logic(
|
||||
phy0_tx_clk,
|
||||
rst,
|
||||
rxd=phy0_txd,
|
||||
rx_ctl=phy0_tx_ctl,
|
||||
mii_select=mii_select_0,
|
||||
name='rgmii_sink_0'
|
||||
)
|
||||
|
||||
mii_select_1 = Signal(bool(0))
|
||||
|
||||
rgmii_source_1 = rgmii_ep.RGMIISource()
|
||||
|
||||
rgmii_source_1_logic = rgmii_source_1.create_logic(
|
||||
phy1_rx_clk,
|
||||
rst,
|
||||
txd=phy1_rxd,
|
||||
tx_ctl=phy1_rx_ctl,
|
||||
mii_select=mii_select_1,
|
||||
name='rgmii_source_1'
|
||||
)
|
||||
|
||||
rgmii_sink_1 = rgmii_ep.RGMIISink()
|
||||
|
||||
rgmii_sink_1_logic = rgmii_sink_1.create_logic(
|
||||
phy1_tx_clk,
|
||||
rst,
|
||||
rxd=phy1_txd,
|
||||
rx_ctl=phy1_tx_ctl,
|
||||
mii_select=mii_select_1,
|
||||
name='rgmii_sink_1'
|
||||
)
|
||||
|
||||
# DUT
|
||||
if os.system(build_cmd):
|
||||
raise Exception("Error running build command")
|
||||
|
||||
dut = Cosimulation(
|
||||
"vvp -m myhdl %s.vvp -lxt2" % testbench,
|
||||
clk=clk,
|
||||
clk90=clk90,
|
||||
rst=rst,
|
||||
current_test=current_test,
|
||||
|
||||
btn=btn,
|
||||
sw=sw,
|
||||
ledg=ledg,
|
||||
ledr=ledr,
|
||||
hex0=hex0,
|
||||
hex1=hex1,
|
||||
hex2=hex2,
|
||||
hex3=hex3,
|
||||
hex4=hex4,
|
||||
hex5=hex5,
|
||||
hex6=hex6,
|
||||
hex7=hex7,
|
||||
gpio=gpio,
|
||||
|
||||
phy0_rx_clk=phy0_rx_clk,
|
||||
phy0_rxd=phy0_rxd,
|
||||
phy0_rx_ctl=phy0_rx_ctl,
|
||||
phy0_tx_clk=phy0_tx_clk,
|
||||
phy0_txd=phy0_txd,
|
||||
phy0_tx_ctl=phy0_tx_ctl,
|
||||
phy0_reset_n=phy0_reset_n,
|
||||
phy0_int_n=phy0_int_n,
|
||||
|
||||
phy1_rx_clk=phy1_rx_clk,
|
||||
phy1_rxd=phy1_rxd,
|
||||
phy1_rx_ctl=phy1_rx_ctl,
|
||||
phy1_tx_clk=phy1_tx_clk,
|
||||
phy1_txd=phy1_txd,
|
||||
phy1_tx_ctl=phy1_tx_ctl,
|
||||
phy1_reset_n=phy1_reset_n,
|
||||
phy1_int_n=phy1_int_n
|
||||
)
|
||||
|
||||
@always(delay(4))
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
@instance
|
||||
def clkgen2():
|
||||
yield delay(4+2)
|
||||
while True:
|
||||
clk90.next = not clk90
|
||||
yield delay(4)
|
||||
|
||||
rx_clk_hp = Signal(int(4))
|
||||
|
||||
@instance
|
||||
def rx_clk_gen():
|
||||
while True:
|
||||
yield delay(int(rx_clk_hp))
|
||||
phy0_rx_clk.next = not phy0_rx_clk
|
||||
|
||||
@instance
|
||||
def check():
|
||||
yield delay(100)
|
||||
yield clk.posedge
|
||||
rst.next = 1
|
||||
yield clk.posedge
|
||||
rst.next = 0
|
||||
yield clk.posedge
|
||||
yield delay(100)
|
||||
yield clk.posedge
|
||||
|
||||
# testbench stimulus
|
||||
|
||||
yield clk.posedge
|
||||
print("test 1: test UDP RX packet")
|
||||
current_test.next = 1
|
||||
|
||||
test_frame = udp_ep.UDPFrame()
|
||||
test_frame.eth_dest_mac = 0x020000000000
|
||||
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
|
||||
test_frame.eth_type = 0x0800
|
||||
test_frame.ip_version = 4
|
||||
test_frame.ip_ihl = 5
|
||||
test_frame.ip_dscp = 0
|
||||
test_frame.ip_ecn = 0
|
||||
test_frame.ip_length = None
|
||||
test_frame.ip_identification = 0
|
||||
test_frame.ip_flags = 2
|
||||
test_frame.ip_fragment_offset = 0
|
||||
test_frame.ip_ttl = 64
|
||||
test_frame.ip_protocol = 0x11
|
||||
test_frame.ip_header_checksum = None
|
||||
test_frame.ip_source_ip = 0xc0a80181
|
||||
test_frame.ip_dest_ip = 0xc0a80180
|
||||
test_frame.udp_source_port = 5678
|
||||
test_frame.udp_dest_port = 1234
|
||||
test_frame.payload = bytearray(range(32))
|
||||
test_frame.build()
|
||||
|
||||
rgmii_source_0.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
|
||||
|
||||
# wait for ARP request packet
|
||||
while rgmii_sink_0.empty():
|
||||
yield clk.posedge
|
||||
|
||||
rx_frame = rgmii_sink_0.recv()
|
||||
check_eth_frame = eth_ep.EthFrame()
|
||||
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
|
||||
check_frame = arp_ep.ARPFrame()
|
||||
check_frame.parse_eth(check_eth_frame)
|
||||
|
||||
print(check_frame)
|
||||
|
||||
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
|
||||
assert check_frame.eth_src_mac == 0x020000000000
|
||||
assert check_frame.eth_type == 0x0806
|
||||
assert check_frame.arp_htype == 0x0001
|
||||
assert check_frame.arp_ptype == 0x0800
|
||||
assert check_frame.arp_hlen == 6
|
||||
assert check_frame.arp_plen == 4
|
||||
assert check_frame.arp_oper == 1
|
||||
assert check_frame.arp_sha == 0x020000000000
|
||||
assert check_frame.arp_spa == 0xc0a80180
|
||||
assert check_frame.arp_tha == 0x000000000000
|
||||
assert check_frame.arp_tpa == 0xc0a80181
|
||||
|
||||
# generate response
|
||||
arp_frame = arp_ep.ARPFrame()
|
||||
arp_frame.eth_dest_mac = 0x020000000000
|
||||
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
|
||||
arp_frame.eth_type = 0x0806
|
||||
arp_frame.arp_htype = 0x0001
|
||||
arp_frame.arp_ptype = 0x0800
|
||||
arp_frame.arp_hlen = 6
|
||||
arp_frame.arp_plen = 4
|
||||
arp_frame.arp_oper = 2
|
||||
arp_frame.arp_sha = 0xDAD1D2D3D4D5
|
||||
arp_frame.arp_spa = 0xc0a80181
|
||||
arp_frame.arp_tha = 0x020000000000
|
||||
arp_frame.arp_tpa = 0xc0a80180
|
||||
|
||||
rgmii_source_0.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
|
||||
|
||||
while rgmii_sink_0.empty():
|
||||
yield clk.posedge
|
||||
|
||||
rx_frame = rgmii_sink_0.recv()
|
||||
check_eth_frame = eth_ep.EthFrame()
|
||||
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
|
||||
check_frame = udp_ep.UDPFrame()
|
||||
check_frame.parse_eth(check_eth_frame)
|
||||
|
||||
print(check_frame)
|
||||
|
||||
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
|
||||
assert check_frame.eth_src_mac == 0x020000000000
|
||||
assert check_frame.eth_type == 0x0800
|
||||
assert check_frame.ip_version == 4
|
||||
assert check_frame.ip_ihl == 5
|
||||
assert check_frame.ip_dscp == 0
|
||||
assert check_frame.ip_ecn == 0
|
||||
assert check_frame.ip_identification == 0
|
||||
assert check_frame.ip_flags == 2
|
||||
assert check_frame.ip_fragment_offset == 0
|
||||
assert check_frame.ip_ttl == 64
|
||||
assert check_frame.ip_protocol == 0x11
|
||||
assert check_frame.ip_source_ip == 0xc0a80180
|
||||
assert check_frame.ip_dest_ip == 0xc0a80181
|
||||
assert check_frame.udp_source_port == 1234
|
||||
assert check_frame.udp_dest_port == 5678
|
||||
assert check_frame.payload.data == bytearray(range(32))
|
||||
|
||||
assert rgmii_source_0.empty()
|
||||
assert rgmii_sink_0.empty()
|
||||
|
||||
yield delay(100)
|
||||
|
||||
raise StopSimulation
|
||||
|
||||
return instances()
|
||||
|
||||
def test_bench():
|
||||
sim = Simulation(bench())
|
||||
sim.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Running test...")
|
||||
test_bench()
|
158
example/DE2-115/fpga/tb/test_fpga_core.v
Normal file
158
example/DE2-115/fpga/tb/test_fpga_core.v
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* Testbench for fpga_core
|
||||
*/
|
||||
module test_fpga_core;
|
||||
|
||||
// Parameters
|
||||
parameter TARGET = "SIM";
|
||||
|
||||
// Inputs
|
||||
reg clk = 0;
|
||||
reg clk90 = 0;
|
||||
reg rst = 0;
|
||||
reg [7:0] current_test = 0;
|
||||
|
||||
reg [3:0] btn = 0;
|
||||
reg [17:0] sw = 0;
|
||||
reg phy0_rx_clk = 0;
|
||||
reg [3:0] phy0_rxd = 0;
|
||||
reg phy0_rx_ctl = 0;
|
||||
reg phy0_int_n = 1;
|
||||
reg phy1_rx_clk = 0;
|
||||
reg [3:0] phy1_rxd = 0;
|
||||
reg phy1_rx_ctl = 0;
|
||||
reg phy1_int_n = 1;
|
||||
|
||||
// Outputs
|
||||
wire [17:0] ledr;
|
||||
wire [8:0] ledg;
|
||||
wire [6:0] hex0;
|
||||
wire [6:0] hex1;
|
||||
wire [6:0] hex2;
|
||||
wire [6:0] hex3;
|
||||
wire [6:0] hex4;
|
||||
wire [6:0] hex5;
|
||||
wire [6:0] hex6;
|
||||
wire [6:0] hex7;
|
||||
wire [35:0] gpio;
|
||||
wire phy0_tx_clk;
|
||||
wire [3:0] phy0_txd;
|
||||
wire phy0_tx_ctl;
|
||||
wire phy0_reset_n;
|
||||
wire phy1_tx_clk;
|
||||
wire [3:0] phy1_txd;
|
||||
wire phy1_tx_ctl;
|
||||
wire phy1_reset_n;
|
||||
|
||||
initial begin
|
||||
// myhdl integration
|
||||
$from_myhdl(
|
||||
clk,
|
||||
clk90,
|
||||
rst,
|
||||
current_test,
|
||||
btn,
|
||||
sw,
|
||||
phy0_rx_clk,
|
||||
phy0_rxd,
|
||||
phy0_rx_ctl,
|
||||
phy0_int_n,
|
||||
phy1_rx_clk,
|
||||
phy1_rxd,
|
||||
phy1_rx_ctl,
|
||||
phy1_int_n
|
||||
);
|
||||
$to_myhdl(
|
||||
ledr,
|
||||
ledg,
|
||||
hex0,
|
||||
hex1,
|
||||
hex2,
|
||||
hex3,
|
||||
hex4,
|
||||
hex5,
|
||||
hex6,
|
||||
hex7,
|
||||
gpio,
|
||||
phy0_tx_clk,
|
||||
phy0_txd,
|
||||
phy0_tx_ctl,
|
||||
phy0_reset_n,
|
||||
phy1_tx_clk,
|
||||
phy1_txd,
|
||||
phy1_tx_ctl,
|
||||
phy1_reset_n
|
||||
);
|
||||
|
||||
// dump file
|
||||
$dumpfile("test_fpga_core.lxt");
|
||||
$dumpvars(0, test_fpga_core);
|
||||
end
|
||||
|
||||
fpga_core #(
|
||||
.TARGET(TARGET)
|
||||
)
|
||||
UUT (
|
||||
.clk(clk),
|
||||
.clk90(clk90),
|
||||
.rst(rst),
|
||||
.btn(btn),
|
||||
.sw(sw),
|
||||
.ledr(ledr),
|
||||
.ledg(ledg),
|
||||
.hex0(hex0),
|
||||
.hex1(hex1),
|
||||
.hex2(hex2),
|
||||
.hex3(hex3),
|
||||
.hex4(hex4),
|
||||
.hex5(hex5),
|
||||
.hex6(hex6),
|
||||
.hex7(hex7),
|
||||
.gpio(gpio),
|
||||
.phy0_rx_clk(phy0_rx_clk),
|
||||
.phy0_rxd(phy0_rxd),
|
||||
.phy0_rx_ctl(phy0_rx_ctl),
|
||||
.phy0_tx_clk(phy0_tx_clk),
|
||||
.phy0_txd(phy0_txd),
|
||||
.phy0_tx_ctl(phy0_tx_ctl),
|
||||
.phy0_reset_n(phy0_reset_n),
|
||||
.phy0_int_n(phy0_int_n),
|
||||
.phy1_rx_clk(phy1_rx_clk),
|
||||
.phy1_rxd(phy1_rxd),
|
||||
.phy1_rx_ctl(phy1_rx_ctl),
|
||||
.phy1_tx_clk(phy1_tx_clk),
|
||||
.phy1_txd(phy1_txd),
|
||||
.phy1_tx_ctl(phy1_tx_ctl),
|
||||
.phy1_reset_n(phy1_reset_n),
|
||||
.phy1_int_n(phy1_int_n)
|
||||
);
|
||||
|
||||
endmodule
|
1
example/DE2-115/fpga/tb/udp_ep.py
Symbolic link
1
example/DE2-115/fpga/tb/udp_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/eth/tb/udp_ep.py
|
Loading…
x
Reference in New Issue
Block a user