mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Add example design for Alveo U50
This commit is contained in:
parent
068ea6edc2
commit
0cbe4897da
19
example/AU50/fpga/README.md
Normal file
19
example/AU50/fpga/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Verilog PCIe Alveo U50 Example Design
|
||||
|
||||
## Introduction
|
||||
|
||||
This example design targets the Xilinx Alveo U50 FPGA board.
|
||||
|
||||
The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design.
|
||||
|
||||
* FPGA: xcu50-fsvh2104-2-e
|
||||
|
||||
## How to build
|
||||
|
||||
Run `make` to build. Ensure that the Xilinx Vivado 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 U50 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.
|
126
example/AU50/fpga/common/vivado.mk
Normal file
126
example/AU50/fpga/common/vivado.mk
Normal file
@ -0,0 +1,126 @@
|
||||
###################################################################
|
||||
#
|
||||
# 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: fpga vivado tmpclean clean distclean
|
||||
|
||||
# prevent make from deleting intermediate files and reports
|
||||
.PRECIOUS: %.xpr %.bit %.mcs %.prm
|
||||
.SECONDARY:
|
||||
|
||||
CONFIG ?= config.mk
|
||||
-include ../$(CONFIG)
|
||||
|
||||
SYN_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(SYN_FILES))) $(filter /% ./%,$(SYN_FILES))
|
||||
INC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(INC_FILES))) $(filter /% ./%,$(INC_FILES))
|
||||
XCI_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XCI_FILES))) $(filter /% ./%,$(XCI_FILES))
|
||||
IP_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(IP_TCL_FILES))) $(filter /% ./%,$(IP_TCL_FILES))
|
||||
CONFIG_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(CONFIG_TCL_FILES))) $(filter /% ./%,$(CONFIG_TCL_FILES))
|
||||
|
||||
ifdef XDC_FILES
|
||||
XDC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XDC_FILES))) $(filter /% ./%,$(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 *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
|
||||
-rm -rf create_project.tcl update_config.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
|
||||
create_project.tcl: 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) $(FPGA_TOP)" > $@
|
||||
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
|
||||
echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@
|
||||
for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done
|
||||
for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done
|
||||
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
|
||||
|
||||
update_config.tcl: $(CONFIG_TCL_FILES_REL)
|
||||
echo "open_project -quiet $(FPGA_TOP).xpr" > $@
|
||||
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
|
||||
|
||||
$(FPGA_TOP).xpr: create_project.tcl update_config.tcl
|
||||
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
|
||||
|
||||
# synthesis run
|
||||
%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) $(CONFIG_TCL_FILES_REL)
|
||||
echo "open_project $*.xpr" > run_synth.tcl
|
||||
echo "reset_run synth_1" >> run_synth.tcl
|
||||
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
|
||||
echo "wait_on_run synth_1" >> 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 -jobs 4 impl_1" >> run_impl.tcl
|
||||
echo "wait_on_run impl_1" >> 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
|
||||
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/AU50/fpga/driver
Symbolic link
1
example/AU50/fpga/driver
Symbolic link
@ -0,0 +1 @@
|
||||
../../common/driver/example/
|
203
example/AU50/fpga/fpga.xdc
Normal file
203
example/AU50/fpga/fpga.xdc
Normal file
@ -0,0 +1,203 @@
|
||||
# XDC constraints for the Xilinx Alveo U50 board
|
||||
# part: xcu50-fsvh2104-2-e
|
||||
|
||||
# General configuration
|
||||
set_property CFGBVS GND [current_design]
|
||||
set_property CONFIG_VOLTAGE 1.8 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
|
||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
||||
set_property CONFIG_MODE SPIx4 [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||
set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design]
|
||||
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
|
||||
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
|
||||
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
|
||||
|
||||
set_operating_conditions -design_power_budget 63
|
||||
|
||||
# System clocks
|
||||
# 100 MHz
|
||||
#set_property -dict {LOC G17 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
|
||||
#set_property -dict {LOC G16 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
|
||||
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
|
||||
|
||||
# 100 MHz
|
||||
#set_property -dict {LOC BB18 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
|
||||
#set_property -dict {LOC BC18 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
|
||||
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
|
||||
|
||||
# LEDs
|
||||
set_property -dict {LOC E18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_act]
|
||||
set_property -dict {LOC E16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_g]
|
||||
set_property -dict {LOC F17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_y]
|
||||
|
||||
set_false_path -to [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
|
||||
set_output_delay 0 [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
|
||||
|
||||
# UART
|
||||
#set_property -dict {LOC BE26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart0_txd]
|
||||
#set_property -dict {LOC BF26 IOSTANDARD LVCMOS18} [get_ports usb_uart0_rxd]
|
||||
#set_property -dict {LOC A17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart1_txd]
|
||||
#set_property -dict {LOC B15 IOSTANDARD LVCMOS18} [get_ports usb_uart1_rxd]
|
||||
#set_property -dict {LOC A19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart2_txd]
|
||||
#set_property -dict {LOC A18 IOSTANDARD LVCMOS18} [get_ports usb_uart2_rxd]
|
||||
|
||||
#set_false_path -to [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
|
||||
#set_output_delay 0 [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
|
||||
#set_false_path -from [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
|
||||
#set_input_delay 0 [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
|
||||
|
||||
# BMC
|
||||
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
|
||||
#set_property -dict {LOC C17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
|
||||
#set_property -dict {LOC BB25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
|
||||
#set_property -dict {LOC BB26 IOSTANDARD LVCMOS18} [get_ports {msp_uart_rxd}]
|
||||
|
||||
#set_false_path -to [get_ports {msp_uart_txd}]
|
||||
#set_output_delay 0 [get_ports {msp_uart_txd}]
|
||||
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
|
||||
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
|
||||
|
||||
# HBM overtemp
|
||||
set_property -dict {LOC J18 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
|
||||
|
||||
set_false_path -to [get_ports {hbm_cattrip}]
|
||||
set_output_delay 0 [get_ports {hbm_cattrip}]
|
||||
|
||||
# SI5394 (SI5394B-A10605-GM)
|
||||
# I2C address 0x68
|
||||
# IN0: 161.1328125 MHz from qsfp_recclk
|
||||
# OUT0: 161.1328125 MHz to qsfp_mgt_refclk_0
|
||||
# OUT2: 322.265625 MHz to qsfp_mgt_refclk_1
|
||||
# OUT3: 100 MHz to clk_100mhz_0, clk_100mhz_1, pcie_refclk_2, pcie_refclk_3
|
||||
#set_property -dict {LOC F20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports si5394_rst_b]
|
||||
#set_property -dict {LOC H18 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_int_b]
|
||||
#set_property -dict {LOC G19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_lol_b]
|
||||
#set_property -dict {LOC H19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports si5394_los_b]
|
||||
#set_property -dict {LOC J16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_i2c_sda]
|
||||
#set_property -dict {LOC L19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_i2c_scl]
|
||||
|
||||
#set_false_path -to [get_ports {si5394_rst_b}]
|
||||
#set_output_delay 0 [get_ports {si5394_rst_b}]
|
||||
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
|
||||
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
|
||||
|
||||
#set_false_path -to [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||
#set_output_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||
#set_false_path -from [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||
#set_input_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
|
||||
|
||||
# QSFP28 Interfaces
|
||||
#set_property -dict {LOC J45 } [get_ports qsfp_rx1_p] ;# MGTYRXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC J46 } [get_ports qsfp_rx1_n] ;# MGTYRXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC D42 } [get_ports qsfp_tx1_p] ;# MGTYTXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC D43 } [get_ports qsfp_tx1_n] ;# MGTYTXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC G45 } [get_ports qsfp_rx2_p] ;# MGTYRXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC G46 } [get_ports qsfp_rx2_n] ;# MGTYRXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC C40 } [get_ports qsfp_tx2_p] ;# MGTYTXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC C41 } [get_ports qsfp_tx2_n] ;# MGTYTXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC F43 } [get_ports qsfp_rx3_p] ;# MGTYRXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC F44 } [get_ports qsfp_rx3_n] ;# MGTYRXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC B42 } [get_ports qsfp_tx3_p] ;# MGTYTXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC B43 } [get_ports qsfp_tx3_n] ;# MGTYTXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC E45 } [get_ports qsfp_rx4_p] ;# MGTYRXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC E46 } [get_ports qsfp_rx4_n] ;# MGTYRXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC A40 } [get_ports qsfp_tx4_p] ;# MGTYTXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC A41 } [get_ports qsfp_tx4_n] ;# MGTYTXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
|
||||
#set_property -dict {LOC N36 } [get_ports qsfp_mgt_refclk_0_p] ;# MGTREFCLK0P_131 from SI5394 OUT0
|
||||
#set_property -dict {LOC N37 } [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_131 from SI5394 OUT0
|
||||
#set_property -dict {LOC M38 } [get_ports qsfp_mgt_refclk_1_p] ;# MGTREFCLK1P_131 from SI5394 OUT2
|
||||
#set_property -dict {LOC M39 } [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_131 from SI5394 OUT2
|
||||
#set_property -dict {LOC F19 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to SI5394 IN0
|
||||
#set_property -dict {LOC F18 IOSTANDARD LVDS} [get_ports qsfp_recclk_n] ;# to SI5394 IN0
|
||||
|
||||
# 161.1328125 MHz MGT reference clock (SI5394 OUT0)
|
||||
#create_clock -period 6.206 -name qsfp_mgt_refclk_0 [get_ports qsfp_mgt_refclk_0_p]
|
||||
|
||||
# 322.265625 MHz MGT reference clock (SI5394 OUT2)
|
||||
#create_clock -period 3.103 -name qsfp_mgt_refclk_1 [get_ports qsfp_mgt_refclk_1_p]
|
||||
|
||||
# PCIe Interface
|
||||
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC Y5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC Y4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AA7 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AA6 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AC7 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AC6 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
|
||||
set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AE7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AE6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
|
||||
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AG7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AG6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AJ7 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AJ6 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AL7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AL6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AM9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
|
||||
set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AN7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AN6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AP9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AP8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BD4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BD3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AR7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AR6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BE6 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC BE5 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AT9 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||
set_property -dict {LOC AT8 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
|
||||
#set_property -dict {LOC AB9 } [get_ports pcie_refclk_0_p] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
|
||||
#set_property -dict {LOC AB8 } [get_ports pcie_refclk_0_n] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
|
||||
#set_property -dict {LOC AA11} [get_ports pcie_refclk_2_p] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
|
||||
#set_property -dict {LOC AA10} [get_ports pcie_refclk_2_n] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
|
||||
set_property -dict {LOC AF9 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
|
||||
set_property -dict {LOC AF8 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
|
||||
#set_property -dict {LOC AE11} [get_ports pcie_refclk_3_p] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
|
||||
#set_property -dict {LOC AE10} [get_ports pcie_refclk_3_n] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
|
||||
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
|
||||
|
||||
# 100 MHz MGT reference clock
|
||||
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports pcie_refclk_0_p]
|
||||
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
|
||||
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
|
||||
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports pcie_refclk_3_p]
|
||||
|
||||
set_false_path -from [get_ports {pcie_reset_n}]
|
||||
set_input_delay 0 [get_ports {pcie_reset_n}]
|
93
example/AU50/fpga/fpga/Makefile
Normal file
93
example/AU50/fpga/fpga/Makefile
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
# FPGA settings
|
||||
FPGA_PART = xcu50-fsvh2104-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/sync_reset.v
|
||||
SYN_FILES += rtl/sync_signal.v
|
||||
SYN_FILES += rtl/common/example_core_pcie_us.v
|
||||
SYN_FILES += rtl/common/example_core_pcie.v
|
||||
SYN_FILES += rtl/common/example_core.v
|
||||
SYN_FILES += rtl/common/axi_ram.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_if.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_us_msi.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_axil_master.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_axi_master.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v
|
||||
SYN_FILES += lib/pcie/rtl/dma_if_pcie.v
|
||||
SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v
|
||||
SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v
|
||||
SYN_FILES += lib/pcie/rtl/dma_psdpram.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/pcie4c_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
|
||||
|
||||
%.mcs %.prm: %.bit
|
||||
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||
echo "exit" >> generate_mcs.tcl
|
||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||
mkdir -p rev
|
||||
COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||
do COUNT=$$((COUNT+1)); done; \
|
||||
COUNT=$$((COUNT-1)); \
|
||||
for x in .mcs .prm; \
|
||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||
|
||||
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
|
||||
echo "open_hw" > flash.tcl
|
||||
echo "connect_hw_server" >> flash.tcl
|
||||
echo "open_hw_target" >> flash.tcl
|
||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
|
||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
|
||||
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
|
||||
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
|
||||
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
|
||||
echo "program_hw_devices [current_hw_device]" >> flash.tcl
|
||||
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
|
||||
echo "boot_hw_device [current_hw_device]" >> flash.tcl
|
||||
echo "exit" >> flash.tcl
|
||||
vivado -nojournal -nolog -mode batch -source flash.tcl
|
||||
|
28
example/AU50/fpga/ip/pcie4c_uscale_plus_0.tcl
Normal file
28
example/AU50/fpga/ip/pcie4c_uscale_plus_0.tcl
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
create_ip -name pcie4c_uscale_plus -vendor xilinx.com -library ip -module_name pcie4c_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 {058000} \
|
||||
CONFIG.PF0_DEVICE_ID {0001} \
|
||||
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
|
||||
CONFIG.PF0_SUBSYSTEM_ID {9032} \
|
||||
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \
|
||||
CONFIG.pf0_bar0_64bit {true} \
|
||||
CONFIG.pf0_bar0_prefetchable {true} \
|
||||
CONFIG.pf0_bar0_scale {Megabytes} \
|
||||
CONFIG.pf0_bar0_size {16} \
|
||||
CONFIG.pf0_bar2_64bit {true} \
|
||||
CONFIG.pf0_bar2_prefetchable {true} \
|
||||
CONFIG.pf0_bar2_enabled {true} \
|
||||
CONFIG.pf0_bar2_type {Memory} \
|
||||
CONFIG.pf0_bar2_scale {Megabytes} \
|
||||
CONFIG.pf0_bar2_size {16} \
|
||||
CONFIG.vendor_id {1234} \
|
||||
CONFIG.en_msi_per_vec_masking {true} \
|
||||
] [get_ips pcie4c_uscale_plus_0]
|
1
example/AU50/fpga/lib/pcie
Symbolic link
1
example/AU50/fpga/lib/pcie
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../
|
1
example/AU50/fpga/rtl/common
Symbolic link
1
example/AU50/fpga/rtl/common
Symbolic link
@ -0,0 +1 @@
|
||||
../../../common/rtl/
|
454
example/AU50/fpga/rtl/fpga.v
Normal file
454
example/AU50/fpga/rtl/fpga.v
Normal file
@ -0,0 +1,454 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`resetall
|
||||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* FPGA top-level module
|
||||
*/
|
||||
module fpga (
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
output wire qsfp_led_act,
|
||||
output wire qsfp_led_stat_g,
|
||||
output wire qsfp_led_stat_y,
|
||||
output wire hbm_cattrip,
|
||||
|
||||
/*
|
||||
* 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_1_p,
|
||||
input wire pcie_refclk_1_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 = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161;
|
||||
parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 60 : 137;
|
||||
parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183;
|
||||
parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81;
|
||||
|
||||
parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6;
|
||||
parameter RQ_SEQ_NUM_ENABLE = 1;
|
||||
|
||||
parameter PCIE_TAG_COUNT = 64;
|
||||
parameter BAR0_APERTURE = 24;
|
||||
parameter BAR2_APERTURE = 24;
|
||||
|
||||
// Clock and reset
|
||||
wire pcie_user_clk;
|
||||
wire pcie_user_reset;
|
||||
|
||||
// GPIO
|
||||
assign hbm_cattrip = 1'b0;
|
||||
|
||||
// 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_1_p),
|
||||
.IB (pcie_refclk_1_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;
|
||||
|
||||
wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num0;
|
||||
wire pcie_rq_seq_num_vld0;
|
||||
wire [RQ_SEQ_NUM_WIDTH-1:0] pcie_rq_seq_num1;
|
||||
wire pcie_rq_seq_num_vld1;
|
||||
|
||||
// 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 [7:0] cfg_fc_ph;
|
||||
wire [11:0] cfg_fc_pd;
|
||||
wire [7:0] cfg_fc_nph;
|
||||
wire [11:0] cfg_fc_npd;
|
||||
wire [7:0] cfg_fc_cplh;
|
||||
wire [11:0] cfg_fc_cpld;
|
||||
wire [2:0] cfg_fc_sel;
|
||||
|
||||
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;
|
||||
|
||||
pcie4c_uscale_plus_0
|
||||
pcie4c_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_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_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_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),
|
||||
|
||||
.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),
|
||||
|
||||
.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),
|
||||
.RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH),
|
||||
.RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE),
|
||||
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
|
||||
.BAR0_APERTURE(BAR0_APERTURE),
|
||||
.BAR2_APERTURE(BAR2_APERTURE)
|
||||
)
|
||||
core_inst (
|
||||
/*
|
||||
* Clock: 250 MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
.clk(pcie_user_clk),
|
||||
.rst(pcie_user_reset),
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.qsfp_led_act(qsfp_led_act),
|
||||
.qsfp_led_stat_g(qsfp_led_stat_g),
|
||||
.qsfp_led_stat_y(qsfp_led_stat_y),
|
||||
/*
|
||||
* 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),
|
||||
|
||||
.s_axis_rq_seq_num_0(pcie_rq_seq_num0),
|
||||
.s_axis_rq_seq_num_valid_0(pcie_rq_seq_num_vld0),
|
||||
.s_axis_rq_seq_num_1(pcie_rq_seq_num1),
|
||||
.s_axis_rq_seq_num_valid_1(pcie_rq_seq_num_vld1),
|
||||
|
||||
.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_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),
|
||||
|
||||
.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
|
||||
|
||||
`resetall
|
274
example/AU50/fpga/rtl/fpga_core.v
Normal file
274
example/AU50/fpga/rtl/fpga_core.v
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`resetall
|
||||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* FPGA core logic
|
||||
*/
|
||||
module fpga_core #
|
||||
(
|
||||
parameter AXIS_PCIE_DATA_WIDTH = 512,
|
||||
parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32),
|
||||
parameter AXIS_PCIE_RC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 75 : 161,
|
||||
parameter AXIS_PCIE_RQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 60 : 137,
|
||||
parameter AXIS_PCIE_CQ_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 85 : 183,
|
||||
parameter AXIS_PCIE_CC_USER_WIDTH = AXIS_PCIE_DATA_WIDTH < 512 ? 33 : 81,
|
||||
parameter RQ_SEQ_NUM_WIDTH = AXIS_PCIE_RQ_USER_WIDTH == 60 ? 4 : 6,
|
||||
parameter RQ_SEQ_NUM_ENABLE = 1,
|
||||
parameter PCIE_TAG_COUNT = 64,
|
||||
parameter BAR0_APERTURE = 24,
|
||||
parameter BAR2_APERTURE = 24
|
||||
)
|
||||
(
|
||||
/*
|
||||
* Clock: 250 MHz
|
||||
* Synchronous reset
|
||||
*/
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
output wire qsfp_led_act,
|
||||
output wire qsfp_led_stat_g,
|
||||
output wire qsfp_led_stat_y,
|
||||
|
||||
/*
|
||||
* PCIe
|
||||
*/
|
||||
output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata,
|
||||
output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep,
|
||||
output wire m_axis_rq_tlast,
|
||||
input wire m_axis_rq_tready,
|
||||
output wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser,
|
||||
output wire m_axis_rq_tvalid,
|
||||
|
||||
input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata,
|
||||
input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep,
|
||||
input wire s_axis_rc_tlast,
|
||||
output wire s_axis_rc_tready,
|
||||
input wire [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser,
|
||||
input wire s_axis_rc_tvalid,
|
||||
|
||||
input wire [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata,
|
||||
input wire [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep,
|
||||
input wire s_axis_cq_tlast,
|
||||
output wire s_axis_cq_tready,
|
||||
input wire [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser,
|
||||
input wire s_axis_cq_tvalid,
|
||||
|
||||
output wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata,
|
||||
output wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep,
|
||||
output wire m_axis_cc_tlast,
|
||||
input wire m_axis_cc_tready,
|
||||
output wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser,
|
||||
output wire m_axis_cc_tvalid,
|
||||
|
||||
input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0,
|
||||
input wire s_axis_rq_seq_num_valid_0,
|
||||
input wire [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1,
|
||||
input wire s_axis_rq_seq_num_valid_1,
|
||||
|
||||
input wire [2:0] cfg_max_payload,
|
||||
input wire [2:0] cfg_max_read_req,
|
||||
|
||||
output wire [9:0] cfg_mgmt_addr,
|
||||
output wire [7:0] cfg_mgmt_function_number,
|
||||
output wire cfg_mgmt_write,
|
||||
output wire [31:0] cfg_mgmt_write_data,
|
||||
output wire [3:0] cfg_mgmt_byte_enable,
|
||||
output wire cfg_mgmt_read,
|
||||
input wire [31:0] cfg_mgmt_read_data,
|
||||
input wire cfg_mgmt_read_write_done,
|
||||
|
||||
input wire [7:0] cfg_fc_ph,
|
||||
input wire [11:0] cfg_fc_pd,
|
||||
input wire [7:0] cfg_fc_nph,
|
||||
input wire [11:0] cfg_fc_npd,
|
||||
input wire [7:0] cfg_fc_cplh,
|
||||
input wire [11:0] cfg_fc_cpld,
|
||||
output wire [2:0] cfg_fc_sel,
|
||||
|
||||
input wire [3:0] cfg_interrupt_msi_enable,
|
||||
input wire [11:0] cfg_interrupt_msi_mmenable,
|
||||
input wire cfg_interrupt_msi_mask_update,
|
||||
input wire [31:0] cfg_interrupt_msi_data,
|
||||
output wire [3:0] cfg_interrupt_msi_select,
|
||||
output wire [31:0] cfg_interrupt_msi_int,
|
||||
output wire [31:0] cfg_interrupt_msi_pending_status,
|
||||
output wire cfg_interrupt_msi_pending_status_data_enable,
|
||||
output wire [3:0] cfg_interrupt_msi_pending_status_function_num,
|
||||
input wire cfg_interrupt_msi_sent,
|
||||
input wire cfg_interrupt_msi_fail,
|
||||
output wire [2:0] cfg_interrupt_msi_attr,
|
||||
output wire cfg_interrupt_msi_tph_present,
|
||||
output wire [1:0] cfg_interrupt_msi_tph_type,
|
||||
output wire [8:0] cfg_interrupt_msi_tph_st_tag,
|
||||
output wire [3:0] cfg_interrupt_msi_function_number,
|
||||
|
||||
output wire status_error_cor,
|
||||
output wire status_error_uncor
|
||||
);
|
||||
|
||||
assign qsfp_led_act = 1'b0;
|
||||
assign qsfp_led_stat_g = 1'b0;
|
||||
assign qsfp_led_stat_y = 1'b0;
|
||||
|
||||
example_core_pcie_us #(
|
||||
.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),
|
||||
.RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH),
|
||||
.RQ_SEQ_NUM_ENABLE(RQ_SEQ_NUM_ENABLE),
|
||||
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
|
||||
.READ_OP_TABLE_SIZE(PCIE_TAG_COUNT),
|
||||
.READ_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)),
|
||||
.READ_TX_FC_ENABLE(1),
|
||||
.WRITE_OP_TABLE_SIZE(2**(RQ_SEQ_NUM_WIDTH-1)),
|
||||
.WRITE_TX_LIMIT(2**(RQ_SEQ_NUM_WIDTH-1)),
|
||||
.WRITE_TX_FC_ENABLE(1),
|
||||
.BAR0_APERTURE(BAR0_APERTURE),
|
||||
.BAR2_APERTURE(BAR2_APERTURE)
|
||||
)
|
||||
example_core_pcie_us_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
/*
|
||||
* AXI input (RC)
|
||||
*/
|
||||
.s_axis_rc_tdata(s_axis_rc_tdata),
|
||||
.s_axis_rc_tkeep(s_axis_rc_tkeep),
|
||||
.s_axis_rc_tvalid(s_axis_rc_tvalid),
|
||||
.s_axis_rc_tready(s_axis_rc_tready),
|
||||
.s_axis_rc_tlast(s_axis_rc_tlast),
|
||||
.s_axis_rc_tuser(s_axis_rc_tuser),
|
||||
|
||||
/*
|
||||
* AXI output (RQ)
|
||||
*/
|
||||
.m_axis_rq_tdata(m_axis_rq_tdata),
|
||||
.m_axis_rq_tkeep(m_axis_rq_tkeep),
|
||||
.m_axis_rq_tvalid(m_axis_rq_tvalid),
|
||||
.m_axis_rq_tready(m_axis_rq_tready),
|
||||
.m_axis_rq_tlast(m_axis_rq_tlast),
|
||||
.m_axis_rq_tuser(m_axis_rq_tuser),
|
||||
|
||||
/*
|
||||
* AXI input (CQ)
|
||||
*/
|
||||
.s_axis_cq_tdata(s_axis_cq_tdata),
|
||||
.s_axis_cq_tkeep(s_axis_cq_tkeep),
|
||||
.s_axis_cq_tvalid(s_axis_cq_tvalid),
|
||||
.s_axis_cq_tready(s_axis_cq_tready),
|
||||
.s_axis_cq_tlast(s_axis_cq_tlast),
|
||||
.s_axis_cq_tuser(s_axis_cq_tuser),
|
||||
|
||||
/*
|
||||
* AXI output (CC)
|
||||
*/
|
||||
.m_axis_cc_tdata(m_axis_cc_tdata),
|
||||
.m_axis_cc_tkeep(m_axis_cc_tkeep),
|
||||
.m_axis_cc_tvalid(m_axis_cc_tvalid),
|
||||
.m_axis_cc_tready(m_axis_cc_tready),
|
||||
.m_axis_cc_tlast(m_axis_cc_tlast),
|
||||
.m_axis_cc_tuser(m_axis_cc_tuser),
|
||||
|
||||
/*
|
||||
* Transmit sequence number input
|
||||
*/
|
||||
.s_axis_rq_seq_num_0(s_axis_rq_seq_num_0),
|
||||
.s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0),
|
||||
.s_axis_rq_seq_num_1(s_axis_rq_seq_num_1),
|
||||
.s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1),
|
||||
|
||||
/*
|
||||
* Flow control
|
||||
*/
|
||||
.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 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),
|
||||
|
||||
/*
|
||||
* Interrupt interface
|
||||
*/
|
||||
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
|
||||
.cfg_interrupt_msi_vf_enable(8'd0),
|
||||
.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),
|
||||
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
.cfg_max_read_req(cfg_max_read_req),
|
||||
.cfg_max_payload(cfg_max_payload),
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
.status_error_cor(status_error_cor),
|
||||
.status_error_uncor(status_error_uncor)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
56
example/AU50/fpga/rtl/sync_reset.v
Normal file
56
example/AU50/fpga/rtl/sync_reset.v
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
|
||||
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
|
||||
|
||||
`resetall
|
||||
`timescale 1 ns / 1 ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
`resetall
|
62
example/AU50/fpga/rtl/sync_signal.v
Normal file
62
example/AU50/fpga/rtl/sync_signal.v
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
|
||||
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
|
||||
|
||||
`resetall
|
||||
`timescale 1 ns / 1 ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
`resetall
|
123
example/AU50/fpga/tb/fpga_core/Makefile
Normal file
123
example/AU50/fpga/tb/fpga_core/Makefile
Normal file
@ -0,0 +1,123 @@
|
||||
# Copyright (c) 2020 Alex Forencich
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
TOPLEVEL_LANG = verilog
|
||||
|
||||
SIM ?= icarus
|
||||
WAVES ?= 0
|
||||
|
||||
COCOTB_HDL_TIMEUNIT = 1ns
|
||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||
|
||||
DUT = fpga_core
|
||||
TOPLEVEL = $(DUT)
|
||||
MODULE = test_$(DUT)
|
||||
VERILOG_SOURCES += ../../rtl/$(DUT).v
|
||||
VERILOG_SOURCES += ../../rtl/common/example_core_pcie_us.v
|
||||
VERILOG_SOURCES += ../../rtl/common/example_core_pcie.v
|
||||
VERILOG_SOURCES += ../../rtl/common/example_core.v
|
||||
VERILOG_SOURCES += ../../rtl/common/axi_ram.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rc.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_rq.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cq.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_if_cc.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axil_master.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_rd.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_axi_master_wr.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux_bar.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_demux.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_mux.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_rd.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_wr.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v
|
||||
|
||||
# module parameters
|
||||
export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512
|
||||
export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 )
|
||||
export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137)
|
||||
export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161)
|
||||
export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183)
|
||||
export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81)
|
||||
export PARAM_RQ_SEQ_NUM_WIDTH ?= 6
|
||||
export PARAM_RQ_SEQ_NUM_ENABLE ?= 1
|
||||
export PARAM_PCIE_TAG_COUNT ?= 64
|
||||
export PARAM_BAR0_APERTURE ?= 24
|
||||
export PARAM_BAR2_APERTURE ?= 24
|
||||
|
||||
ifeq ($(SIM), icarus)
|
||||
PLUSARGS += -fst
|
||||
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).PCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).BAR2_APERTURE=$(PARAM_BAR2_APERTURE)
|
||||
|
||||
ifeq ($(WAVES), 1)
|
||||
VERILOG_SOURCES += iverilog_dump.v
|
||||
COMPILE_ARGS += -s iverilog_dump
|
||||
endif
|
||||
else ifeq ($(SIM), verilator)
|
||||
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
|
||||
|
||||
COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH)
|
||||
COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH)
|
||||
COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH)
|
||||
COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH)
|
||||
COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH)
|
||||
COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH)
|
||||
COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH)
|
||||
COMPILE_ARGS += -GRQ_SEQ_NUM_ENABLE=$(PARAM_RQ_SEQ_NUM_ENABLE)
|
||||
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
|
||||
COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE)
|
||||
COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE)
|
||||
|
||||
ifeq ($(WAVES), 1)
|
||||
COMPILE_ARGS += --trace-fst
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
|
||||
iverilog_dump.v:
|
||||
echo 'module iverilog_dump();' > $@
|
||||
echo 'initial begin' >> $@
|
||||
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
|
||||
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
|
||||
echo 'end' >> $@
|
||||
echo 'endmodule' >> $@
|
||||
|
||||
clean::
|
||||
@rm -rf iverilog_dump.v
|
||||
@rm -rf dump.fst $(TOPLEVEL).fst
|
472
example/AU50/fpga/tb/fpga_core/test_fpga_core.py
Normal file
472
example/AU50/fpga/tb/fpga_core/test_fpga_core.py
Normal file
@ -0,0 +1,472 @@
|
||||
"""
|
||||
|
||||
Copyright (c) 2020 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import cocotb_test.simulator
|
||||
|
||||
import cocotb
|
||||
from cocotb.log import SimLog
|
||||
from cocotb.triggers import RisingEdge, FallingEdge, Timer
|
||||
|
||||
from cocotbext.axi import AxiStreamBus
|
||||
from cocotbext.pcie.core import RootComplex
|
||||
from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice
|
||||
|
||||
|
||||
class TB(object):
|
||||
def __init__(self, dut):
|
||||
self.dut = dut
|
||||
|
||||
self.log = SimLog("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
# PCIe
|
||||
self.rc = RootComplex()
|
||||
|
||||
self.dev = UltraScalePlusPcieDevice(
|
||||
# configuration options
|
||||
pcie_generation=3,
|
||||
pcie_link_width=16,
|
||||
user_clk_frequency=250e6,
|
||||
alignment="dword",
|
||||
cq_cc_straddle=False,
|
||||
rq_rc_straddle=False,
|
||||
rc_4tlp_straddle=False,
|
||||
enable_pf1=False,
|
||||
enable_client_tag=True,
|
||||
enable_extended_tag=True,
|
||||
enable_parity=False,
|
||||
enable_rx_msg_interface=False,
|
||||
enable_sriov=False,
|
||||
enable_extended_configuration=False,
|
||||
|
||||
enable_pf0_msi=True,
|
||||
enable_pf1_msi=False,
|
||||
|
||||
# signals
|
||||
# Clock and Reset Interface
|
||||
user_clk=dut.clk,
|
||||
user_reset=dut.rst,
|
||||
# user_lnk_up
|
||||
# sys_clk
|
||||
# sys_clk_gt
|
||||
# sys_reset
|
||||
# phy_rdy_out
|
||||
|
||||
# Requester reQuest Interface
|
||||
rq_bus=AxiStreamBus.from_prefix(dut, "m_axis_rq"),
|
||||
pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0,
|
||||
pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0,
|
||||
pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1,
|
||||
pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1,
|
||||
# pcie_rq_tag0
|
||||
# pcie_rq_tag1
|
||||
# pcie_rq_tag_av
|
||||
# pcie_rq_tag_vld0
|
||||
# pcie_rq_tag_vld1
|
||||
|
||||
# Requester Completion Interface
|
||||
rc_bus=AxiStreamBus.from_prefix(dut, "s_axis_rc"),
|
||||
|
||||
# Completer reQuest Interface
|
||||
cq_bus=AxiStreamBus.from_prefix(dut, "s_axis_cq"),
|
||||
# pcie_cq_np_req
|
||||
# pcie_cq_np_req_count
|
||||
|
||||
# Completer Completion Interface
|
||||
cc_bus=AxiStreamBus.from_prefix(dut, "m_axis_cc"),
|
||||
|
||||
# Transmit Flow Control Interface
|
||||
# pcie_tfc_nph_av=dut.pcie_tfc_nph_av,
|
||||
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
|
||||
|
||||
# Configuration Management Interface
|
||||
cfg_mgmt_addr=dut.cfg_mgmt_addr,
|
||||
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
|
||||
cfg_mgmt_write=dut.cfg_mgmt_write,
|
||||
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
|
||||
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
|
||||
cfg_mgmt_read=dut.cfg_mgmt_read,
|
||||
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
|
||||
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
|
||||
# cfg_mgmt_debug_access
|
||||
|
||||
# Configuration Status Interface
|
||||
# cfg_phy_link_down
|
||||
# cfg_phy_link_status
|
||||
# cfg_negotiated_width
|
||||
# cfg_current_speed
|
||||
cfg_max_payload=dut.cfg_max_payload,
|
||||
cfg_max_read_req=dut.cfg_max_read_req,
|
||||
# cfg_function_status
|
||||
# cfg_vf_status
|
||||
# cfg_function_power_state
|
||||
# cfg_vf_power_state
|
||||
# cfg_link_power_state
|
||||
# cfg_err_cor_out
|
||||
# cfg_err_nonfatal_out
|
||||
# cfg_err_fatal_out
|
||||
# cfg_local_error_out
|
||||
# cfg_local_error_valid
|
||||
# cfg_rx_pm_state
|
||||
# cfg_tx_pm_state
|
||||
# cfg_ltssm_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
|
||||
|
||||
# Configuration Received Message Interface
|
||||
# cfg_msg_received
|
||||
# cfg_msg_received_data
|
||||
# cfg_msg_received_type
|
||||
|
||||
# Configuration Transmit Message Interface
|
||||
# cfg_msg_transmit
|
||||
# cfg_msg_transmit_type
|
||||
# cfg_msg_transmit_data
|
||||
# cfg_msg_transmit_done
|
||||
|
||||
# Configuration Flow Control Interface
|
||||
cfg_fc_ph=dut.cfg_fc_ph,
|
||||
cfg_fc_pd=dut.cfg_fc_pd,
|
||||
cfg_fc_nph=dut.cfg_fc_nph,
|
||||
cfg_fc_npd=dut.cfg_fc_npd,
|
||||
cfg_fc_cplh=dut.cfg_fc_cplh,
|
||||
cfg_fc_cpld=dut.cfg_fc_cpld,
|
||||
cfg_fc_sel=dut.cfg_fc_sel,
|
||||
|
||||
# Configuration Control Interface
|
||||
# cfg_hot_reset_in
|
||||
# cfg_hot_reset_out
|
||||
# cfg_config_space_enable
|
||||
# cfg_dsn
|
||||
# cfg_bus_number
|
||||
# cfg_ds_port_number
|
||||
# cfg_ds_bus_number
|
||||
# cfg_ds_device_number
|
||||
# cfg_ds_function_number
|
||||
# cfg_power_state_change_ack
|
||||
# cfg_power_state_change_interrupt
|
||||
cfg_err_cor_in=dut.status_error_cor,
|
||||
cfg_err_uncor_in=dut.status_error_uncor,
|
||||
# cfg_flr_in_process
|
||||
# cfg_flr_done
|
||||
# cfg_vf_flr_in_process
|
||||
# cfg_vf_flr_func_num
|
||||
# cfg_vf_flr_done
|
||||
# cfg_pm_aspm_l1_entry_reject
|
||||
# cfg_pm_aspm_tx_l0s_entry_disable
|
||||
# cfg_req_pm_transition_l23_ready
|
||||
# cfg_link_training_enable
|
||||
|
||||
# Configuration Interrupt Controller Interface
|
||||
# cfg_interrupt_int
|
||||
# cfg_interrupt_sent
|
||||
# cfg_interrupt_pending
|
||||
cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable,
|
||||
cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable,
|
||||
cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update,
|
||||
cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data,
|
||||
# cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select,
|
||||
cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int,
|
||||
cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status,
|
||||
cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable,
|
||||
# cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num,
|
||||
cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent,
|
||||
cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail,
|
||||
# cfg_interrupt_msix_enable
|
||||
# cfg_interrupt_msix_mask
|
||||
# cfg_interrupt_msix_vf_enable
|
||||
# cfg_interrupt_msix_vf_mask
|
||||
# cfg_interrupt_msix_address
|
||||
# cfg_interrupt_msix_data
|
||||
# cfg_interrupt_msix_int
|
||||
# cfg_interrupt_msix_vec_pending
|
||||
# cfg_interrupt_msix_vec_pending_status
|
||||
cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr,
|
||||
cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present,
|
||||
cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type,
|
||||
# cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag,
|
||||
# cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number,
|
||||
|
||||
# Configuration Extend Interface
|
||||
# cfg_ext_read_received
|
||||
# cfg_ext_write_received
|
||||
# cfg_ext_register_number
|
||||
# cfg_ext_function_number
|
||||
# cfg_ext_write_data
|
||||
# cfg_ext_write_byte_enable
|
||||
# cfg_ext_read_data
|
||||
# cfg_ext_read_data_valid
|
||||
)
|
||||
|
||||
# self.dev.log.setLevel(logging.DEBUG)
|
||||
|
||||
self.rc.make_port().connect(self.dev)
|
||||
|
||||
self.dev.functions[0].msi_multiple_message_capable = 5
|
||||
|
||||
self.dev.functions[0].configure_bar(0, 2**len(dut.example_core_pcie_us_inst.core_pcie_inst.axil_ctrl_awaddr))
|
||||
self.dev.functions[0].configure_bar(2, 2**len(dut.example_core_pcie_us_inst.core_pcie_inst.axi_ram_awaddr))
|
||||
|
||||
async def init(self):
|
||||
|
||||
await FallingEdge(self.dut.rst)
|
||||
await Timer(100, 'ns')
|
||||
|
||||
await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True)
|
||||
|
||||
|
||||
@cocotb.test()
|
||||
async def run_test(dut):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
await tb.init()
|
||||
|
||||
mem = tb.rc.mem_pool.alloc_region(16*1024*1024)
|
||||
mem_base = mem.get_absolute_address(0)
|
||||
|
||||
dev_pf0_bar0 = tb.rc.tree[0][0].bar_window[0]
|
||||
dev_pf0_bar2 = tb.rc.tree[0][0].bar_window[2]
|
||||
|
||||
tb.log.info("Test memory write to BAR 2")
|
||||
|
||||
test_data = b'\x11\x22\x33\x44'
|
||||
await dev_pf0_bar2.write(0, test_data)
|
||||
|
||||
await Timer(100, 'ns')
|
||||
|
||||
tb.log.info("Test memory read from BAR 2")
|
||||
|
||||
val = await dev_pf0_bar2.read(0, len(test_data), timeout=1000)
|
||||
tb.log.info("Read data: %s", val)
|
||||
assert val == test_data
|
||||
|
||||
tb.log.info("Test DMA")
|
||||
|
||||
# write packet data
|
||||
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
|
||||
|
||||
# enable DMA
|
||||
await dev_pf0_bar0.write_dword(0x000000, 1)
|
||||
|
||||
# write pcie read descriptor
|
||||
await dev_pf0_bar0.write_dword(0x000100, (mem_base+0x0000) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x000104, (mem_base+0x0000 >> 32) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x000108, 0x100)
|
||||
await dev_pf0_bar0.write_dword(0x000110, 0x400)
|
||||
await dev_pf0_bar0.write_dword(0x000114, 0xAA)
|
||||
|
||||
await Timer(2000, 'ns')
|
||||
|
||||
# read status
|
||||
val = await dev_pf0_bar0.read_dword(0x000118)
|
||||
tb.log.info("Status: 0x%x", val)
|
||||
assert val == 0x800000AA
|
||||
|
||||
# write pcie write descriptor
|
||||
await dev_pf0_bar0.write_dword(0x000200, (mem_base+0x1000) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x000204, (mem_base+0x1000 >> 32) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x000208, 0x100)
|
||||
await dev_pf0_bar0.write_dword(0x000210, 0x400)
|
||||
await dev_pf0_bar0.write_dword(0x000214, 0x55)
|
||||
|
||||
await Timer(2000, 'ns')
|
||||
|
||||
# read status
|
||||
val = await dev_pf0_bar0.read_dword(0x000218)
|
||||
tb.log.info("Status: 0x%x", val)
|
||||
assert val == 0x80000055
|
||||
|
||||
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
|
||||
|
||||
assert mem[0:1024] == mem[0x1000:0x1000+1024]
|
||||
|
||||
tb.log.info("Test DMA block operations")
|
||||
|
||||
# write packet data
|
||||
mem[0:1024] = bytearray([x % 256 for x in range(1024)])
|
||||
|
||||
# enable DMA
|
||||
await dev_pf0_bar0.write_dword(0x000000, 1)
|
||||
# disable interrupts
|
||||
await dev_pf0_bar0.write_dword(0x000008, 0)
|
||||
|
||||
# configure operation (read)
|
||||
# DMA base address
|
||||
await dev_pf0_bar0.write_dword(0x001080, (mem_base+0x0000) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x001084, (mem_base+0x0000 >> 32) & 0xffffffff)
|
||||
# DMA offset address
|
||||
await dev_pf0_bar0.write_dword(0x001088, 0)
|
||||
await dev_pf0_bar0.write_dword(0x00108c, 0)
|
||||
# DMA offset mask
|
||||
await dev_pf0_bar0.write_dword(0x001090, 0x000003ff)
|
||||
await dev_pf0_bar0.write_dword(0x001094, 0)
|
||||
# DMA stride
|
||||
await dev_pf0_bar0.write_dword(0x001098, 256)
|
||||
await dev_pf0_bar0.write_dword(0x00109c, 0)
|
||||
# RAM base address
|
||||
await dev_pf0_bar0.write_dword(0x0010c0, 0)
|
||||
await dev_pf0_bar0.write_dword(0x0010c4, 0)
|
||||
# RAM offset address
|
||||
await dev_pf0_bar0.write_dword(0x0010c8, 0)
|
||||
await dev_pf0_bar0.write_dword(0x0010cc, 0)
|
||||
# RAM offset mask
|
||||
await dev_pf0_bar0.write_dword(0x0010d0, 0x000003ff)
|
||||
await dev_pf0_bar0.write_dword(0x0010d4, 0)
|
||||
# RAM stride
|
||||
await dev_pf0_bar0.write_dword(0x0010d8, 256)
|
||||
await dev_pf0_bar0.write_dword(0x0010dc, 0)
|
||||
# clear cycle count
|
||||
await dev_pf0_bar0.write_dword(0x001008, 0)
|
||||
await dev_pf0_bar0.write_dword(0x00100c, 0)
|
||||
# block length
|
||||
await dev_pf0_bar0.write_dword(0x001010, 256)
|
||||
# block count
|
||||
await dev_pf0_bar0.write_dword(0x001018, 32)
|
||||
await dev_pf0_bar0.write_dword(0x00101c, 0)
|
||||
# start
|
||||
await dev_pf0_bar0.write_dword(0x001000, 1)
|
||||
|
||||
await Timer(2000, 'ns')
|
||||
|
||||
# configure operation (write)
|
||||
# DMA base address
|
||||
await dev_pf0_bar0.write_dword(0x001180, (mem_base+0x0000) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x001184, (mem_base+0x0000 >> 32) & 0xffffffff)
|
||||
# DMA offset address
|
||||
await dev_pf0_bar0.write_dword(0x001188, 0)
|
||||
await dev_pf0_bar0.write_dword(0x00118c, 0)
|
||||
# DMA offset mask
|
||||
await dev_pf0_bar0.write_dword(0x001190, 0x000003ff)
|
||||
await dev_pf0_bar0.write_dword(0x001194, 0)
|
||||
# DMA stride
|
||||
await dev_pf0_bar0.write_dword(0x001198, 256)
|
||||
await dev_pf0_bar0.write_dword(0x00119c, 0)
|
||||
# RAM base address
|
||||
await dev_pf0_bar0.write_dword(0x0011c0, 0)
|
||||
await dev_pf0_bar0.write_dword(0x0011c4, 0)
|
||||
# RAM offset address
|
||||
await dev_pf0_bar0.write_dword(0x0011c8, 0)
|
||||
await dev_pf0_bar0.write_dword(0x0011cc, 0)
|
||||
# RAM offset mask
|
||||
await dev_pf0_bar0.write_dword(0x0011d0, 0x000003ff)
|
||||
await dev_pf0_bar0.write_dword(0x0011d4, 0)
|
||||
# RAM stride
|
||||
await dev_pf0_bar0.write_dword(0x0011d8, 256)
|
||||
await dev_pf0_bar0.write_dword(0x0011dc, 0)
|
||||
# clear cycle count
|
||||
await dev_pf0_bar0.write_dword(0x001108, 0)
|
||||
await dev_pf0_bar0.write_dword(0x00110c, 0)
|
||||
# block length
|
||||
await dev_pf0_bar0.write_dword(0x001110, 256)
|
||||
# block count
|
||||
await dev_pf0_bar0.write_dword(0x001118, 32)
|
||||
await dev_pf0_bar0.write_dword(0x00111c, 0)
|
||||
# start
|
||||
await dev_pf0_bar0.write_dword(0x001100, 1)
|
||||
|
||||
await Timer(2000, 'ns')
|
||||
|
||||
await RisingEdge(dut.clk)
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
# cocotb-test
|
||||
|
||||
tests_dir = os.path.dirname(__file__)
|
||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
|
||||
pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl'))
|
||||
|
||||
|
||||
def test_fpga_core(request):
|
||||
dut = "fpga_core"
|
||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||
toplevel = dut
|
||||
|
||||
verilog_sources = [
|
||||
os.path.join(rtl_dir, f"{dut}.v"),
|
||||
os.path.join(rtl_dir, "common", "example_core_pcie_us.v"),
|
||||
os.path.join(rtl_dir, "common", "example_core_pcie.v"),
|
||||
os.path.join(rtl_dir, "common", "example_core.v"),
|
||||
os.path.join(rtl_dir, "common", "axi_ram.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_if.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_if_rc.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_if_rq.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_if_cq.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_if_cc.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_us_msi.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_axil_master.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_axi_master.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_axi_master_rd.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_axi_master_wr.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_tlp_demux_bar.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_tlp_demux.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_tlp_mux.v"),
|
||||
os.path.join(pcie_rtl_dir, "dma_if_pcie.v"),
|
||||
os.path.join(pcie_rtl_dir, "dma_if_pcie_rd.v"),
|
||||
os.path.join(pcie_rtl_dir, "dma_if_pcie_wr.v"),
|
||||
os.path.join(pcie_rtl_dir, "dma_psdpram.v"),
|
||||
os.path.join(pcie_rtl_dir, "arbiter.v"),
|
||||
os.path.join(pcie_rtl_dir, "priority_encoder.v"),
|
||||
os.path.join(pcie_rtl_dir, "pulse_merge.v"),
|
||||
]
|
||||
|
||||
parameters = {}
|
||||
|
||||
parameters['AXIS_PCIE_DATA_WIDTH'] = 512
|
||||
parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32
|
||||
parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137
|
||||
parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161
|
||||
parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183
|
||||
parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81
|
||||
parameters['RQ_SEQ_NUM_WIDTH'] = 6
|
||||
parameters['RQ_SEQ_NUM_ENABLE'] = 1
|
||||
parameters['PCIE_TAG_COUNT'] = 64
|
||||
parameters['BAR0_APERTURE'] = 24
|
||||
parameters['BAR2_APERTURE'] = 24
|
||||
|
||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||
|
||||
sim_build = os.path.join(tests_dir, "sim_build",
|
||||
request.node.name.replace('[', '-').replace(']', ''))
|
||||
|
||||
cocotb_test.simulator.run(
|
||||
python_search=[tests_dir],
|
||||
verilog_sources=verilog_sources,
|
||||
toplevel=toplevel,
|
||||
module=module,
|
||||
parameters=parameters,
|
||||
sim_build=sim_build,
|
||||
extra_env=extra_env,
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user