Add AU250 AXI example design
This commit is contained in:
parent
0080f631c6
commit
722222a01c
25
example/AU250/fpga_axi/Makefile
Normal file
25
example/AU250/fpga_axi/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:
|
||||
#djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit
|
26
example/AU250/fpga_axi/README.md
Normal file
26
example/AU250/fpga_axi/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Verilog PCIe Alveo U250 Example Design
|
||||
|
||||
## Introduction
|
||||
|
||||
This example design targets the Xilinx Alveo U250 FPGA board.
|
||||
|
||||
The design implements the PCIe AXI lite master module, the PCIe AXI master
|
||||
module, and the PCIe AXI DMA module. A very simple Linux driver is included
|
||||
to test the FPGA design.
|
||||
|
||||
FPGA: xcu250-figd2104-2-e
|
||||
|
||||
## How to build
|
||||
|
||||
Run make to build. Ensure that the Xilinx Vivado toolchain components are
|
||||
in PATH.
|
||||
|
||||
Run make to build the driver. Ensure the headers for the running kernel are
|
||||
installed, otherwise the driver cannot be compiled.
|
||||
|
||||
## How to test
|
||||
|
||||
Run make program to program the Alveo U250 board with Vivado. Then load the
|
||||
driver with insmod example.ko. Check dmesg for the output.
|
||||
|
||||
|
123
example/AU250/fpga_axi/common/vivado.mk
Normal file
123
example/AU250/fpga_axi/common/vivado.mk
Normal file
@ -0,0 +1,123 @@
|
||||
###################################################################
|
||||
#
|
||||
# Xilinx Vivado FPGA Makefile
|
||||
#
|
||||
# Copyright (c) 2016 Alex Forencich
|
||||
#
|
||||
###################################################################
|
||||
#
|
||||
# Parameters:
|
||||
# FPGA_TOP - Top module name
|
||||
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
|
||||
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
|
||||
# SYN_FILES - space-separated list of source files
|
||||
# INC_FILES - space-separated list of include files
|
||||
# XDC_FILES - space-separated list of timing constraint files
|
||||
# XCI_FILES - space-separated list of IP XCI files
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# FPGA_TOP = fpga
|
||||
# FPGA_FAMILY = VirtexUltrascale
|
||||
# FPGA_DEVICE = xcvu095-ffva2104-2-e
|
||||
# SYN_FILES = rtl/fpga.v
|
||||
# XDC_FILES = fpga.xdc
|
||||
# XCI_FILES = ip/pcspma.xci
|
||||
# include ../common/vivado.mk
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# phony targets
|
||||
.PHONY: clean fpga
|
||||
|
||||
# prevent make from deleting intermediate files and reports
|
||||
.PRECIOUS: %.xpr %.bit %.mcs %.prm
|
||||
.SECONDARY:
|
||||
|
||||
CONFIG ?= config.mk
|
||||
-include ../$(CONFIG)
|
||||
|
||||
SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES))
|
||||
INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES))
|
||||
XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES))
|
||||
IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES))
|
||||
|
||||
ifdef XDC_FILES
|
||||
XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES))
|
||||
else
|
||||
XDC_FILES_REL = $(FPGA_TOP).xdc
|
||||
endif
|
||||
|
||||
###################################################################
|
||||
# Main Targets
|
||||
#
|
||||
# all: build everything
|
||||
# clean: remove output files and project files
|
||||
###################################################################
|
||||
|
||||
all: fpga
|
||||
|
||||
fpga: $(FPGA_TOP).bit
|
||||
|
||||
vivado: $(FPGA_TOP).xpr
|
||||
vivado $(FPGA_TOP).xpr
|
||||
|
||||
tmpclean:
|
||||
-rm -rf *.log *.jou *.cache *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
|
||||
-rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
|
||||
|
||||
clean: tmpclean
|
||||
-rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
|
||||
|
||||
distclean: clean
|
||||
-rm -rf rev
|
||||
|
||||
###################################################################
|
||||
# Target implementations
|
||||
###################################################################
|
||||
|
||||
# Vivado project file
|
||||
%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL)
|
||||
rm -rf defines.v
|
||||
touch defines.v
|
||||
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
|
||||
echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl
|
||||
echo "add_files -fileset sources_1 defines.v" >> create_project.tcl
|
||||
for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done
|
||||
for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done
|
||||
for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done
|
||||
for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done
|
||||
echo "exit" >> create_project.tcl
|
||||
vivado -nojournal -nolog -mode batch -source create_project.tcl
|
||||
|
||||
# synthesis run
|
||||
%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL)
|
||||
echo "open_project $*.xpr" > run_synth.tcl
|
||||
echo "reset_run synth_1" >> run_synth.tcl
|
||||
echo "launch_runs synth_1" >> run_synth.tcl
|
||||
echo "wait_on_run synth_1" >> run_synth.tcl
|
||||
echo "exit" >> run_synth.tcl
|
||||
vivado -nojournal -nolog -mode batch -source run_synth.tcl
|
||||
|
||||
# implementation run
|
||||
%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp
|
||||
echo "open_project $*.xpr" > run_impl.tcl
|
||||
echo "reset_run impl_1" >> run_impl.tcl
|
||||
echo "launch_runs impl_1" >> run_impl.tcl
|
||||
echo "wait_on_run impl_1" >> run_impl.tcl
|
||||
echo "exit" >> run_impl.tcl
|
||||
vivado -nojournal -nolog -mode batch -source run_impl.tcl
|
||||
|
||||
# bit file
|
||||
%.bit: %.runs/impl_1/%_routed.dcp
|
||||
echo "open_project $*.xpr" > generate_bit.tcl
|
||||
echo "open_run impl_1" >> generate_bit.tcl
|
||||
echo "write_bitstream -force $*.bit" >> generate_bit.tcl
|
||||
echo "exit" >> generate_bit.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
|
||||
mkdir -p rev
|
||||
EXT=bit; COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
cp $@ rev/$*_rev$$COUNT.$$EXT; \
|
||||
echo "Output: rev/$*_rev$$COUNT.$$EXT";
|
1
example/AU250/fpga_axi/driver
Symbolic link
1
example/AU250/fpga_axi/driver
Symbolic link
@ -0,0 +1 @@
|
||||
../../common/driver/
|
215
example/AU250/fpga_axi/fpga.xdc
Normal file
215
example/AU250/fpga_axi/fpga.xdc
Normal file
@ -0,0 +1,215 @@
|
||||
# XDC constraints for the Xilinx Alveo U250 board
|
||||
# part: xcu250-figd2104-2-e
|
||||
|
||||
# General configuration
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
|
||||
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_OPCODE 8'h6B [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
|
||||
|
||||
# System clocks
|
||||
# 300 MHz (DDR 0)
|
||||
#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p]
|
||||
#set_property -dict {LOC AY38 IOSTANDARD LVDS} [get_ports clk_300mhz_0_n]
|
||||
#create_clock -period 3.333 -name clk_300mhz_0 [get_ports clk_300mhz_0_p]
|
||||
|
||||
# 300 MHz (DDR 1)
|
||||
#set_property -dict {LOC AW20 IOSTANDARD LVDS} [get_ports clk_300mhz_1_p]
|
||||
#set_property -dict {LOC AW19 IOSTANDARD LVDS} [get_ports clk_300mhz_1_n]
|
||||
#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p]
|
||||
|
||||
# 300 MHz (DDR 2)
|
||||
#set_property -dict {LOC F32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_p]
|
||||
#set_property -dict {LOC E32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_n]
|
||||
#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p]
|
||||
|
||||
# 300 MHz (DDR 3)
|
||||
#set_property -dict {LOC J16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_p]
|
||||
#set_property -dict {LOC H16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_n]
|
||||
#create_clock -period 3.333 -name clk_300mhz_3 [get_ports clk_300mhz_3_p]
|
||||
|
||||
# SI570 user clock
|
||||
#set_property -dict {LOC AU19 IOSTANDARD LVDS} [get_ports clk_user_p]
|
||||
#set_property -dict {LOC AV19 IOSTANDARD LVDS} [get_ports clk_user_n]
|
||||
#create_clock -period 6.400 -name clk_user [get_ports clk_user_p]
|
||||
|
||||
# LEDs
|
||||
set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
|
||||
set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
|
||||
set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
|
||||
|
||||
# Reset button
|
||||
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
|
||||
|
||||
# DIP switches
|
||||
set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
|
||||
set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
|
||||
set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
|
||||
set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
|
||||
|
||||
# UART
|
||||
#set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_txd]
|
||||
#set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_rxd]
|
||||
|
||||
# QSFP28 Interfaces
|
||||
#set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
|
||||
#set_property -dict {LOC M11 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U14.4 via U43.13
|
||||
#set_property -dict {LOC M10 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U14.5 via U43.14
|
||||
#set_property -dict {LOC K11 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U9.18
|
||||
#set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17
|
||||
#set_property -dict {LOC BE16 IOSTANDARD LVCMOS12} [get_ports qsfp0_modsell]
|
||||
#set_property -dict {LOC BE17 IOSTANDARD LVCMOS12} [get_ports qsfp0_resetl]
|
||||
#set_property -dict {LOC BE20 IOSTANDARD LVCMOS12} [get_ports qsfp0_modprsl]
|
||||
#set_property -dict {LOC BE21 IOSTANDARD LVCMOS12} [get_ports qsfp0_intl]
|
||||
#set_property -dict {LOC BD18 IOSTANDARD LVCMOS12} [get_ports qsfp0_lpmode]
|
||||
#set_property -dict {LOC AT22 IOSTANDARD LVCMOS12} [get_ports qsfp0_refclk_reset]
|
||||
#set_property -dict {LOC AT20 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[0]}]
|
||||
#set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}]
|
||||
|
||||
# 156.25 MHz MGT reference clock (from SI570)
|
||||
#create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports qsfp0_mgt_refclk_0_p]
|
||||
|
||||
# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01)
|
||||
#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
|
||||
|
||||
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
|
||||
#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
|
||||
|
||||
#set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
|
||||
#set_property -dict {LOC T11 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U14.4 via U43.15
|
||||
#set_property -dict {LOC T10 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U14.5 via U43.16
|
||||
#set_property -dict {LOC P11 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U12.18
|
||||
#set_property -dict {LOC P10 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U12.17
|
||||
#set_property -dict {LOC AY20 IOSTANDARD LVCMOS12} [get_ports qsfp1_modsell]
|
||||
#set_property -dict {LOC BC18 IOSTANDARD LVCMOS12} [get_ports qsfp1_resetl]
|
||||
#set_property -dict {LOC BC19 IOSTANDARD LVCMOS12} [get_ports qsfp1_modprsl]
|
||||
#set_property -dict {LOC AV21 IOSTANDARD LVCMOS12} [get_ports qsfp1_intl]
|
||||
#set_property -dict {LOC AV22 IOSTANDARD LVCMOS12} [get_ports qsfp1_lpmode]
|
||||
#set_property -dict {LOC AR21 IOSTANDARD LVCMOS12} [get_ports qsfp1_refclk_reset]
|
||||
#set_property -dict {LOC AR22 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[0]}]
|
||||
#set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}]
|
||||
|
||||
# 156.25 MHz MGT reference clock (from SI570)
|
||||
#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p]
|
||||
|
||||
# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01)
|
||||
#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
|
||||
|
||||
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
|
||||
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
|
||||
|
||||
# I2C interface
|
||||
#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset]
|
||||
#set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl]
|
||||
#set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda]
|
||||
|
||||
# PCIe Interface
|
||||
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
|
||||
#set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
|
||||
set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
|
||||
#set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
|
||||
set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
|
||||
#set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
|
||||
set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y19 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y18 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y17 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4
|
||||
#set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y16 / GTYE4_COMMON_X1Y4
|
||||
set_property -dict {LOC AM11 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_226
|
||||
#set_property -dict {LOC AM10 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_226
|
||||
set_property -dict {LOC BD21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n]
|
||||
|
||||
# 100 MHz MGT reference clock
|
||||
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_p]
|
||||
|
||||
|
49
example/AU250/fpga_axi/fpga/Makefile
Normal file
49
example/AU250/fpga_axi/fpga/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcu250-figd2104-2-e
|
||||
FPGA_TOP = fpga
|
||||
FPGA_ARCH = virtexuplus
|
||||
|
||||
# Files for synthesis
|
||||
SYN_FILES = rtl/fpga.v
|
||||
SYN_FILES += rtl/fpga_core.v
|
||||
SYN_FILES += rtl/debounce_switch.v
|
||||
SYN_FILES += rtl/sync_reset.v
|
||||
SYN_FILES += rtl/sync_signal.v
|
||||
SYN_FILES += rtl/axi_ram.v
|
||||
SYN_FILES += rtl/axis_register.v
|
||||
SYN_FILES += lib/pcie/rtl/axis_arb_mux.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axil_master.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_dma.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_dma_rd.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_dma_wr.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tag_manager.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_master.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_master_rd.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axi_master_wr.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_axis_cq_demux.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_msi.v
|
||||
SYN_FILES += lib/pcie/rtl/arbiter.v
|
||||
SYN_FILES += lib/pcie/rtl/priority_encoder.v
|
||||
SYN_FILES += lib/pcie/rtl/pulse_merge.v
|
||||
|
||||
# XDC files
|
||||
XDC_FILES = fpga.xdc
|
||||
|
||||
# IP
|
||||
IP_TCL_FILES = ip/pcie4_uscale_plus_0.tcl
|
||||
|
||||
include ../common/vivado.mk
|
||||
|
||||
program: $(FPGA_TOP).bit
|
||||
echo "open_hw" > program.tcl
|
||||
echo "connect_hw_server" >> program.tcl
|
||||
echo "open_hw_target" >> program.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||
echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [current_hw_device]" >> program.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||
echo "exit" >> program.tcl
|
||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||
|
28
example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl
Normal file
28
example/AU250/fpga_axi/ip/pcie4_uscale_plus_0.tcl
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
create_ip -name pcie4_uscale_plus -vendor xilinx.com -library ip -module_name pcie4_uscale_plus_0
|
||||
|
||||
set_property -dict [list \
|
||||
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
|
||||
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X16} \
|
||||
CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \
|
||||
CONFIG.axisten_if_enable_client_tag {true} \
|
||||
CONFIG.axisten_if_width {512_bit} \
|
||||
CONFIG.axisten_freq {250} \
|
||||
CONFIG.PF0_CLASS_CODE {020000} \
|
||||
CONFIG.PF0_DEVICE_ID {0001} \
|
||||
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
|
||||
CONFIG.PF0_SUBSYSTEM_ID {0001} \
|
||||
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1234} \
|
||||
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {true} \
|
||||
CONFIG.pf0_class_code_sub {00} \
|
||||
CONFIG.pf0_base_class_menu {Network_controller} \
|
||||
CONFIG.pf0_sub_class_interface_menu {Ethernet_controller} \
|
||||
CONFIG.pf0_bar0_scale {Megabytes} \
|
||||
CONFIG.pf0_bar0_size {16} \
|
||||
CONFIG.pf0_bar1_enabled {true} \
|
||||
CONFIG.pf0_bar1_type {Memory} \
|
||||
CONFIG.pf0_bar1_scale {Megabytes} \
|
||||
CONFIG.pf0_bar1_size {16} \
|
||||
CONFIG.vendor_id {1234} \
|
||||
CONFIG.en_msi_per_vec_masking {true} \
|
||||
] [get_ips pcie4_uscale_plus_0]
|
1
example/AU250/fpga_axi/lib/pcie
Symbolic link
1
example/AU250/fpga_axi/lib/pcie
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../
|
365
example/AU250/fpga_axi/rtl/axi_ram.v
Normal file
365
example/AU250/fpga_axi/rtl/axi_ram.v
Normal file
@ -0,0 +1,365 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 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
|
||||
|
||||
/*
|
||||
* AXI4 RAM
|
||||
*/
|
||||
module axi_ram #
|
||||
(
|
||||
parameter DATA_WIDTH = 32, // width of data bus in bits
|
||||
parameter ADDR_WIDTH = 16, // width of address bus in bits
|
||||
parameter STRB_WIDTH = (DATA_WIDTH/8),
|
||||
parameter ID_WIDTH = 8,
|
||||
parameter PIPELINE_OUTPUT = 0
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
input wire [ID_WIDTH-1:0] s_axi_awid,
|
||||
input wire [ADDR_WIDTH-1:0] s_axi_awaddr,
|
||||
input wire [7:0] s_axi_awlen,
|
||||
input wire [2:0] s_axi_awsize,
|
||||
input wire [1:0] s_axi_awburst,
|
||||
input wire s_axi_awlock,
|
||||
input wire [3:0] s_axi_awcache,
|
||||
input wire [2:0] s_axi_awprot,
|
||||
input wire s_axi_awvalid,
|
||||
output wire s_axi_awready,
|
||||
input wire [DATA_WIDTH-1:0] s_axi_wdata,
|
||||
input wire [STRB_WIDTH-1:0] s_axi_wstrb,
|
||||
input wire s_axi_wlast,
|
||||
input wire s_axi_wvalid,
|
||||
output wire s_axi_wready,
|
||||
output wire [ID_WIDTH-1:0] s_axi_bid,
|
||||
output wire [1:0] s_axi_bresp,
|
||||
output wire s_axi_bvalid,
|
||||
input wire s_axi_bready,
|
||||
input wire [ID_WIDTH-1:0] s_axi_arid,
|
||||
input wire [ADDR_WIDTH-1:0] s_axi_araddr,
|
||||
input wire [7:0] s_axi_arlen,
|
||||
input wire [2:0] s_axi_arsize,
|
||||
input wire [1:0] s_axi_arburst,
|
||||
input wire s_axi_arlock,
|
||||
input wire [3:0] s_axi_arcache,
|
||||
input wire [2:0] s_axi_arprot,
|
||||
input wire s_axi_arvalid,
|
||||
output wire s_axi_arready,
|
||||
output wire [ID_WIDTH-1:0] s_axi_rid,
|
||||
output wire [DATA_WIDTH-1:0] s_axi_rdata,
|
||||
output wire [1:0] s_axi_rresp,
|
||||
output wire s_axi_rlast,
|
||||
output wire s_axi_rvalid,
|
||||
input wire s_axi_rready
|
||||
);
|
||||
|
||||
parameter VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH);
|
||||
parameter WORD_WIDTH = STRB_WIDTH;
|
||||
parameter WORD_SIZE = DATA_WIDTH/WORD_WIDTH;
|
||||
|
||||
// bus width assertions
|
||||
initial begin
|
||||
if (WORD_SIZE * STRB_WIDTH != DATA_WIDTH) begin
|
||||
$error("Error: AXI data width not evenly divisble");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (2**$clog2(WORD_WIDTH) != WORD_WIDTH) begin
|
||||
$error("Error: AXI word width must be even power of two");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
localparam [0:0]
|
||||
READ_STATE_IDLE = 1'd0,
|
||||
READ_STATE_BURST = 1'd1;
|
||||
|
||||
reg [0:0] read_state_reg = READ_STATE_IDLE, read_state_next;
|
||||
|
||||
localparam [1:0]
|
||||
WRITE_STATE_IDLE = 2'd0,
|
||||
WRITE_STATE_BURST = 2'd1,
|
||||
WRITE_STATE_RESP = 2'd2;
|
||||
|
||||
reg [1:0] write_state_reg = WRITE_STATE_IDLE, write_state_next;
|
||||
|
||||
reg mem_wr_en;
|
||||
reg mem_rd_en;
|
||||
|
||||
reg [ID_WIDTH-1:0] read_id_reg = {ID_WIDTH{1'b0}}, read_id_next;
|
||||
reg [ADDR_WIDTH-1:0] read_addr_reg = {ADDR_WIDTH{1'b0}}, read_addr_next;
|
||||
reg [7:0] read_count_reg = 8'd0, read_count_next;
|
||||
reg [2:0] read_size_reg = 3'd0, read_size_next;
|
||||
reg [1:0] read_burst_reg = 2'd0, read_burst_next;
|
||||
reg [ID_WIDTH-1:0] write_id_reg = {ID_WIDTH{1'b0}}, write_id_next;
|
||||
reg [ADDR_WIDTH-1:0] write_addr_reg = {ADDR_WIDTH{1'b0}}, write_addr_next;
|
||||
reg [7:0] write_count_reg = 8'd0, write_count_next;
|
||||
reg [2:0] write_size_reg = 3'd0, write_size_next;
|
||||
reg [1:0] write_burst_reg = 2'd0, write_burst_next;
|
||||
|
||||
reg s_axi_awready_reg = 1'b0, s_axi_awready_next;
|
||||
reg s_axi_wready_reg = 1'b0, s_axi_wready_next;
|
||||
reg [ID_WIDTH-1:0] s_axi_bid_reg = {ID_WIDTH{1'b0}}, s_axi_bid_next;
|
||||
reg s_axi_bvalid_reg = 1'b0, s_axi_bvalid_next;
|
||||
reg s_axi_arready_reg = 1'b0, s_axi_arready_next;
|
||||
reg [ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}, s_axi_rid_next;
|
||||
reg [DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}, s_axi_rdata_next;
|
||||
reg s_axi_rlast_reg = 1'b0, s_axi_rlast_next;
|
||||
reg s_axi_rvalid_reg = 1'b0, s_axi_rvalid_next;
|
||||
reg [ID_WIDTH-1:0] s_axi_rid_pipe_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DATA_WIDTH-1:0] s_axi_rdata_pipe_reg = {DATA_WIDTH{1'b0}};
|
||||
reg s_axi_rlast_pipe_reg = 1'b0;
|
||||
reg s_axi_rvalid_pipe_reg = 1'b0;
|
||||
|
||||
// (* RAM_STYLE="BLOCK" *)
|
||||
reg [DATA_WIDTH-1:0] mem[(2**VALID_ADDR_WIDTH)-1:0];
|
||||
|
||||
wire [VALID_ADDR_WIDTH-1:0] s_axi_awaddr_valid = s_axi_awaddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
|
||||
wire [VALID_ADDR_WIDTH-1:0] s_axi_araddr_valid = s_axi_araddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
|
||||
wire [VALID_ADDR_WIDTH-1:0] read_addr_valid = read_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
|
||||
wire [VALID_ADDR_WIDTH-1:0] write_addr_valid = write_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
|
||||
|
||||
assign s_axi_awready = s_axi_awready_reg;
|
||||
assign s_axi_wready = s_axi_wready_reg;
|
||||
assign s_axi_bid = s_axi_bid_reg;
|
||||
assign s_axi_bresp = 2'b00;
|
||||
assign s_axi_bvalid = s_axi_bvalid_reg;
|
||||
assign s_axi_arready = s_axi_arready_reg;
|
||||
assign s_axi_rid = PIPELINE_OUTPUT ? s_axi_rid_pipe_reg : s_axi_rid_reg;
|
||||
assign s_axi_rdata = PIPELINE_OUTPUT ? s_axi_rdata_pipe_reg : s_axi_rdata_reg;
|
||||
assign s_axi_rresp = 2'b00;
|
||||
assign s_axi_rlast = PIPELINE_OUTPUT ? s_axi_rlast_pipe_reg : s_axi_rlast_reg;
|
||||
assign s_axi_rvalid = PIPELINE_OUTPUT ? s_axi_rvalid_pipe_reg : s_axi_rvalid_reg;
|
||||
|
||||
integer i, j;
|
||||
|
||||
initial begin
|
||||
// two nested loops for smaller number of iterations per loop
|
||||
// workaround for synthesizer complaints about large loop counts
|
||||
for (i = 0; i < 2**ADDR_WIDTH; i = i + 2**(ADDR_WIDTH/2)) begin
|
||||
for (j = i; j < i + 2**(ADDR_WIDTH/2); j = j + 1) begin
|
||||
mem[j] = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @* begin
|
||||
write_state_next = WRITE_STATE_IDLE;
|
||||
|
||||
mem_wr_en = 1'b0;
|
||||
|
||||
write_id_next = write_id_reg;
|
||||
write_addr_next = write_addr_reg;
|
||||
write_count_next = write_count_reg;
|
||||
write_size_next = write_size_reg;
|
||||
write_burst_next = write_burst_reg;
|
||||
|
||||
s_axi_awready_next = 1'b0;
|
||||
s_axi_wready_next = 1'b0;
|
||||
s_axi_bid_next = s_axi_bid_reg;
|
||||
s_axi_bvalid_next = s_axi_bvalid_reg && !s_axi_bready;
|
||||
|
||||
case (write_state_reg)
|
||||
WRITE_STATE_IDLE: begin
|
||||
s_axi_awready_next = 1'b1;
|
||||
|
||||
if (s_axi_awready && s_axi_awvalid) begin
|
||||
write_id_next = s_axi_awid;
|
||||
write_addr_next = s_axi_awaddr;
|
||||
write_count_next = s_axi_awlen;
|
||||
write_size_next = s_axi_awsize < $clog2(STRB_WIDTH) ? s_axi_awsize : $clog2(STRB_WIDTH);
|
||||
write_burst_next = s_axi_awburst;
|
||||
|
||||
s_axi_awready_next = 1'b0;
|
||||
s_axi_wready_next = 1'b1;
|
||||
write_state_next = WRITE_STATE_BURST;
|
||||
end else begin
|
||||
write_state_next = WRITE_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
WRITE_STATE_BURST: begin
|
||||
s_axi_wready_next = 1'b1;
|
||||
|
||||
if (s_axi_wready && s_axi_wvalid) begin
|
||||
mem_wr_en = 1'b1;
|
||||
if (write_burst_reg != 2'b00) begin
|
||||
write_addr_next = write_addr_reg + (1 << write_size_reg);
|
||||
end
|
||||
write_count_next = write_count_reg - 1;
|
||||
if (write_count_reg > 0) begin
|
||||
write_state_next = WRITE_STATE_BURST;
|
||||
end else begin
|
||||
s_axi_wready_next = 1'b0;
|
||||
if (s_axi_bready || !s_axi_bvalid) begin
|
||||
s_axi_bid_next = write_id_reg;
|
||||
s_axi_bvalid_next = 1'b1;
|
||||
s_axi_awready_next = 1'b1;
|
||||
write_state_next = WRITE_STATE_IDLE;
|
||||
end else begin
|
||||
write_state_next = WRITE_STATE_RESP;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
write_state_next = WRITE_STATE_BURST;
|
||||
end
|
||||
end
|
||||
WRITE_STATE_RESP: begin
|
||||
if (s_axi_bready || !s_axi_bvalid) begin
|
||||
s_axi_bid_next = write_id_reg;
|
||||
s_axi_bvalid_next = 1'b1;
|
||||
s_axi_awready_next = 1'b1;
|
||||
write_state_next = WRITE_STATE_IDLE;
|
||||
end else begin
|
||||
write_state_next = WRITE_STATE_RESP;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
write_state_reg <= WRITE_STATE_IDLE;
|
||||
s_axi_awready_reg <= 1'b0;
|
||||
s_axi_wready_reg <= 1'b0;
|
||||
s_axi_bvalid_reg <= 1'b0;
|
||||
end else begin
|
||||
write_state_reg <= write_state_next;
|
||||
s_axi_awready_reg <= s_axi_awready_next;
|
||||
s_axi_wready_reg <= s_axi_wready_next;
|
||||
s_axi_bvalid_reg <= s_axi_bvalid_next;
|
||||
end
|
||||
|
||||
write_id_reg <= write_id_next;
|
||||
write_addr_reg <= write_addr_next;
|
||||
write_count_reg <= write_count_next;
|
||||
write_size_reg <= write_size_next;
|
||||
write_burst_reg <= write_burst_next;
|
||||
|
||||
s_axi_bid_reg <= s_axi_bid_next;
|
||||
|
||||
for (i = 0; i < WORD_WIDTH; i = i + 1) begin
|
||||
if (mem_wr_en & s_axi_wstrb[i]) begin
|
||||
mem[write_addr_valid][WORD_SIZE*i +: WORD_SIZE] <= s_axi_wdata[WORD_SIZE*i +: WORD_SIZE];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @* begin
|
||||
read_state_next = READ_STATE_IDLE;
|
||||
|
||||
mem_rd_en = 1'b0;
|
||||
|
||||
s_axi_rid_next = s_axi_rid_reg;
|
||||
s_axi_rlast_next = s_axi_rlast_reg;
|
||||
s_axi_rvalid_next = s_axi_rvalid_reg && !(s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg));
|
||||
|
||||
read_id_next = read_id_reg;
|
||||
read_addr_next = read_addr_reg;
|
||||
read_count_next = read_count_reg;
|
||||
read_size_next = read_size_reg;
|
||||
read_burst_next = read_burst_reg;
|
||||
|
||||
s_axi_arready_next = 1'b0;
|
||||
|
||||
case (read_state_reg)
|
||||
READ_STATE_IDLE: begin
|
||||
s_axi_arready_next = 1'b1;
|
||||
|
||||
if (s_axi_arready && s_axi_arvalid) begin
|
||||
read_id_next = s_axi_arid;
|
||||
read_addr_next = s_axi_araddr;
|
||||
read_count_next = s_axi_arlen;
|
||||
read_size_next = s_axi_arsize < $clog2(STRB_WIDTH) ? s_axi_arsize : $clog2(STRB_WIDTH);
|
||||
read_burst_next = s_axi_arburst;
|
||||
|
||||
s_axi_arready_next = 1'b0;
|
||||
read_state_next = READ_STATE_BURST;
|
||||
end else begin
|
||||
read_state_next = READ_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
READ_STATE_BURST: begin
|
||||
if (s_axi_rready || (PIPELINE_OUTPUT && !s_axi_rvalid_pipe_reg) || !s_axi_rvalid_reg) begin
|
||||
mem_rd_en = 1'b1;
|
||||
s_axi_rvalid_next = 1'b1;
|
||||
s_axi_rid_next = read_id_reg;
|
||||
s_axi_rlast_next = read_count_reg == 0;
|
||||
if (read_burst_reg != 2'b00) begin
|
||||
read_addr_next = read_addr_reg + (1 << read_size_reg);
|
||||
end
|
||||
read_count_next = read_count_reg - 1;
|
||||
if (read_count_reg > 0) begin
|
||||
read_state_next = READ_STATE_BURST;
|
||||
end else begin
|
||||
s_axi_arready_next = 1'b1;
|
||||
read_state_next = READ_STATE_IDLE;
|
||||
end
|
||||
end else begin
|
||||
read_state_next = READ_STATE_BURST;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
read_state_reg <= READ_STATE_IDLE;
|
||||
s_axi_arready_reg <= 1'b0;
|
||||
s_axi_rvalid_reg <= 1'b0;
|
||||
s_axi_rvalid_pipe_reg <= 1'b0;
|
||||
end else begin
|
||||
read_state_reg <= read_state_next;
|
||||
s_axi_arready_reg <= s_axi_arready_next;
|
||||
s_axi_rvalid_reg <= s_axi_rvalid_next;
|
||||
|
||||
if (!s_axi_rvalid_pipe_reg || s_axi_rready) begin
|
||||
s_axi_rvalid_pipe_reg <= s_axi_rvalid_reg;
|
||||
end
|
||||
end
|
||||
|
||||
read_id_reg <= read_id_next;
|
||||
read_addr_reg <= read_addr_next;
|
||||
read_count_reg <= read_count_next;
|
||||
read_size_reg <= read_size_next;
|
||||
read_burst_reg <= read_burst_next;
|
||||
|
||||
s_axi_rid_reg <= s_axi_rid_next;
|
||||
s_axi_rlast_reg <= s_axi_rlast_next;
|
||||
|
||||
if (mem_rd_en) begin
|
||||
s_axi_rdata_reg <= mem[read_addr_valid];
|
||||
end
|
||||
|
||||
if (!s_axi_rvalid_pipe_reg || s_axi_rready) begin
|
||||
s_axi_rid_pipe_reg <= s_axi_rid_reg;
|
||||
s_axi_rdata_pipe_reg <= s_axi_rdata_reg;
|
||||
s_axi_rlast_pipe_reg <= s_axi_rlast_reg;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
264
example/AU250/fpga_axi/rtl/axis_register.v
Normal file
264
example/AU250/fpga_axi/rtl/axis_register.v
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* AXI4-Stream register
|
||||
*/
|
||||
module axis_register #
|
||||
(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter KEEP_ENABLE = (DATA_WIDTH>8),
|
||||
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||
parameter LAST_ENABLE = 1,
|
||||
parameter ID_ENABLE = 0,
|
||||
parameter ID_WIDTH = 8,
|
||||
parameter DEST_ENABLE = 0,
|
||||
parameter DEST_WIDTH = 8,
|
||||
parameter USER_ENABLE = 1,
|
||||
parameter USER_WIDTH = 1,
|
||||
parameter REG_TYPE = 2
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/*
|
||||
* AXI Stream input
|
||||
*/
|
||||
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
||||
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||
input wire s_axis_tvalid,
|
||||
output wire s_axis_tready,
|
||||
input wire s_axis_tlast,
|
||||
input wire [ID_WIDTH-1:0] s_axis_tid,
|
||||
input wire [DEST_WIDTH-1:0] s_axis_tdest,
|
||||
input wire [USER_WIDTH-1:0] s_axis_tuser,
|
||||
|
||||
/*
|
||||
* AXI Stream output
|
||||
*/
|
||||
output wire [DATA_WIDTH-1:0] m_axis_tdata,
|
||||
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||
output wire m_axis_tvalid,
|
||||
input wire m_axis_tready,
|
||||
output wire m_axis_tlast,
|
||||
output wire [ID_WIDTH-1:0] m_axis_tid,
|
||||
output wire [DEST_WIDTH-1:0] m_axis_tdest,
|
||||
output wire [USER_WIDTH-1:0] m_axis_tuser
|
||||
);
|
||||
|
||||
generate
|
||||
|
||||
if (REG_TYPE > 1) begin
|
||||
// skid buffer, no bubble cycles
|
||||
|
||||
// datapath registers
|
||||
reg s_axis_tready_reg = 1'b0;
|
||||
|
||||
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
|
||||
reg m_axis_tlast_reg = 1'b0;
|
||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||
|
||||
reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||
reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||
reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next;
|
||||
reg temp_m_axis_tlast_reg = 1'b0;
|
||||
reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||
reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||
|
||||
// datapath control
|
||||
reg store_axis_input_to_output;
|
||||
reg store_axis_input_to_temp;
|
||||
reg store_axis_temp_to_output;
|
||||
|
||||
assign s_axis_tready = s_axis_tready_reg;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_reg;
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||
wire s_axis_tready_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !s_axis_tvalid));
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
m_axis_tvalid_next = m_axis_tvalid_reg;
|
||||
temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg;
|
||||
|
||||
store_axis_input_to_output = 1'b0;
|
||||
store_axis_input_to_temp = 1'b0;
|
||||
store_axis_temp_to_output = 1'b0;
|
||||
|
||||
if (s_axis_tready_reg) begin
|
||||
// input is ready
|
||||
if (m_axis_tready || !m_axis_tvalid_reg) begin
|
||||
// output is ready or currently not valid, transfer data to output
|
||||
m_axis_tvalid_next = s_axis_tvalid;
|
||||
store_axis_input_to_output = 1'b1;
|
||||
end else begin
|
||||
// output is not ready, store input in temp
|
||||
temp_m_axis_tvalid_next = s_axis_tvalid;
|
||||
store_axis_input_to_temp = 1'b1;
|
||||
end
|
||||
end else if (m_axis_tready) begin
|
||||
// input is not ready, but output is ready
|
||||
m_axis_tvalid_next = temp_m_axis_tvalid_reg;
|
||||
temp_m_axis_tvalid_next = 1'b0;
|
||||
store_axis_temp_to_output = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
s_axis_tready_reg <= 1'b0;
|
||||
m_axis_tvalid_reg <= 1'b0;
|
||||
temp_m_axis_tvalid_reg <= 1'b0;
|
||||
end else begin
|
||||
s_axis_tready_reg <= s_axis_tready_early;
|
||||
m_axis_tvalid_reg <= m_axis_tvalid_next;
|
||||
temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next;
|
||||
end
|
||||
|
||||
// datapath
|
||||
if (store_axis_input_to_output) begin
|
||||
m_axis_tdata_reg <= s_axis_tdata;
|
||||
m_axis_tkeep_reg <= s_axis_tkeep;
|
||||
m_axis_tlast_reg <= s_axis_tlast;
|
||||
m_axis_tid_reg <= s_axis_tid;
|
||||
m_axis_tdest_reg <= s_axis_tdest;
|
||||
m_axis_tuser_reg <= s_axis_tuser;
|
||||
end else if (store_axis_temp_to_output) begin
|
||||
m_axis_tdata_reg <= temp_m_axis_tdata_reg;
|
||||
m_axis_tkeep_reg <= temp_m_axis_tkeep_reg;
|
||||
m_axis_tlast_reg <= temp_m_axis_tlast_reg;
|
||||
m_axis_tid_reg <= temp_m_axis_tid_reg;
|
||||
m_axis_tdest_reg <= temp_m_axis_tdest_reg;
|
||||
m_axis_tuser_reg <= temp_m_axis_tuser_reg;
|
||||
end
|
||||
|
||||
if (store_axis_input_to_temp) begin
|
||||
temp_m_axis_tdata_reg <= s_axis_tdata;
|
||||
temp_m_axis_tkeep_reg <= s_axis_tkeep;
|
||||
temp_m_axis_tlast_reg <= s_axis_tlast;
|
||||
temp_m_axis_tid_reg <= s_axis_tid;
|
||||
temp_m_axis_tdest_reg <= s_axis_tdest;
|
||||
temp_m_axis_tuser_reg <= s_axis_tuser;
|
||||
end
|
||||
end
|
||||
|
||||
end else if (REG_TYPE == 1) begin
|
||||
// simple register, inserts bubble cycles
|
||||
|
||||
// datapath registers
|
||||
reg s_axis_tready_reg = 1'b0;
|
||||
|
||||
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
|
||||
reg m_axis_tlast_reg = 1'b0;
|
||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||
|
||||
// datapath control
|
||||
reg store_axis_input_to_output;
|
||||
|
||||
assign s_axis_tready = s_axis_tready_reg;
|
||||
|
||||
assign m_axis_tdata = m_axis_tdata_reg;
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||
|
||||
// enable ready input next cycle if output buffer will be empty
|
||||
wire s_axis_tready_early = !m_axis_tvalid_next;
|
||||
|
||||
always @* begin
|
||||
// transfer sink ready state to source
|
||||
m_axis_tvalid_next = m_axis_tvalid_reg;
|
||||
|
||||
store_axis_input_to_output = 1'b0;
|
||||
|
||||
if (s_axis_tready_reg) begin
|
||||
m_axis_tvalid_next = s_axis_tvalid;
|
||||
store_axis_input_to_output = 1'b1;
|
||||
end else if (m_axis_tready) begin
|
||||
m_axis_tvalid_next = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
s_axis_tready_reg <= 1'b0;
|
||||
m_axis_tvalid_reg <= 1'b0;
|
||||
end else begin
|
||||
s_axis_tready_reg <= s_axis_tready_early;
|
||||
m_axis_tvalid_reg <= m_axis_tvalid_next;
|
||||
end
|
||||
|
||||
// datapath
|
||||
if (store_axis_input_to_output) begin
|
||||
m_axis_tdata_reg <= s_axis_tdata;
|
||||
m_axis_tkeep_reg <= s_axis_tkeep;
|
||||
m_axis_tlast_reg <= s_axis_tlast;
|
||||
m_axis_tid_reg <= s_axis_tid;
|
||||
m_axis_tdest_reg <= s_axis_tdest;
|
||||
m_axis_tuser_reg <= s_axis_tuser;
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
// bypass
|
||||
|
||||
assign m_axis_tdata = s_axis_tdata;
|
||||
assign m_axis_tkeep = KEEP_ENABLE ? s_axis_tkeep : {KEEP_WIDTH{1'b1}};
|
||||
assign m_axis_tvalid = s_axis_tvalid;
|
||||
assign m_axis_tlast = LAST_ENABLE ? s_axis_tlast : 1'b1;
|
||||
assign m_axis_tid = ID_ENABLE ? s_axis_tid : {ID_WIDTH{1'b0}};
|
||||
assign m_axis_tdest = DEST_ENABLE ? s_axis_tdest : {DEST_WIDTH{1'b0}};
|
||||
assign m_axis_tuser = USER_ENABLE ? s_axis_tuser : {USER_WIDTH{1'b0}};
|
||||
|
||||
assign s_axis_tready = m_axis_tready;
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
89
example/AU250/fpga_axi/rtl/debounce_switch.v
Normal file
89
example/AU250/fpga_axi/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
|
424
example/AU250/fpga_axi/rtl/fpga.v
Normal file
424
example/AU250/fpga_axi/rtl/fpga.v
Normal file
@ -0,0 +1,424 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* FPGA top-level module
|
||||
*/
|
||||
module fpga (
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
input wire [3:0] sw,
|
||||
output wire [2:0] led,
|
||||
|
||||
/*
|
||||
* PCI express
|
||||
*/
|
||||
input wire [15:0] pcie_rx_p,
|
||||
input wire [15:0] pcie_rx_n,
|
||||
output wire [15:0] pcie_tx_p,
|
||||
output wire [15:0] pcie_tx_n,
|
||||
input wire pcie_refclk_p,
|
||||
input wire pcie_refclk_n,
|
||||
input wire pcie_reset_n
|
||||
);
|
||||
|
||||
parameter AXIS_PCIE_DATA_WIDTH = 512;
|
||||
parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32);
|
||||
parameter AXIS_PCIE_RC_USER_WIDTH = 161;
|
||||
parameter AXIS_PCIE_RQ_USER_WIDTH = 137;
|
||||
parameter AXIS_PCIE_CQ_USER_WIDTH = 183;
|
||||
parameter AXIS_PCIE_CC_USER_WIDTH = 81;
|
||||
|
||||
// Clock and reset
|
||||
wire pcie_user_clk;
|
||||
wire pcie_user_reset;
|
||||
|
||||
// GPIO
|
||||
wire [3:0] sw_int;
|
||||
|
||||
debounce_switch #(
|
||||
.WIDTH(4),
|
||||
.N(4),
|
||||
.RATE(250000)
|
||||
)
|
||||
debounce_switch_inst (
|
||||
.clk(pcie_user_clk),
|
||||
.rst(pcie_user_reset),
|
||||
.in({sw}),
|
||||
.out({sw_int})
|
||||
);
|
||||
|
||||
// PCIe
|
||||
wire pcie_sys_clk;
|
||||
wire pcie_sys_clk_gt;
|
||||
|
||||
IBUFDS_GTE4 #(
|
||||
.REFCLK_HROW_CK_SEL(2'b00)
|
||||
)
|
||||
ibufds_gte4_pcie_mgt_refclk_inst (
|
||||
.I (pcie_refclk_p),
|
||||
.IB (pcie_refclk_n),
|
||||
.CEB (1'b0),
|
||||
.O (pcie_sys_clk_gt),
|
||||
.ODIV2 (pcie_sys_clk)
|
||||
);
|
||||
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rq_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rq_tkeep;
|
||||
wire axis_rq_tlast;
|
||||
wire axis_rq_tready;
|
||||
wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] axis_rq_tuser;
|
||||
wire axis_rq_tvalid;
|
||||
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_rc_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_rc_tkeep;
|
||||
wire axis_rc_tlast;
|
||||
wire axis_rc_tready;
|
||||
wire [AXIS_PCIE_RC_USER_WIDTH-1:0] axis_rc_tuser;
|
||||
wire axis_rc_tvalid;
|
||||
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cq_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cq_tkeep;
|
||||
wire axis_cq_tlast;
|
||||
wire axis_cq_tready;
|
||||
wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] axis_cq_tuser;
|
||||
wire axis_cq_tvalid;
|
||||
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] axis_cc_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] axis_cc_tkeep;
|
||||
wire axis_cc_tlast;
|
||||
wire axis_cc_tready;
|
||||
wire [AXIS_PCIE_CC_USER_WIDTH-1:0] axis_cc_tuser;
|
||||
wire axis_cc_tvalid;
|
||||
|
||||
// ila_0 rq_ila (
|
||||
// .clk(pcie_user_clk),
|
||||
// .probe0(axis_rq_tdata),
|
||||
// .probe1(axis_rq_tkeep),
|
||||
// .probe2(axis_rq_tlast),
|
||||
// .probe3(axis_rq_tready),
|
||||
// .probe4(axis_rq_tuser),
|
||||
// .probe5(axis_rq_tvalid)
|
||||
// );
|
||||
|
||||
// ila_0 rc_ila (
|
||||
// .clk(pcie_user_clk),
|
||||
// .probe0(axis_rc_tdata),
|
||||
// .probe1(axis_rc_tkeep),
|
||||
// .probe2(axis_rc_tlast),
|
||||
// .probe3(axis_rc_tready),
|
||||
// .probe4(axis_rc_tuser),
|
||||
// .probe5(axis_rc_tvalid)
|
||||
// );
|
||||
|
||||
wire [2:0] cfg_max_payload;
|
||||
wire [2:0] cfg_max_read_req;
|
||||
|
||||
wire [9:0] cfg_mgmt_addr;
|
||||
wire [7:0] cfg_mgmt_function_number;
|
||||
wire cfg_mgmt_write;
|
||||
wire [31:0] cfg_mgmt_write_data;
|
||||
wire [3:0] cfg_mgmt_byte_enable;
|
||||
wire cfg_mgmt_read;
|
||||
wire [31:0] cfg_mgmt_read_data;
|
||||
wire cfg_mgmt_read_write_done;
|
||||
|
||||
wire [3:0] cfg_interrupt_msi_enable;
|
||||
wire [11:0] cfg_interrupt_msi_mmenable;
|
||||
wire cfg_interrupt_msi_mask_update;
|
||||
wire [31:0] cfg_interrupt_msi_data;
|
||||
wire [3:0] cfg_interrupt_msi_select;
|
||||
wire [31:0] cfg_interrupt_msi_int;
|
||||
wire [31:0] cfg_interrupt_msi_pending_status;
|
||||
wire cfg_interrupt_msi_pending_status_data_enable;
|
||||
wire [3:0] cfg_interrupt_msi_pending_status_function_num;
|
||||
wire cfg_interrupt_msi_sent;
|
||||
wire cfg_interrupt_msi_fail;
|
||||
wire [2:0] cfg_interrupt_msi_attr;
|
||||
wire cfg_interrupt_msi_tph_present;
|
||||
wire [1:0] cfg_interrupt_msi_tph_type;
|
||||
wire [8:0] cfg_interrupt_msi_tph_st_tag;
|
||||
wire [3:0] cfg_interrupt_msi_function_number;
|
||||
|
||||
wire status_error_cor;
|
||||
wire status_error_uncor;
|
||||
|
||||
pcie4_uscale_plus_0
|
||||
pcie4_uscale_plus_inst (
|
||||
.pci_exp_txn(pcie_tx_n),
|
||||
.pci_exp_txp(pcie_tx_p),
|
||||
.pci_exp_rxn(pcie_rx_n),
|
||||
.pci_exp_rxp(pcie_rx_p),
|
||||
.user_clk(pcie_user_clk),
|
||||
.user_reset(pcie_user_reset),
|
||||
.user_lnk_up(),
|
||||
|
||||
.s_axis_rq_tdata(axis_rq_tdata),
|
||||
.s_axis_rq_tkeep(axis_rq_tkeep),
|
||||
.s_axis_rq_tlast(axis_rq_tlast),
|
||||
.s_axis_rq_tready(axis_rq_tready),
|
||||
.s_axis_rq_tuser(axis_rq_tuser),
|
||||
.s_axis_rq_tvalid(axis_rq_tvalid),
|
||||
|
||||
.m_axis_rc_tdata(axis_rc_tdata),
|
||||
.m_axis_rc_tkeep(axis_rc_tkeep),
|
||||
.m_axis_rc_tlast(axis_rc_tlast),
|
||||
.m_axis_rc_tready(axis_rc_tready),
|
||||
.m_axis_rc_tuser(axis_rc_tuser),
|
||||
.m_axis_rc_tvalid(axis_rc_tvalid),
|
||||
|
||||
.m_axis_cq_tdata(axis_cq_tdata),
|
||||
.m_axis_cq_tkeep(axis_cq_tkeep),
|
||||
.m_axis_cq_tlast(axis_cq_tlast),
|
||||
.m_axis_cq_tready(axis_cq_tready),
|
||||
.m_axis_cq_tuser(axis_cq_tuser),
|
||||
.m_axis_cq_tvalid(axis_cq_tvalid),
|
||||
|
||||
.s_axis_cc_tdata(axis_cc_tdata),
|
||||
.s_axis_cc_tkeep(axis_cc_tkeep),
|
||||
.s_axis_cc_tlast(axis_cc_tlast),
|
||||
.s_axis_cc_tready(axis_cc_tready),
|
||||
.s_axis_cc_tuser(axis_cc_tuser),
|
||||
.s_axis_cc_tvalid(axis_cc_tvalid),
|
||||
|
||||
.pcie_rq_seq_num0(),
|
||||
.pcie_rq_seq_num_vld0(),
|
||||
.pcie_rq_seq_num1(),
|
||||
.pcie_rq_seq_num_vld1(),
|
||||
.pcie_rq_tag0(),
|
||||
.pcie_rq_tag1(),
|
||||
.pcie_rq_tag_av(),
|
||||
.pcie_rq_tag_vld0(),
|
||||
.pcie_rq_tag_vld1(),
|
||||
|
||||
.pcie_tfc_nph_av(),
|
||||
.pcie_tfc_npd_av(),
|
||||
|
||||
.pcie_cq_np_req(1'b1),
|
||||
.pcie_cq_np_req_count(),
|
||||
|
||||
.cfg_phy_link_down(),
|
||||
.cfg_phy_link_status(),
|
||||
.cfg_negotiated_width(),
|
||||
.cfg_current_speed(),
|
||||
.cfg_max_payload(cfg_max_payload),
|
||||
.cfg_max_read_req(cfg_max_read_req),
|
||||
.cfg_function_status(),
|
||||
.cfg_function_power_state(),
|
||||
.cfg_vf_status(),
|
||||
.cfg_vf_power_state(),
|
||||
.cfg_link_power_state(),
|
||||
|
||||
.cfg_mgmt_addr(cfg_mgmt_addr),
|
||||
.cfg_mgmt_function_number(cfg_mgmt_function_number),
|
||||
.cfg_mgmt_write(cfg_mgmt_write),
|
||||
.cfg_mgmt_write_data(cfg_mgmt_write_data),
|
||||
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
|
||||
.cfg_mgmt_read(cfg_mgmt_read),
|
||||
.cfg_mgmt_read_data(cfg_mgmt_read_data),
|
||||
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
|
||||
.cfg_mgmt_debug_access(1'b0),
|
||||
|
||||
.cfg_err_cor_out(),
|
||||
.cfg_err_nonfatal_out(),
|
||||
.cfg_err_fatal_out(),
|
||||
.cfg_local_error_valid(),
|
||||
.cfg_local_error_out(),
|
||||
.cfg_ltssm_state(),
|
||||
.cfg_rx_pm_state(),
|
||||
.cfg_tx_pm_state(),
|
||||
.cfg_rcb_status(),
|
||||
.cfg_obff_enable(),
|
||||
.cfg_pl_status_change(),
|
||||
.cfg_tph_requester_enable(),
|
||||
.cfg_tph_st_mode(),
|
||||
.cfg_vf_tph_requester_enable(),
|
||||
.cfg_vf_tph_st_mode(),
|
||||
|
||||
.cfg_msg_received(),
|
||||
.cfg_msg_received_data(),
|
||||
.cfg_msg_received_type(),
|
||||
.cfg_msg_transmit(1'b0),
|
||||
.cfg_msg_transmit_type(3'd0),
|
||||
.cfg_msg_transmit_data(32'd0),
|
||||
.cfg_msg_transmit_done(),
|
||||
|
||||
.cfg_fc_ph(),
|
||||
.cfg_fc_pd(),
|
||||
.cfg_fc_nph(),
|
||||
.cfg_fc_npd(),
|
||||
.cfg_fc_cplh(),
|
||||
.cfg_fc_cpld(),
|
||||
.cfg_fc_sel(3'd0),
|
||||
|
||||
.cfg_dsn(64'd0),
|
||||
|
||||
.cfg_bus_number(),
|
||||
|
||||
.cfg_power_state_change_ack(1'b1),
|
||||
.cfg_power_state_change_interrupt(),
|
||||
|
||||
.cfg_err_cor_in(status_error_cor),
|
||||
.cfg_err_uncor_in(status_error_uncor),
|
||||
.cfg_flr_in_process(),
|
||||
.cfg_flr_done(4'd0),
|
||||
.cfg_vf_flr_in_process(),
|
||||
.cfg_vf_flr_func_num(8'd0),
|
||||
.cfg_vf_flr_done(8'd0),
|
||||
|
||||
.cfg_link_training_enable(1'b1),
|
||||
|
||||
.cfg_interrupt_int(4'd0),
|
||||
.cfg_interrupt_pending(4'd0),
|
||||
.cfg_interrupt_sent(),
|
||||
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
|
||||
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
|
||||
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
|
||||
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
|
||||
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
|
||||
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
|
||||
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
|
||||
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
|
||||
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
|
||||
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
|
||||
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
|
||||
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
|
||||
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
|
||||
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
|
||||
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
||||
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
||||
|
||||
.cfg_pm_aspm_l1_entry_reject(1'b0),
|
||||
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
|
||||
|
||||
.cfg_hot_reset_out(),
|
||||
|
||||
.cfg_config_space_enable(1'b1),
|
||||
.cfg_req_pm_transition_l23_ready(1'b0),
|
||||
.cfg_hot_reset_in(1'b0),
|
||||
|
||||
.cfg_ds_port_number(8'd0),
|
||||
.cfg_ds_bus_number(8'd0),
|
||||
.cfg_ds_device_number(5'd0),
|
||||
//.cfg_ds_function_number(3'd0),
|
||||
|
||||
//.cfg_subsys_vend_id(16'h1234),
|
||||
|
||||
.sys_clk(pcie_sys_clk),
|
||||
.sys_clk_gt(pcie_sys_clk_gt),
|
||||
.sys_reset(pcie_reset_n),
|
||||
|
||||
.phy_rdy_out()
|
||||
);
|
||||
|
||||
fpga_core #(
|
||||
.AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH),
|
||||
.AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH),
|
||||
.AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH),
|
||||
.AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH),
|
||||
.AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH),
|
||||
.AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH)
|
||||
)
|
||||
core_inst (
|
||||
/*
|
||||
* Clock: 250 MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
.clk(pcie_user_clk),
|
||||
.rst(pcie_user_reset),
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.sw(sw_int),
|
||||
.led(led),
|
||||
/*
|
||||
* PCIe
|
||||
*/
|
||||
.m_axis_rq_tdata(axis_rq_tdata),
|
||||
.m_axis_rq_tkeep(axis_rq_tkeep),
|
||||
.m_axis_rq_tlast(axis_rq_tlast),
|
||||
.m_axis_rq_tready(axis_rq_tready),
|
||||
.m_axis_rq_tuser(axis_rq_tuser),
|
||||
.m_axis_rq_tvalid(axis_rq_tvalid),
|
||||
|
||||
.s_axis_rc_tdata(axis_rc_tdata),
|
||||
.s_axis_rc_tkeep(axis_rc_tkeep),
|
||||
.s_axis_rc_tlast(axis_rc_tlast),
|
||||
.s_axis_rc_tready(axis_rc_tready),
|
||||
.s_axis_rc_tuser(axis_rc_tuser),
|
||||
.s_axis_rc_tvalid(axis_rc_tvalid),
|
||||
|
||||
.s_axis_cq_tdata(axis_cq_tdata),
|
||||
.s_axis_cq_tkeep(axis_cq_tkeep),
|
||||
.s_axis_cq_tlast(axis_cq_tlast),
|
||||
.s_axis_cq_tready(axis_cq_tready),
|
||||
.s_axis_cq_tuser(axis_cq_tuser),
|
||||
.s_axis_cq_tvalid(axis_cq_tvalid),
|
||||
|
||||
.m_axis_cc_tdata(axis_cc_tdata),
|
||||
.m_axis_cc_tkeep(axis_cc_tkeep),
|
||||
.m_axis_cc_tlast(axis_cc_tlast),
|
||||
.m_axis_cc_tready(axis_cc_tready),
|
||||
.m_axis_cc_tuser(axis_cc_tuser),
|
||||
.m_axis_cc_tvalid(axis_cc_tvalid),
|
||||
|
||||
.cfg_max_payload(cfg_max_payload),
|
||||
.cfg_max_read_req(cfg_max_read_req),
|
||||
|
||||
.cfg_mgmt_addr(cfg_mgmt_addr),
|
||||
.cfg_mgmt_function_number(cfg_mgmt_function_number),
|
||||
.cfg_mgmt_write(cfg_mgmt_write),
|
||||
.cfg_mgmt_write_data(cfg_mgmt_write_data),
|
||||
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
|
||||
.cfg_mgmt_read(cfg_mgmt_read),
|
||||
.cfg_mgmt_read_data(cfg_mgmt_read_data),
|
||||
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
|
||||
|
||||
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
|
||||
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
|
||||
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
|
||||
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
|
||||
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
|
||||
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
|
||||
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
|
||||
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
|
||||
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
|
||||
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
|
||||
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
|
||||
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
|
||||
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
|
||||
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
|
||||
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
||||
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
||||
|
||||
.status_error_cor(status_error_cor),
|
||||
.status_error_uncor(status_error_uncor)
|
||||
);
|
||||
|
||||
endmodule
|
1089
example/AU250/fpga_axi/rtl/fpga_core.v
Normal file
1089
example/AU250/fpga_axi/rtl/fpga_core.v
Normal file
File diff suppressed because it is too large
Load Diff
52
example/AU250/fpga_axi/rtl/sync_reset.v
Normal file
52
example/AU250/fpga_axi/rtl/sync_reset.v
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
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 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
|
58
example/AU250/fpga_axi/rtl/sync_signal.v
Normal file
58
example/AU250/fpga_axi/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/AU250/fpga_axi/tb/axis_ep.py
Symbolic link
1
example/AU250/fpga_axi/tb/axis_ep.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/pcie/tb/axis_ep.py
|
1
example/AU250/fpga_axi/tb/pcie.py
Symbolic link
1
example/AU250/fpga_axi/tb/pcie.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/pcie/tb/pcie.py
|
1
example/AU250/fpga_axi/tb/pcie_us.py
Symbolic link
1
example/AU250/fpga_axi/tb/pcie_us.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/pcie/tb/pcie_us.py
|
1
example/AU250/fpga_axi/tb/pcie_usp.py
Symbolic link
1
example/AU250/fpga_axi/tb/pcie_usp.py
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/pcie/tb/pcie_usp.py
|
520
example/AU250/fpga_axi/tb/test_fpga_core.py
Executable file
520
example/AU250/fpga_axi/tb/test_fpga_core.py
Executable file
@ -0,0 +1,520 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
|
||||
Copyright (c) 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 struct
|
||||
|
||||
import pcie
|
||||
import pcie_usp
|
||||
|
||||
module = 'fpga_core'
|
||||
testbench = 'test_%s' % module
|
||||
|
||||
srcs = []
|
||||
|
||||
srcs.append("../rtl/%s.v" % module)
|
||||
srcs.append("../rtl/axi_ram.v")
|
||||
srcs.append("../rtl/axis_register.v")
|
||||
srcs.append("../lib/pcie/rtl/axis_arb_mux.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_tag_manager.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_cfg.v")
|
||||
srcs.append("../lib/pcie/rtl/pcie_us_msi.v")
|
||||
srcs.append("../lib/pcie/rtl/arbiter.v")
|
||||
srcs.append("../lib/pcie/rtl/priority_encoder.v")
|
||||
srcs.append("../lib/pcie/rtl/pulse_merge.v")
|
||||
srcs.append("%s.v" % testbench)
|
||||
|
||||
src = ' '.join(srcs)
|
||||
|
||||
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
|
||||
|
||||
def bench():
|
||||
|
||||
# Parameters
|
||||
AXIS_PCIE_DATA_WIDTH = 512
|
||||
AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32)
|
||||
AXIS_PCIE_RC_USER_WIDTH = 161
|
||||
AXIS_PCIE_RQ_USER_WIDTH = 137
|
||||
AXIS_PCIE_CQ_USER_WIDTH = 183
|
||||
AXIS_PCIE_CC_USER_WIDTH = 81
|
||||
|
||||
# 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)[4:])
|
||||
m_axis_rq_tready = Signal(bool(0))
|
||||
s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
|
||||
s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
|
||||
s_axis_rc_tlast = Signal(bool(0))
|
||||
s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:])
|
||||
s_axis_rc_tvalid = Signal(bool(0))
|
||||
s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
|
||||
s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
|
||||
s_axis_cq_tlast = Signal(bool(0))
|
||||
s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:])
|
||||
s_axis_cq_tvalid = Signal(bool(0))
|
||||
m_axis_cc_tready = Signal(bool(0))
|
||||
cfg_max_payload = Signal(intbv(0)[2:])
|
||||
cfg_max_read_req = Signal(intbv(0)[3:])
|
||||
cfg_mgmt_read_data = Signal(intbv(0)[32:])
|
||||
cfg_mgmt_read_write_done = Signal(bool(0))
|
||||
cfg_interrupt_msi_enable = Signal(intbv(0)[4:])
|
||||
cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:])
|
||||
cfg_interrupt_msi_mask_update = Signal(bool(0))
|
||||
cfg_interrupt_msi_data = Signal(intbv(0)[32:])
|
||||
cfg_interrupt_msi_sent = Signal(bool(0))
|
||||
cfg_interrupt_msi_fail = Signal(bool(0))
|
||||
|
||||
# Outputs
|
||||
led = Signal(intbv(0)[8:])
|
||||
m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
|
||||
m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
|
||||
m_axis_rq_tlast = Signal(bool(0))
|
||||
m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:])
|
||||
m_axis_rq_tvalid = Signal(bool(0))
|
||||
s_axis_rc_tready = Signal(bool(0))
|
||||
s_axis_cq_tready = Signal(bool(0))
|
||||
m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
|
||||
m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
|
||||
m_axis_cc_tlast = Signal(bool(0))
|
||||
m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:])
|
||||
m_axis_cc_tvalid = Signal(bool(0))
|
||||
status_error_cor = Signal(bool(0))
|
||||
status_error_uncor = Signal(bool(0))
|
||||
cfg_mgmt_addr = Signal(intbv(0)[10:])
|
||||
cfg_mgmt_function_number = Signal(intbv(0)[8:])
|
||||
cfg_mgmt_write = Signal(bool(0))
|
||||
cfg_mgmt_write_data = Signal(intbv(0)[32:])
|
||||
cfg_mgmt_byte_enable = Signal(intbv(0)[4:])
|
||||
cfg_mgmt_read = Signal(bool(0))
|
||||
cfg_interrupt_msi_int = Signal(intbv(0)[32:])
|
||||
cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:])
|
||||
cfg_interrupt_msi_select = Signal(intbv(0)[2:])
|
||||
cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:])
|
||||
cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0))
|
||||
cfg_interrupt_msi_attr = Signal(intbv(0)[3:])
|
||||
cfg_interrupt_msi_tph_present = Signal(bool(0))
|
||||
cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:])
|
||||
cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:])
|
||||
cfg_interrupt_msi_function_number = Signal(intbv(0)[8:])
|
||||
|
||||
# Clock and Reset Interface
|
||||
user_clk=Signal(bool(0))
|
||||
user_reset=Signal(bool(0))
|
||||
sys_clk=Signal(bool(0))
|
||||
sys_reset=Signal(bool(0))
|
||||
|
||||
# PCIe devices
|
||||
rc = pcie.RootComplex()
|
||||
|
||||
mem_base, mem_data = rc.alloc_region(16*1024*1024)
|
||||
|
||||
dev = pcie_usp.UltrascalePlusPCIe()
|
||||
|
||||
dev.pcie_generation = 3
|
||||
dev.pcie_link_width = 16
|
||||
dev.user_clock_frequency = 256e6
|
||||
|
||||
dev.functions[0].msi_multiple_message_capable = 5
|
||||
|
||||
dev.functions[0].configure_bar(0, 4*1024*1024)
|
||||
dev.functions[0].configure_bar(1, 4*1024*1024)
|
||||
|
||||
rc.make_port().connect(dev)
|
||||
|
||||
pcie_logic = dev.create_logic(
|
||||
# Completer reQuest Interface
|
||||
m_axis_cq_tdata=s_axis_cq_tdata,
|
||||
m_axis_cq_tuser=s_axis_cq_tuser,
|
||||
m_axis_cq_tlast=s_axis_cq_tlast,
|
||||
m_axis_cq_tkeep=s_axis_cq_tkeep,
|
||||
m_axis_cq_tvalid=s_axis_cq_tvalid,
|
||||
m_axis_cq_tready=s_axis_cq_tready,
|
||||
#pcie_cq_np_req=pcie_cq_np_req,
|
||||
pcie_cq_np_req=Signal(intbv(1)[2:]),
|
||||
#pcie_cq_np_req_count=pcie_cq_np_req_count,
|
||||
|
||||
# Completer Completion Interface
|
||||
s_axis_cc_tdata=m_axis_cc_tdata,
|
||||
s_axis_cc_tuser=m_axis_cc_tuser,
|
||||
s_axis_cc_tlast=m_axis_cc_tlast,
|
||||
s_axis_cc_tkeep=m_axis_cc_tkeep,
|
||||
s_axis_cc_tvalid=m_axis_cc_tvalid,
|
||||
s_axis_cc_tready=m_axis_cc_tready,
|
||||
|
||||
# Requester reQuest Interface
|
||||
s_axis_rq_tdata=m_axis_rq_tdata,
|
||||
s_axis_rq_tuser=m_axis_rq_tuser,
|
||||
s_axis_rq_tlast=m_axis_rq_tlast,
|
||||
s_axis_rq_tkeep=m_axis_rq_tkeep,
|
||||
s_axis_rq_tvalid=m_axis_rq_tvalid,
|
||||
s_axis_rq_tready=m_axis_rq_tready,
|
||||
#pcie_rq_seq_num0=pcie_rq_seq_num0,
|
||||
#pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0,
|
||||
#pcie_rq_seq_num1=pcie_rq_seq_num1,
|
||||
#pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1,
|
||||
#pcie_rq_tag0=pcie_rq_tag0,
|
||||
#pcie_rq_tag1=pcie_rq_tag1,
|
||||
#pcie_rq_tag_av=pcie_rq_tag_av,
|
||||
#pcie_rq_tag_vld0=pcie_rq_tag_vld0,
|
||||
#pcie_rq_tag_vld1=pcie_rq_tag_vld1,
|
||||
|
||||
# Requester Completion Interface
|
||||
m_axis_rc_tdata=s_axis_rc_tdata,
|
||||
m_axis_rc_tuser=s_axis_rc_tuser,
|
||||
m_axis_rc_tlast=s_axis_rc_tlast,
|
||||
m_axis_rc_tkeep=s_axis_rc_tkeep,
|
||||
m_axis_rc_tvalid=s_axis_rc_tvalid,
|
||||
m_axis_rc_tready=s_axis_rc_tready,
|
||||
|
||||
# Transmit Flow Control Interface
|
||||
#pcie_tfc_nph_av=pcie_tfc_nph_av,
|
||||
#pcie_tfc_npd_av=pcie_tfc_npd_av,
|
||||
|
||||
# Configuration Management Interface
|
||||
cfg_mgmt_addr=cfg_mgmt_addr,
|
||||
cfg_mgmt_function_number=cfg_mgmt_function_number,
|
||||
cfg_mgmt_write=cfg_mgmt_write,
|
||||
cfg_mgmt_write_data=cfg_mgmt_write_data,
|
||||
cfg_mgmt_byte_enable=cfg_mgmt_byte_enable,
|
||||
cfg_mgmt_read=cfg_mgmt_read,
|
||||
cfg_mgmt_read_data=cfg_mgmt_read_data,
|
||||
cfg_mgmt_read_write_done=cfg_mgmt_read_write_done,
|
||||
#cfg_mgmt_debug_access=cfg_mgmt_debug_access,
|
||||
|
||||
# Configuration Status Interface
|
||||
#cfg_phy_link_down=cfg_phy_link_down,
|
||||
#cfg_phy_link_status=cfg_phy_link_status,
|
||||
#cfg_negotiated_width=cfg_negotiated_width,
|
||||
#cfg_current_speed=cfg_current_speed,
|
||||
cfg_max_payload=cfg_max_payload,
|
||||
cfg_max_read_req=cfg_max_read_req,
|
||||
#cfg_function_status=cfg_function_status,
|
||||
#cfg_vf_status=cfg_vf_status,
|
||||
#cfg_function_power_state=cfg_function_power_state,
|
||||
#cfg_vf_power_state=cfg_vf_power_state,
|
||||
#cfg_link_power_state=cfg_link_power_state,
|
||||
#cfg_err_cor_out=cfg_err_cor_out,
|
||||
#cfg_err_nonfatal_out=cfg_err_nonfatal_out,
|
||||
#cfg_err_fatal_out=cfg_err_fatal_out,
|
||||
#cfg_local_err_out=cfg_local_err_out,
|
||||
#cfg_local_err_valid=cfg_local_err_valid,
|
||||
#cfg_rx_pm_state=cfg_rx_pm_state,
|
||||
#cfg_tx_pm_state=cfg_tx_pm_state,
|
||||
#cfg_ltssm_state=cfg_ltssm_state,
|
||||
#cfg_rcb_status=cfg_rcb_status,
|
||||
#cfg_obff_enable=cfg_obff_enable,
|
||||
#cfg_pl_status_change=cfg_pl_status_change,
|
||||
#cfg_tph_requester_enable=cfg_tph_requester_enable,
|
||||
#cfg_tph_st_mode=cfg_tph_st_mode,
|
||||
#cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable,
|
||||
#cfg_vf_tph_st_mode=cfg_vf_tph_st_mode,
|
||||
|
||||
# Configuration Received Message Interface
|
||||
#cfg_msg_received=cfg_msg_received,
|
||||
#cfg_msg_received_data=cfg_msg_received_data,
|
||||
#cfg_msg_received_type=cfg_msg_received_type,
|
||||
|
||||
# Configuration Transmit Message Interface
|
||||
#cfg_msg_transmit=cfg_msg_transmit,
|
||||
#cfg_msg_transmit_type=cfg_msg_transmit_type,
|
||||
#cfg_msg_transmit_data=cfg_msg_transmit_data,
|
||||
#cfg_msg_transmit_done=cfg_msg_transmit_done,
|
||||
|
||||
# Configuration Flow Control Interface
|
||||
#cfg_fc_ph=cfg_fc_ph,
|
||||
#cfg_fc_pd=cfg_fc_pd,
|
||||
#cfg_fc_nph=cfg_fc_nph,
|
||||
#cfg_fc_npd=cfg_fc_npd,
|
||||
#cfg_fc_cplh=cfg_fc_cplh,
|
||||
#cfg_fc_cpld=cfg_fc_cpld,
|
||||
#cfg_fc_sel=cfg_fc_sel,
|
||||
|
||||
# Configuration Control Interface
|
||||
#cfg_hot_reset_in=cfg_hot_reset_in,
|
||||
#cfg_hot_reset_out=cfg_hot_reset_out,
|
||||
#cfg_config_space_enable=cfg_config_space_enable,
|
||||
#cfg_dsn=cfg_dsn,
|
||||
#cfg_ds_port_number=cfg_ds_port_number,
|
||||
#cfg_ds_bus_number=cfg_ds_bus_number,
|
||||
#cfg_ds_device_number=cfg_ds_device_number,
|
||||
#cfg_ds_function_number=cfg_ds_function_number,
|
||||
#cfg_power_state_change_ack=cfg_power_state_change_ack,
|
||||
#cfg_power_state_change_interrupt=cfg_power_state_change_interrupt,
|
||||
cfg_err_cor_in=status_error_cor,
|
||||
cfg_err_uncor_in=status_error_uncor,
|
||||
#cfg_flr_done=cfg_flr_done,
|
||||
#cfg_vf_flr_done=cfg_vf_flr_done,
|
||||
#cfg_flr_in_process=cfg_flr_in_process,
|
||||
#cfg_vf_flr_in_process=cfg_vf_flr_in_process,
|
||||
#cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready,
|
||||
#cfg_link_training_enable=cfg_link_training_enable,
|
||||
|
||||
# Configuration Interrupt Controller Interface
|
||||
#cfg_interrupt_int=cfg_interrupt_int,
|
||||
#cfg_interrupt_sent=cfg_interrupt_sent,
|
||||
#cfg_interrupt_pending=cfg_interrupt_pending,
|
||||
cfg_interrupt_msi_enable=cfg_interrupt_msi_enable,
|
||||
cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable,
|
||||
cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update,
|
||||
cfg_interrupt_msi_data=cfg_interrupt_msi_data,
|
||||
cfg_interrupt_msi_select=cfg_interrupt_msi_select,
|
||||
cfg_interrupt_msi_int=cfg_interrupt_msi_int,
|
||||
cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status,
|
||||
cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable,
|
||||
cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num,
|
||||
cfg_interrupt_msi_sent=cfg_interrupt_msi_sent,
|
||||
cfg_interrupt_msi_fail=cfg_interrupt_msi_fail,
|
||||
#cfg_interrupt_msix_enable=cfg_interrupt_msix_enable,
|
||||
#cfg_interrupt_msix_mask=cfg_interrupt_msix_mask,
|
||||
#cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable,
|
||||
#cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask,
|
||||
#cfg_interrupt_msix_address=cfg_interrupt_msix_address,
|
||||
#cfg_interrupt_msix_data=cfg_interrupt_msix_data,
|
||||
#cfg_interrupt_msix_int=cfg_interrupt_msix_int,
|
||||
#cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending,
|
||||
#cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status,
|
||||
cfg_interrupt_msi_attr=cfg_interrupt_msi_attr,
|
||||
cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present,
|
||||
cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type,
|
||||
cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag,
|
||||
cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number,
|
||||
|
||||
# Configuration Extend Interface
|
||||
#cfg_ext_read_received=cfg_ext_read_received,
|
||||
#cfg_ext_write_received=cfg_ext_write_received,
|
||||
#cfg_ext_register_number=cfg_ext_register_number,
|
||||
#cfg_ext_function_number=cfg_ext_function_number,
|
||||
#cfg_ext_write_data=cfg_ext_write_data,
|
||||
#cfg_ext_write_byte_enable=cfg_ext_write_byte_enable,
|
||||
#cfg_ext_read_data=cfg_ext_read_data,
|
||||
#cfg_ext_read_data_valid=cfg_ext_read_data_valid,
|
||||
|
||||
# Clock and Reset Interface
|
||||
user_clk=user_clk,
|
||||
user_reset=user_reset,
|
||||
#user_lnk_up=user_lnk_up,
|
||||
sys_clk=sys_clk,
|
||||
sys_clk_gt=sys_clk,
|
||||
sys_reset=sys_reset,
|
||||
#phy_rdy_out=phy_rdy_out
|
||||
)
|
||||
|
||||
# DUT
|
||||
if os.system(build_cmd):
|
||||
raise Exception("Error running build command")
|
||||
|
||||
dut = Cosimulation(
|
||||
"vvp -m myhdl %s.vvp -lxt2" % testbench,
|
||||
clk=user_clk,
|
||||
rst=user_reset,
|
||||
current_test=current_test,
|
||||
btnu=btnu,
|
||||
btnl=btnl,
|
||||
btnd=btnd,
|
||||
btnr=btnr,
|
||||
btnc=btnc,
|
||||
sw=sw,
|
||||
led=led,
|
||||
m_axis_rq_tdata=m_axis_rq_tdata,
|
||||
m_axis_rq_tkeep=m_axis_rq_tkeep,
|
||||
m_axis_rq_tlast=m_axis_rq_tlast,
|
||||
m_axis_rq_tready=m_axis_rq_tready,
|
||||
m_axis_rq_tuser=m_axis_rq_tuser,
|
||||
m_axis_rq_tvalid=m_axis_rq_tvalid,
|
||||
s_axis_rc_tdata=s_axis_rc_tdata,
|
||||
s_axis_rc_tkeep=s_axis_rc_tkeep,
|
||||
s_axis_rc_tlast=s_axis_rc_tlast,
|
||||
s_axis_rc_tready=s_axis_rc_tready,
|
||||
s_axis_rc_tuser=s_axis_rc_tuser,
|
||||
s_axis_rc_tvalid=s_axis_rc_tvalid,
|
||||
s_axis_cq_tdata=s_axis_cq_tdata,
|
||||
s_axis_cq_tkeep=s_axis_cq_tkeep,
|
||||
s_axis_cq_tlast=s_axis_cq_tlast,
|
||||
s_axis_cq_tready=s_axis_cq_tready,
|
||||
s_axis_cq_tuser=s_axis_cq_tuser,
|
||||
s_axis_cq_tvalid=s_axis_cq_tvalid,
|
||||
m_axis_cc_tdata=m_axis_cc_tdata,
|
||||
m_axis_cc_tkeep=m_axis_cc_tkeep,
|
||||
m_axis_cc_tlast=m_axis_cc_tlast,
|
||||
m_axis_cc_tready=m_axis_cc_tready,
|
||||
m_axis_cc_tuser=m_axis_cc_tuser,
|
||||
m_axis_cc_tvalid=m_axis_cc_tvalid,
|
||||
cfg_max_payload=cfg_max_payload,
|
||||
cfg_max_read_req=cfg_max_read_req,
|
||||
cfg_mgmt_addr=cfg_mgmt_addr,
|
||||
cfg_mgmt_function_number=cfg_mgmt_function_number,
|
||||
cfg_mgmt_write=cfg_mgmt_write,
|
||||
cfg_mgmt_write_data=cfg_mgmt_write_data,
|
||||
cfg_mgmt_byte_enable=cfg_mgmt_byte_enable,
|
||||
cfg_mgmt_read=cfg_mgmt_read,
|
||||
cfg_mgmt_read_data=cfg_mgmt_read_data,
|
||||
cfg_mgmt_read_write_done=cfg_mgmt_read_write_done,
|
||||
cfg_interrupt_msi_enable=cfg_interrupt_msi_enable,
|
||||
cfg_interrupt_msi_int=cfg_interrupt_msi_int,
|
||||
cfg_interrupt_msi_sent=cfg_interrupt_msi_sent,
|
||||
cfg_interrupt_msi_fail=cfg_interrupt_msi_fail,
|
||||
cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable,
|
||||
cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status,
|
||||
cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update,
|
||||
cfg_interrupt_msi_select=cfg_interrupt_msi_select,
|
||||
cfg_interrupt_msi_data=cfg_interrupt_msi_data,
|
||||
cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num,
|
||||
cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable,
|
||||
cfg_interrupt_msi_attr=cfg_interrupt_msi_attr,
|
||||
cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present,
|
||||
cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type,
|
||||
cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag,
|
||||
cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number,
|
||||
status_error_cor=status_error_cor,
|
||||
status_error_uncor=status_error_uncor
|
||||
)
|
||||
|
||||
@always(delay(5))
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
@always_comb
|
||||
def clk_logic():
|
||||
sys_clk.next = clk
|
||||
sys_reset.next = not rst
|
||||
|
||||
@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
|
||||
|
||||
current_tag = 1
|
||||
|
||||
yield clk.posedge
|
||||
print("test 1: enumeration")
|
||||
current_test.next = 1
|
||||
|
||||
yield rc.enumerate(enable_bus_mastering=True, configure_msi=True)
|
||||
|
||||
dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc
|
||||
dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 2: memory write to bar 1")
|
||||
current_test.next = 2
|
||||
|
||||
yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44')
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 3: memory read from bar 1")
|
||||
current_test.next = 3
|
||||
|
||||
val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000)
|
||||
print(val)
|
||||
assert val == b'\x11\x22\x33\x44'
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 4: test DMA")
|
||||
current_test.next = 4
|
||||
|
||||
# write packet data
|
||||
mem_data[0:1024] = bytearray([x%256 for x in range(1024)])
|
||||
|
||||
# enable DMA
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('<L', 1))
|
||||
|
||||
# write pcie read descriptor
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100100, struct.pack('<L', (mem_base+0x0000) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100104, struct.pack('<L', (mem_base+0x0000 >> 32) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('<L', (0x100) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x10010C, struct.pack('<L', (0x100 >> 32) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('<L', 0x400))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100114, struct.pack('<L', 0xAA))
|
||||
|
||||
yield delay(2000)
|
||||
|
||||
# read status
|
||||
val = yield from rc.mem_read(dev_pf0_bar0+0x100118, 4)
|
||||
print(val)
|
||||
|
||||
# write pcie write descriptor
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100200, struct.pack('<L', (mem_base+0x1000) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100204, struct.pack('<L', (mem_base+0x1000 >> 32) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('<L', (0x100) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x10020C, struct.pack('<L', (0x100 >> 32) & 0xffffffff))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack('<L', 0x400))
|
||||
yield rc.mem_write(dev_pf0_bar0+0x100214, struct.pack('<L', 0x55))
|
||||
|
||||
yield delay(2000)
|
||||
|
||||
# read status
|
||||
val = yield from rc.mem_read(dev_pf0_bar0+0x100218, 4)
|
||||
print(val)
|
||||
|
||||
data = mem_data[0x1000:(0x1000)+64]
|
||||
for i in range(0, len(data), 16):
|
||||
print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i+16]))))
|
||||
|
||||
assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024]
|
||||
|
||||
yield delay(100)
|
||||
|
||||
raise StopSimulation
|
||||
|
||||
return instances()
|
||||
|
||||
def test_bench():
|
||||
sim = Simulation(bench())
|
||||
sim.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Running test...")
|
||||
test_bench()
|
243
example/AU250/fpga_axi/tb/test_fpga_core.v
Normal file
243
example/AU250/fpga_axi/tb/test_fpga_core.v
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 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 AXIS_PCIE_DATA_WIDTH = 512;
|
||||
parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32);
|
||||
parameter AXIS_PCIE_RC_USER_WIDTH = 161;
|
||||
parameter AXIS_PCIE_RQ_USER_WIDTH = 137;
|
||||
parameter AXIS_PCIE_CQ_USER_WIDTH = 183;
|
||||
parameter AXIS_PCIE_CC_USER_WIDTH = 81;
|
||||
|
||||
// Inputs
|
||||
reg clk = 0;
|
||||
reg rst = 0;
|
||||
reg [7:0] current_test = 0;
|
||||
|
||||
reg [3:0] sw = 0;
|
||||
reg m_axis_rq_tready = 0;
|
||||
reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0;
|
||||
reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0;
|
||||
reg s_axis_rc_tlast = 0;
|
||||
reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0;
|
||||
reg s_axis_rc_tvalid = 0;
|
||||
reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0;
|
||||
reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0;
|
||||
reg s_axis_cq_tlast = 0;
|
||||
reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0;
|
||||
reg s_axis_cq_tvalid = 0;
|
||||
reg m_axis_cc_tready = 0;
|
||||
reg [2:0] cfg_max_payload = 0;
|
||||
reg [2:0] cfg_max_read_req = 0;
|
||||
reg [31:0] cfg_mgmt_read_data = 0;
|
||||
reg cfg_mgmt_read_write_done = 0;
|
||||
reg [3:0] cfg_interrupt_msi_enable = 0;
|
||||
reg [11:0] cfg_interrupt_msi_mmenable = 0;
|
||||
reg cfg_interrupt_msi_mask_update = 0;
|
||||
reg [31:0] cfg_interrupt_msi_data = 0;
|
||||
reg cfg_interrupt_msi_sent = 0;
|
||||
reg cfg_interrupt_msi_fail = 0;
|
||||
|
||||
// Outputs
|
||||
wire [2:0] led;
|
||||
wire [1:0] user_led_g;
|
||||
wire user_led_r;
|
||||
wire [1:0] front_led;
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep;
|
||||
wire m_axis_rq_tlast;
|
||||
wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser;
|
||||
wire m_axis_rq_tvalid;
|
||||
wire s_axis_rc_tready;
|
||||
wire s_axis_cq_tready;
|
||||
wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata;
|
||||
wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep;
|
||||
wire m_axis_cc_tlast;
|
||||
wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser;
|
||||
wire m_axis_cc_tvalid;
|
||||
wire [9:0] cfg_mgmt_addr;
|
||||
wire [7:0] cfg_mgmt_function_number;
|
||||
wire cfg_mgmt_write;
|
||||
wire [31:0] cfg_mgmt_write_data;
|
||||
wire [3:0] cfg_mgmt_byte_enable;
|
||||
wire cfg_mgmt_read;
|
||||
wire [3:0] cfg_interrupt_msi_select;
|
||||
wire [31:0] cfg_interrupt_msi_int;
|
||||
wire [31:0] cfg_interrupt_msi_pending_status;
|
||||
wire cfg_interrupt_msi_pending_status_data_enable;
|
||||
wire [3:0] cfg_interrupt_msi_pending_status_function_num;
|
||||
wire [2:0] cfg_interrupt_msi_attr;
|
||||
wire cfg_interrupt_msi_tph_present;
|
||||
wire [1:0] cfg_interrupt_msi_tph_type;
|
||||
wire [8:0] cfg_interrupt_msi_tph_st_tag;
|
||||
wire [3:0] cfg_interrupt_msi_function_number;
|
||||
wire status_error_cor;
|
||||
wire status_error_uncor;
|
||||
|
||||
initial begin
|
||||
// myhdl integration
|
||||
$from_myhdl(
|
||||
clk,
|
||||
rst,
|
||||
current_test,
|
||||
sw,
|
||||
m_axis_rq_tready,
|
||||
s_axis_rc_tdata,
|
||||
s_axis_rc_tkeep,
|
||||
s_axis_rc_tlast,
|
||||
s_axis_rc_tuser,
|
||||
s_axis_rc_tvalid,
|
||||
s_axis_cq_tdata,
|
||||
s_axis_cq_tkeep,
|
||||
s_axis_cq_tlast,
|
||||
s_axis_cq_tuser,
|
||||
s_axis_cq_tvalid,
|
||||
m_axis_cc_tready,
|
||||
cfg_max_payload,
|
||||
cfg_max_read_req,
|
||||
cfg_mgmt_read_data,
|
||||
cfg_mgmt_read_write_done,
|
||||
cfg_interrupt_msi_enable,
|
||||
cfg_interrupt_msi_mmenable,
|
||||
cfg_interrupt_msi_mask_update,
|
||||
cfg_interrupt_msi_data,
|
||||
cfg_interrupt_msi_sent,
|
||||
cfg_interrupt_msi_fail
|
||||
);
|
||||
$to_myhdl(
|
||||
led,
|
||||
m_axis_rq_tdata,
|
||||
m_axis_rq_tkeep,
|
||||
m_axis_rq_tlast,
|
||||
m_axis_rq_tuser,
|
||||
m_axis_rq_tvalid,
|
||||
s_axis_rc_tready,
|
||||
s_axis_cq_tready,
|
||||
m_axis_cc_tdata,
|
||||
m_axis_cc_tkeep,
|
||||
m_axis_cc_tlast,
|
||||
m_axis_cc_tuser,
|
||||
m_axis_cc_tvalid,
|
||||
cfg_mgmt_addr,
|
||||
cfg_mgmt_function_number,
|
||||
cfg_mgmt_write,
|
||||
cfg_mgmt_write_data,
|
||||
cfg_mgmt_byte_enable,
|
||||
cfg_mgmt_read,
|
||||
cfg_interrupt_msi_select,
|
||||
cfg_interrupt_msi_int,
|
||||
cfg_interrupt_msi_pending_status,
|
||||
cfg_interrupt_msi_pending_status_data_enable,
|
||||
cfg_interrupt_msi_pending_status_function_num,
|
||||
cfg_interrupt_msi_attr,
|
||||
cfg_interrupt_msi_tph_present,
|
||||
cfg_interrupt_msi_tph_type,
|
||||
cfg_interrupt_msi_tph_st_tag,
|
||||
cfg_interrupt_msi_function_number,
|
||||
status_error_cor,
|
||||
status_error_uncor
|
||||
);
|
||||
|
||||
// dump file
|
||||
$dumpfile("test_fpga_core.lxt");
|
||||
$dumpvars(0, test_fpga_core);
|
||||
end
|
||||
|
||||
fpga_core #(
|
||||
.AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH),
|
||||
.AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH),
|
||||
.AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH),
|
||||
.AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH),
|
||||
.AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH),
|
||||
.AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH)
|
||||
)
|
||||
UUT (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.sw(sw),
|
||||
.led(led),
|
||||
.m_axis_rq_tdata(m_axis_rq_tdata),
|
||||
.m_axis_rq_tkeep(m_axis_rq_tkeep),
|
||||
.m_axis_rq_tlast(m_axis_rq_tlast),
|
||||
.m_axis_rq_tready(m_axis_rq_tready),
|
||||
.m_axis_rq_tuser(m_axis_rq_tuser),
|
||||
.m_axis_rq_tvalid(m_axis_rq_tvalid),
|
||||
.s_axis_rc_tdata(s_axis_rc_tdata),
|
||||
.s_axis_rc_tkeep(s_axis_rc_tkeep),
|
||||
.s_axis_rc_tlast(s_axis_rc_tlast),
|
||||
.s_axis_rc_tready(s_axis_rc_tready),
|
||||
.s_axis_rc_tuser(s_axis_rc_tuser),
|
||||
.s_axis_rc_tvalid(s_axis_rc_tvalid),
|
||||
.s_axis_cq_tdata(s_axis_cq_tdata),
|
||||
.s_axis_cq_tkeep(s_axis_cq_tkeep),
|
||||
.s_axis_cq_tlast(s_axis_cq_tlast),
|
||||
.s_axis_cq_tready(s_axis_cq_tready),
|
||||
.s_axis_cq_tuser(s_axis_cq_tuser),
|
||||
.s_axis_cq_tvalid(s_axis_cq_tvalid),
|
||||
.m_axis_cc_tdata(m_axis_cc_tdata),
|
||||
.m_axis_cc_tkeep(m_axis_cc_tkeep),
|
||||
.m_axis_cc_tlast(m_axis_cc_tlast),
|
||||
.m_axis_cc_tready(m_axis_cc_tready),
|
||||
.m_axis_cc_tuser(m_axis_cc_tuser),
|
||||
.m_axis_cc_tvalid(m_axis_cc_tvalid),
|
||||
.cfg_max_payload(cfg_max_payload),
|
||||
.cfg_max_read_req(cfg_max_read_req),
|
||||
.cfg_mgmt_addr(cfg_mgmt_addr),
|
||||
.cfg_mgmt_function_number(cfg_mgmt_function_number),
|
||||
.cfg_mgmt_write(cfg_mgmt_write),
|
||||
.cfg_mgmt_write_data(cfg_mgmt_write_data),
|
||||
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
|
||||
.cfg_mgmt_read(cfg_mgmt_read),
|
||||
.cfg_mgmt_read_data(cfg_mgmt_read_data),
|
||||
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
|
||||
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
|
||||
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
|
||||
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
|
||||
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
|
||||
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
|
||||
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
|
||||
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
|
||||
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
|
||||
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
|
||||
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
|
||||
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
|
||||
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
|
||||
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
|
||||
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
|
||||
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
|
||||
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
|
||||
.status_error_cor(status_error_cor),
|
||||
.status_error_uncor(status_error_uncor)
|
||||
);
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user