1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

merged changes in pcie

This commit is contained in:
Alex Forencich 2021-12-02 17:00:11 -08:00
commit bbb9f42516
162 changed files with 20264 additions and 39 deletions

View File

@ -12,10 +12,20 @@ Collection of PCI express related components. Includes PCIe to AXI and AXI lite
Example designs are included for the following FPGA boards:
* Alpha Data ADM-PCIE-9V3 (Xilinx Virtex UltraScale+ XCVU3P)
* BittWare 520N-MX (Intel Stratix 10 MX 1SM21CHU2F53E2VG)
* Exablaze ExaNIC X10 (Xilinx Kintex UltraScale XCKU035)
* Exablaze ExaNIC X25 (Xilinx Kintex UltraScale+ XCKU3P)
* Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P)
* Intel Stratix 10 MX dev kit (Intel Stratix 10 MX 1SM21CHU1F53E1VG)
* Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50)
* Xilinx Alveo U200 (Xilinx Virtex UltraScale+ XCU200)
* Xilinx Alveo U250 (Xilinx Virtex UltraScale+ XCU250)
* Xilinx Alveo U280 (Xilinx Virtex UltraScale+ XCU280)
* Xilinx VCU108 (Xilinx Virtex UltraScale XCVU095)
* Xilinx VCU118 (Xilinx Virtex UltraScale+ XCVU9P)
* Xilinx VCU1525 (Xilinx Virtex UltraScale+ XCVU9P)
* Xilinx ZCU106 (Xilinx Zynq UltraScale+ XCZU7EV)
## Documentation

View File

@ -33,7 +33,6 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus
from cocotbext.axi.utils import hexdump_str
class TB(object):
@ -156,8 +155,8 @@ class TB(object):
self.dev.functions[0].msi_multiple_message_capable = 5
self.dev.functions[0].configure_bar(0, 2**22)
self.dev.functions[0].configure_bar(2, 2**22)
self.dev.functions[0].configure_bar(0, 2**len(dut.example_core_pcie_s10_inst.core_pcie_inst.axil_ctrl_awaddr))
self.dev.functions[0].configure_bar(2, 2**len(dut.example_core_pcie_s10_inst.core_pcie_inst.axi_ram_awaddr))
async def init(self):

View File

@ -0,0 +1,19 @@
# Verilog PCIe ADM-PCIE-9V3 Example Design
## Introduction
This example design targets the Alpha Data ADM-PCIE-9V3 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: xcvu3p-ffvc1517-2-i
## 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 ADM-PCIE-9V3 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,206 @@
# XDC constraints for the ADM-PCIE-9V3
# part: xcvu3p-ffvc1517-2-i
# 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.EXTMASTERCCLK_EN {DIV-1} [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN {Pullnone} [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 300 MHz system clock
#set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p]
#set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n]
#create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p]
# LEDs
set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}]
set_property -dict {LOC AU27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[1]}]
set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_r}]
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}]
set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}]
set_false_path -to [get_ports {user_led_g[*] user_led_r front_led[*]}]
set_output_delay 0 [get_ports {user_led_g[*] user_led_r front_led[*]}]
# Switches
#set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}]
#set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
#set_false_path -from [get_ports {user_sw[*]}]
#set_input_delay 0 [get_ports {user_sw[*]}]
# GPIO
#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]]
#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]]
#set_property -dict {LOC J31 IOSTANDARD LVCMOS18} [get_ports gpio_p[1]]
#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]]
# QSFP28 Interfaces
#set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
#set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ?
#set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
#set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l]
#set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l]
# 161.1328125 MHz MGT reference clock
#create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p]
#set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ?
#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
#set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l]
#set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l]
# 161.1328125 MHz MGT reference clock
#create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p]
#set_property -dict {LOC B29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_reset_l]
#set_property -dict {LOC C29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_sda]
#set_false_path -to [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
#set_output_delay 0 [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
#set_false_path -from [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_input_delay 0 [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_false_path -to [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_false_path -from [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC AT25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC AT26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_wp]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226
set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226
#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224
#set_property -dict {LOC AJ6 } [get_ports pcie_refclk_2_n] ;# MGTREFCLK0N_224
set_property -dict {LOC AJ31 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_0]
#set_property -dict {LOC AH29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports perst_1]
# 100 MHz MGT reference clock
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]
set_false_path -from [get_ports {perst_0}]
set_input_delay 0 [get_ports {perst_0}]
# QSPI flash
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[3]}]
#set_property -dict {LOC AV30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
#set_false_path -to [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_output_delay 0 [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_false_path -from [get_ports {qspi_1_dq}]
#set_input_delay 0 [get_ports {qspi_1_dq}]

View File

@ -0,0 +1,94 @@
# FPGA settings
FPGA_PART = xcvu3p-ffvc1517-2-i
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/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/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
%_primary.mcs %_secondary.mcs %_primary.prm %_secondary.prm: %.bit
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.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 _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP)_primary.mcs $(FPGA_TOP)_secondary.mcs $(FPGA_TOP)_primary.prm $(FPGA_TOP)_secondary.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 {mt25qu256-spi-x1_x2_x4_x8}] 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)_primary.mcs\" \"$(FPGA_TOP)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP)_primary.prm\" \"$(FPGA_TOP)_secondary.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

View 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 {058000} \
CONFIG.PF0_DEVICE_ID {0001} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.PF0_SUBSYSTEM_ID {9003} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} \
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 pcie4_uscale_plus_0]

View File

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

View File

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

View File

@ -0,0 +1,93 @@
/*
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 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
`resetall

View File

@ -0,0 +1,449 @@
/*
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
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga (
/*
* GPIO
*/
output wire [1:0] user_led_g,
output wire user_led_r,
output wire [1:0] front_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_1_p,
input wire pcie_refclk_1_n,
input wire perst_0
);
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;
// PCIe
wire pcie_user_clk;
wire pcie_user_reset;
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;
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_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(perst_0),
.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
*/
.user_led_g(user_led_g),
.user_led_r(user_led_r),
.front_led(front_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),
.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

View File

@ -0,0 +1,274 @@
/*
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
`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 [1:0] user_led_g,
output wire user_led_r,
output wire [1:0] front_led,
/*
* 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 user_led_g = 2'b11;
assign user_led_r = 1'b1;
assign front_led = 2'b00;
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

View 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

View 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

View 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

View 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,
)

View File

@ -0,0 +1,19 @@
# Verilog PCIe Alveo U200 Example Design
## Introduction
This example design targets the Xilinx Alveo U200 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: xcu200-fsgd2104-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 U200 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,259 @@
# XDC constraints for the Xilinx Alveo U200 board
# part: xcu200-fsgd2104-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.UNUSEDPIN PULLUP [current_design]
set_operating_conditions -design_power_budget 160
# 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]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
#set_false_path -from [get_ports {reset}]
#set_input_delay 0 [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]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# UART
#set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_txd]
#set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS12} [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}]
# QSFP28 Interfaces
#set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#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 SLEW SLOW DRIVE 8} [get_ports qsfp0_modsell]
#set_property -dict {LOC BE17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl]
#set_property -dict {LOC BE20 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_modprsl]
#set_property -dict {LOC BE21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_intl]
#set_property -dict {LOC BD18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode]
#set_property -dict {LOC AT22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_reset]
#set_property -dict {LOC AT20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[0]}]
#set_property -dict {LOC AU22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [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_false_path -to [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
#set_output_delay 0 [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
#set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}]
#set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}]
#set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#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 SLEW SLOW DRIVE 8} [get_ports qsfp1_modsell]
#set_property -dict {LOC BC18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl]
#set_property -dict {LOC BC19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_modprsl]
#set_property -dict {LOC AV21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_intl]
#set_property -dict {LOC AV22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode]
#set_property -dict {LOC AR21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_reset]
#set_property -dict {LOC AR22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[0]}]
#set_property -dict {LOC AU20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [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]
#set_false_path -to [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
#set_output_delay 0 [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
#set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}]
#set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}]
# 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]
#set_false_path -to [get_ports {i2c_sda i2c_scl}]
#set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
#set_false_path -from [get_ports {i2c_sda i2c_scl}]
#set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# PCIe Interface
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
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]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -0,0 +1,94 @@
# FPGA settings
FPGA_PART = xcu200-fsgd2104-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/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/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
%.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

View 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 {058000} \
CONFIG.PF0_DEVICE_ID {0001} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.PF0_SUBSYSTEM_ID {90c8} \
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 pcie4_uscale_plus_0]

View File

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

View File

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

View File

@ -0,0 +1,93 @@
/*
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 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
`resetall

View File

@ -0,0 +1,463 @@
/*
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
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* 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 = 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
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;
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;
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_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
*/
.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),
.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

View File

@ -0,0 +1,271 @@
/*
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
`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
*/
input wire [3:0] sw,
output wire [2:0] led,
/*
* 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 led = 3'd0;
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

View 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

View 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

View 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

View File

@ -0,0 +1,474 @@
"""
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))
dut.sw.setimmediatevalue(0)
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,
)

View File

@ -0,0 +1,19 @@
# 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 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 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.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,259 @@
# 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.UNUSEDPIN PULLUP [current_design]
set_operating_conditions -design_power_budget 160
# 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]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
#set_false_path -from [get_ports {reset}]
#set_input_delay 0 [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]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# UART
#set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_txd]
#set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS12} [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}]
# 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 SLEW SLOW DRIVE 8} [get_ports qsfp0_modsell]
#set_property -dict {LOC BE17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl]
#set_property -dict {LOC BE20 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_modprsl]
#set_property -dict {LOC BE21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_intl]
#set_property -dict {LOC BD18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode]
#set_property -dict {LOC AT22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_reset]
#set_property -dict {LOC AT20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[0]}]
#set_property -dict {LOC AU22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [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_false_path -to [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
#set_output_delay 0 [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
#set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}]
#set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}]
#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 SLEW SLOW DRIVE 8} [get_ports qsfp1_modsell]
#set_property -dict {LOC BC18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl]
#set_property -dict {LOC BC19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_modprsl]
#set_property -dict {LOC AV21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_intl]
#set_property -dict {LOC AV22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode]
#set_property -dict {LOC AR21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_reset]
#set_property -dict {LOC AR22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[0]}]
#set_property -dict {LOC AU20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [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]
#set_false_path -to [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
#set_output_delay 0 [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
#set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}]
#set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}]
# 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]
#set_false_path -to [get_ports {i2c_sda i2c_scl}]
#set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
#set_false_path -from [get_ports {i2c_sda i2c_scl}]
#set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# 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]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -0,0 +1,94 @@
# 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/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/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
%.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

View 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 {058000} \
CONFIG.PF0_DEVICE_ID {0001} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.PF0_SUBSYSTEM_ID {90fa} \
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 pcie4_uscale_plus_0]

View File

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

View File

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

View File

@ -0,0 +1,93 @@
/*
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 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
`resetall

View File

@ -0,0 +1,463 @@
/*
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
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* 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 = 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
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;
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;
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_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
*/
.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),
.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

View File

@ -0,0 +1,271 @@
/*
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
`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
*/
input wire [3:0] sw,
output wire [2:0] led,
/*
* 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 led = 3'd0;
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

View 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

View 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

View 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

View File

@ -0,0 +1,474 @@
"""
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))
dut.sw.setimmediatevalue(0)
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,
)

View File

@ -0,0 +1,19 @@
# Verilog PCIe Alveo U280 Example Design
## Introduction
This example design targets the Xilinx Alveo U280 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: xcu280-fsvh2892-2L-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 U280 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,227 @@
# XDC constraints for the Xilinx Alveo U280 board
# part: xcu280-fsvh2892-2L-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 160
# System clocks
# 100 MHz (DDR4)
#set_property -dict {LOC BJ43 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
#set_property -dict {LOC BJ44 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
# 100 MHz (DDR4)
#set_property -dict {LOC BH6 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
#set_property -dict {LOC BJ6 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
# 100 MHz
#set_property -dict {LOC G31 IOSTANDARD LVDS} [get_ports clk_100mhz_2_p]
#set_property -dict {LOC F31 IOSTANDARD LVDS} [get_ports clk_100mhz_2_n]
#create_clock -period 10 -name clk_100mhz_2 [get_ports clk_100mhz_2_p]
# SI570 user clock
#set_property -dict {LOC G30 IOSTANDARD LVDS} [get_ports clk_si570_p]
#set_property -dict {LOC F30 IOSTANDARD LVDS} [get_ports clk_si570_n]
#create_clock -period 6.4 -name clk_si570 [get_ports clk_si570_p]
# Reset button
#set_property -dict {LOC L30 IOSTANDARD LVCMOS18} [get_ports reset]
#set_false_path -from [get_ports {reset}]
#set_input_delay 0 [get_ports {reset}]
# UART
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart_txd]
#set_property -dict {LOC B33 IOSTANDARD LVCMOS18} [get_ports usb_uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC K28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC J29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC K29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC J31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC D29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC E28 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 D32 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# QSFP28 Interfaces
#set_property -dict {LOC L53 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC L54 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC L48 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC L49 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC K51 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC K52 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC L44 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC L45 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC J53 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC J54 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC K46 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC K47 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC H51 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC H52 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC J48 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC J49 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC T42 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_134 from SI570
#set_property -dict {LOC T43 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_134 from SI570
#set_property -dict {LOC R40 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_134 from SI546
#set_property -dict {LOC R41 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_134 from SI546
#set_property -dict {LOC H32 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_oe_b]
#set_property -dict {LOC G32 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_fs]
# 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 SI546, fs = 0)
#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
#set_false_path -to [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
#set_output_delay 0 [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
#set_property -dict {LOC G53 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC G54 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC G48 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC G49 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC F51 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC F52 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC E48 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC E49 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC E53 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC E54 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC C48 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC C49 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC D51 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC D52 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC A49 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC A50 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC P42 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_135 from SI570
#set_property -dict {LOC P43 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_135 from SI570
#set_property -dict {LOC M42 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_135 from SI546
#set_property -dict {LOC M43 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_135 from SI546
#set_property -dict {LOC H30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_oe_b]
#set_property -dict {LOC G33 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_fs]
# 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 SI546, fs = 0)
#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
#set_false_path -to [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
#set_output_delay 0 [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
# 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 AL11} [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL10} [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 AM9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN6 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN5 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN11} [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN10} [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 AP9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP8 } [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 AR11} [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR10} [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 AR7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR6 } [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 AT9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT8 } [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 AU11} [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU10} [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 AU7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW11} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW10} [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BA6 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA5 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA11} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA10} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC11} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC10} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AL15} [get_ports pcie_refclk_0_p] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AL14} [get_ports pcie_refclk_0_n] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK13} [get_ports pcie_refclk_2_p] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK12} [get_ports pcie_refclk_2_n] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
set_property -dict {LOC AR15} [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AR14} [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP13} [get_ports pcie_refclk_3_p] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP12} [get_ports pcie_refclk_3_n] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC BH26 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}]

View File

@ -0,0 +1,94 @@
# FPGA settings
FPGA_PART = xcu280-fsvh2892-2L-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
#XCI_FILES =
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

View 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 {9118} \
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]

View File

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

View File

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

View File

@ -0,0 +1,445 @@
/*
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 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),
/*
* 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

View File

@ -0,0 +1,263 @@
/*
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`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,
/*
* 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
);
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

View 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

View 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

View 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

View 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,
)

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

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View 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}]

View 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

View 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]

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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

View 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,
)

View File

@ -34,7 +34,6 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.axi import AxiStreamBus
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.xilinx.us import UltraScalePcieDevice
from cocotbext.axi.utils import hexdump_str
class TB(object):
@ -228,8 +227,8 @@ class TB(object):
self.dev.functions[0].msi_multiple_message_capable = 5
self.dev.functions[0].configure_bar(0, 2**24)
self.dev.functions[0].configure_bar(2, 2**24)
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):

View File

@ -0,0 +1,19 @@
# Verilog PCIe ExaNIC X25 Example Design
## Introduction
This example design targets the Exablaze ExaNIC X25 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: xcku3p-ffvb676-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 ExaNIC X25 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,187 @@
# XDC constraints for the ExaNIC X25
# part: xcku3p-ffvb676-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.UNUSEDPIN Pullup [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 31.9 [current_design]
set_property BITSTREAM.CONFIG.BPI_PAGE_SIZE 8 [current_design]
set_property BITSTREAM.CONFIG.BPI_1ST_READ_CYCLE 4 [current_design]
set_property CONFIG_MODE BPI16 [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 10 MHz TXCO
#set_property -dict {LOC D14 IOSTANDARD LVCMOS33} [get_ports clk_10mhz]
#create_clock -period 100 -name clk_100mhz [get_ports clk_10mhz]
# LEDs
set_property -dict {LOC J12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[0]}]
set_property -dict {LOC H12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_1_led[1]}]
set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[0]}]
set_property -dict {LOC H13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_2_led[1]}]
set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led[0]}]
set_property -dict {LOC G12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sma_led[1]}]
set_false_path -to [get_ports {sfp_1_led[*] sfp_2_led[*] sma_led[*]}]
set_output_delay 0 [get_ports {sfp_1_led[*] sfp_2_led[*] sma_led[*]}]
# GPIO
#set_property -dict {LOC F9 IOSTANDARD LVCMOS18} [get_ports gpio[0]]
#set_property -dict {LOC F10 IOSTANDARD LVCMOS18} [get_ports gpio[1]]
#set_property -dict {LOC G9 IOSTANDARD LVCMOS18} [get_ports gpio[2]]
#set_property -dict {LOC G10 IOSTANDARD LVCMOS18} [get_ports gpio[3]]
# SMA
#set_property -dict {LOC A14 IOSTANDARD LVCMOS33} [get_ports sma_in]
#set_property -dict {LOC A12 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports sma_out]
#set_property -dict {LOC A13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sma_out_en]
#set_property -dict {LOC B12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sma_term_en]
#set_false_path -to [get_ports {sma_out sma_term sma_term_en}]
#set_output_delay 0 [get_ports {sma_out sma_term sma_term_en}]
#set_false_path -from [get_ports {sma_in}]
#set_input_delay 0 [get_ports {sma_in}]
# Config
#set_property -dict {LOC C14 IOSTANDARD LVCMOS33} [get_ports ddr_npres]
# SFP28 Interfaces
#set_property -dict {LOC D2 } [get_ports sfp_1_rx_p] ;# MGTYRXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC D1 } [get_ports sfp_1_rx_n] ;# MGTYRXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC A4 } [get_ports sfp_2_rx_p] ;# MGTYRXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC A3 } [get_ports sfp_2_rx_n] ;# MGTYRXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC F7 } [get_ports sfp_1_tx_p] ;# MGTYTXP0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC F6 } [get_ports sfp_1_tx_n] ;# MGTYTXN0_227 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC B7 } [get_ports sfp_2_tx_p] ;# MGTYTXP3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC B6 } [get_ports sfp_2_tx_n] ;# MGTYTXN3_227 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC K7 } [get_ports sfp_mgt_refclk_p] ;# MGTREFCLK0P_227 from X2
#set_property -dict {LOC K6 } [get_ports sfp_mgt_refclk_n] ;# MGTREFCLK0N_227 from X2
#set_property -dict {LOC AC17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_1_tx_disable]
#set_property -dict {LOC AA17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports sfp_2_tx_disable]
#set_property -dict {LOC F12 IOSTANDARD LVCMOS33 PULLUP true} [get_ports sfp_1_npres]
#set_property -dict {LOC F14 IOSTANDARD LVCMOS33 PULLUP true} [get_ports sfp_2_npres]
#set_property -dict {LOC AC16 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_1_los]
#set_property -dict {LOC Y17 IOSTANDARD LVCMOS18 PULLUP true} [get_ports sfp_2_los]
#set_property -dict {LOC G14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sfp_1_rs]
#set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports sfp_2_rs]
#set_property -dict {LOC A10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_i2c_scl]
#set_property -dict {LOC C11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_1_i2c_sda]
#set_property -dict {LOC B11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports sfp_2_i2c_sda]
# 161.1328125 MHz MGT reference clock
#create_clock -period 6.206 -name sfp_mgt_refclk [get_ports sfp_mgt_refclk_p]
#set_false_path -to [get_ports {sfp_1_tx_disable sfp_2_tx_disable sfp_1_rs sfp_2_rs}]
#set_output_delay 0 [get_ports {sfp_1_tx_disable sfp_2_tx_disable sfp_1_rs sfp_2_rs}]
#set_false_path -from [get_ports {sfp_1_npres sfp_2_npres sfp_1_los sfp_2_los}]
#set_input_delay 0 [get_ports {sfp_1_npres sfp_2_npres sfp_1_los sfp_2_los}]
#set_false_path -to [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
#set_output_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
#set_false_path -from [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
#set_input_delay 0 [get_ports {sfp_1_i2c_sda sfp_2_i2c_sda sfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC B9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC A9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
set_property -dict {LOC P2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC P1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC Y2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC Y1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC V7 } [get_ports pcie_refclk_p] ;# MGTREFCLK0P_225
set_property -dict {LOC V6 } [get_ports pcie_refclk_n] ;# MGTREFCLK0N_225
set_property -dict {LOC T19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p]
# BPI flash
#set_property -dict {LOC AF20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[0]}]
#set_property -dict {LOC AE18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[1]}]
#set_property -dict {LOC AF19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[2]}]
#set_property -dict {LOC AF17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[3]}]
#set_property -dict {LOC AB19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[4]}]
#set_property -dict {LOC AD19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[5]}]
#set_property -dict {LOC AB17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[6]}]
#set_property -dict {LOC AE17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[7]}]
#set_property -dict {LOC AD16 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[8]}]
#set_property -dict {LOC AE16 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[9]}]
#set_property -dict {LOC AD18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[10]}]
#set_property -dict {LOC AC21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[11]}]
#set_property -dict {LOC AE22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[12]}]
#set_property -dict {LOC AF22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[13]}]
#set_property -dict {LOC AF25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[14]}]
#set_property -dict {LOC AF24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[15]}]
#set_property -dict {LOC AE20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[0]}]
#set_property -dict {LOC AE26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[1]}]
#set_property -dict {LOC AD24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[2]}]
#set_property -dict {LOC AC23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[3]}]
#set_property -dict {LOC AE23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[4]}]
#set_property -dict {LOC AD20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[5]}]
#set_property -dict {LOC AC24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[6]}]
#set_property -dict {LOC AC22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[7]}]
#set_property -dict {LOC AD23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[8]}]
#set_property -dict {LOC AD21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[9]}]
#set_property -dict {LOC AB22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[10]}]
#set_property -dict {LOC AA22 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[11]}]
#set_property -dict {LOC AE25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[12]}]
#set_property -dict {LOC AD26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[13]}]
#set_property -dict {LOC AB25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[14]}]
#set_property -dict {LOC AB26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[15]}]
#set_property -dict {LOC AD25 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[16]}]
#set_property -dict {LOC AC26 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[17]}]
#set_property -dict {LOC AB21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[18]}]
#set_property -dict {LOC AB24 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[19]}]
#set_property -dict {LOC Y18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[20]}]
#set_property -dict {LOC AA20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[21]}]
#set_property -dict {LOC AC19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[22]}]
#set_property -dict {LOC Y20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {flash_region}]
#set_property -dict {LOC AF18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_ce_n}]
#set_property -dict {LOC Y21 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_oe_n}]
#set_property -dict {LOC AB20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_we_n}]
#set_property -dict {LOC AF23 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_adv_n}]
#set_false_path -to [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
#set_output_delay 0 [get_ports {flash_dq[*] flash_addr[*] flash_region flash_ce_n flash_oe_n flash_we_n flash_adv_n}]
#set_false_path -from [get_ports {flash_dq[*]}]
#set_input_delay 0 [get_ports {flash_dq[*]}]

View File

@ -0,0 +1,95 @@
# FPGA settings
FPGA_PART = xcku3p-ffvb676-2-e
FPGA_TOP = fpga
FPGA_ARCH = kintexuplus
# 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/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/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
%.mcs %.prm: %.bit
echo "write_cfgmem -force -format mcs -size 32 -interface BPIx16 -loadbit {up 0x00800000 $*.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 {s29gl256p-bpi-x16}] 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.BPI_RS_PINS {24:23} [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

View File

@ -0,0 +1,32 @@
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 {X8} \
CONFIG.AXISTEN_IF_RC_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {256_bit} \
CONFIG.extended_tag_field {true} \
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 {0009} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ce4} \
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} \
CONFIG.mode_selection {Advanced} \
CONFIG.en_gt_selection {true} \
CONFIG.MASTER_GT {GTYE4_CHANNEL_X0Y7} \
] [get_ips pcie4_uscale_plus_0]

View File

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

View File

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

View File

@ -0,0 +1,93 @@
/*
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 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
`resetall

View File

@ -0,0 +1,449 @@
/*
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
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga (
/*
* GPIO
*/
output wire [1:0] sfp_1_led,
output wire [1:0] sfp_2_led,
output wire [1:0] sma_led,
/*
* PCI express
*/
input wire [7:0] pcie_rx_p,
input wire [7:0] pcie_rx_n,
output wire [7:0] pcie_tx_p,
output wire [7:0] pcie_tx_n,
input wire pcie_refclk_p,
input wire pcie_refclk_n,
input wire pcie_reset_n
);
parameter AXIS_PCIE_DATA_WIDTH = 256;
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;
// PCIe
wire pcie_user_clk;
wire pcie_user_reset;
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;
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;
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_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
*/
.sfp_1_led(sfp_1_led),
.sfp_2_led(sfp_2_led),
.sma_led(sma_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),
.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

View File

@ -0,0 +1,274 @@
/*
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
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA core logic
*/
module fpga_core #
(
parameter AXIS_PCIE_DATA_WIDTH = 256,
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 [1:0] sfp_1_led,
output wire [1:0] sfp_2_led,
output wire [1:0] sma_led,
/*
* 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 sfp_1_led = 2'b00;
assign sfp_2_led = 2'b00;
assign sma_led = 2'b00;
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

View 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

View 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

View 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 ?= 256
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

View 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=8,
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'] = 256
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,
)

View File

@ -33,7 +33,6 @@ from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus
from cocotbext.axi.utils import hexdump_str
class TB(object):
@ -156,8 +155,8 @@ class TB(object):
self.dev.functions[0].msi_multiple_message_capable = 5
self.dev.functions[0].configure_bar(0, 2**22)
self.dev.functions[0].configure_bar(2, 2**22)
self.dev.functions[0].configure_bar(0, 2**len(dut.example_core_pcie_s10_inst.core_pcie_inst.axil_ctrl_awaddr))
self.dev.functions[0].configure_bar(2, 2**len(dut.example_core_pcie_s10_inst.core_pcie_inst.axi_ram_awaddr))
async def init(self):

View File

@ -0,0 +1,19 @@
# Verilog PCIe VCU108 Example Design
## Introduction
This example design targets the Xilinx VCU108 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: xcvu095-ffva2104-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 VCU108 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.

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

View File

@ -0,0 +1 @@
../../common/driver/example/

View File

@ -0,0 +1,262 @@
# XDC constraints for the Xilinx VCU108 board
# part: xcvu095-ffva2104-2-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design]
set_property BITSTREAM.CONFIG.BPI_SYNC_MODE Type1 [current_design]
set_property CONFIG_MODE BPI16 [current_design]
# System clocks
# 300 MHz
#set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p]
#set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n]
#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p]
#set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p]
#set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n]
#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p]
# 125 MHz
#set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p]
#set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n]
#create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p]
# 90 MHz
#set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz]
#create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz]
# LEDs
set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}]
set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}]
set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}]
set_property -dict {LOC AY35 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}]
set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
#set_property -dict {LOC E36 IOSTANDARD LVCMOS12} [get_ports reset]
#set_false_path -from [get_ports {reset}]
#set_input_delay 0 [get_ports {reset}]
# Push buttons
set_property -dict {LOC E34 IOSTANDARD LVCMOS12} [get_ports btnu]
set_property -dict {LOC M22 IOSTANDARD LVCMOS12} [get_ports btnl]
set_property -dict {LOC D9 IOSTANDARD LVCMOS12} [get_ports btnd]
set_property -dict {LOC A10 IOSTANDARD LVCMOS12} [get_ports btnr]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS12} [get_ports btnc]
set_false_path -from [get_ports {btnu btnl btnd btnr btnc}]
set_input_delay 0 [get_ports {btnu btnl btnd btnr btnc}]
# DIP switches
set_property -dict {LOC BC40 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {LOC C37 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {LOC C38 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# PMOD0
#set_property -dict {LOC BC14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[0]}]
#set_property -dict {LOC BA10 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[1]}]
#set_property -dict {LOC AW16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[2]}]
#set_property -dict {LOC BB16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[3]}]
#set_property -dict {LOC BC13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[4]}]
#set_property -dict {LOC BF7 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[5]}]
#set_property -dict {LOC AW12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[6]}]
#set_property -dict {LOC BC16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {pmod0[7]}]
#set_false_path -to [get_ports {pmod0[*]}]
#set_output_delay 0 [get_ports {pmod0[*]}]
# PMOD1
#set_property -dict {LOC P22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[0]}]
#set_property -dict {LOC N22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[1]}]
#set_property -dict {LOC J20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[2]}]
#set_property -dict {LOC K24 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[3]}]
#set_property -dict {LOC J24 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[4]}]
#set_property -dict {LOC T23 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[5]}]
#set_property -dict {LOC R23 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[6]}]
#set_property -dict {LOC R22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {pmod1[7]}]
#set_false_path -to [get_ports {pmod1[*]}]
#set_output_delay 0 [get_ports {pmod1[*]}]
# UART
#set_property -dict {LOC BE24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd]
#set_property -dict {LOC BC24 IOSTANDARD LVCMOS18} [get_ports uart_rxd]
#set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts]
#set_property -dict {LOC BD22 IOSTANDARD LVCMOS18} [get_ports uart_cts]
#set_false_path -to [get_ports {uart_txd uart_rts}]
#set_output_delay 0 [get_ports {uart_txd uart_rts}]
#set_false_path -from [get_ports {uart_rxd uart_cts}]
#set_input_delay 0 [get_ports {uart_rxd uart_cts}]
# Gigabit Ethernet SGMII PHY
#set_property -dict {LOC AR24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_p]
#set_property -dict {LOC AT24 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_rx_n]
#set_property -dict {LOC AR23 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_p]
#set_property -dict {LOC AR22 IOSTANDARD DIFF_HSTL_I_18} [get_ports phy_sgmii_tx_n]
#set_property -dict {LOC AT22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_p]
#set_property -dict {LOC AU22 IOSTANDARD LVDS_25} [get_ports phy_sgmii_clk_n]
#set_property -dict {LOC AU21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_reset_n]
#set_property -dict {LOC AT21 IOSTANDARD LVCMOS18} [get_ports phy_int_n]
#set_property -dict {LOC AV24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdio]
#set_property -dict {LOC AV21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports phy_mdc]
# 625 MHz ref clock from SGMII PHY
#create_clock -period 1.600 -name phy_sgmii_clk [get_ports phy_sgmii_clk_p]
#set_false_path -to [get_ports {phy_reset_n phy_mdio phy_mdc}]
#set_output_delay 0 [get_ports {phy_reset_n phy_mdio phy_mdc}]
#set_false_path -from [get_ports {phy_int_n phy_mdio}]
#set_input_delay 0 [get_ports {phy_int_n phy_mdio}]
# QSFP+ Interface
#set_property -dict {LOC AG45} [get_ports qsfp_rx1_p] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AG46} [get_ports qsfp_rx1_n] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AK42} [get_ports qsfp_tx1_p] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AK43} [get_ports qsfp_tx1_n] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AF43} [get_ports qsfp_rx2_p] ;# MGTYRXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AF44} [get_ports qsfp_rx2_n] ;# MGTYRXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AJ40} [get_ports qsfp_tx2_p] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AJ41} [get_ports qsfp_tx2_n] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AE45} [get_ports qsfp_rx3_p] ;# MGTYRXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AE46} [get_ports qsfp_rx3_n] ;# MGTYRXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AG40} [get_ports qsfp_tx3_p] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AG41} [get_ports qsfp_tx3_n] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AD43} [get_ports qsfp_rx4_p] ;# MGTYRXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AD44} [get_ports qsfp_rx4_n] ;# MGTYRXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AE40} [get_ports qsfp_tx4_p] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AE41} [get_ports qsfp_tx4_n] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC AF38} [get_ports qsfp_mgt_refclk_0_p] ;# MGTREFCLK0P_127 from U32 SI570 via U102 SI53340
#set_property -dict {LOC AF39} [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_127 from U32 SI570 via U102 SI53340
#set_property -dict {LOC AD38} [get_ports qsfp_mgt_refclk_1_p] ;# MGTREFCLK1P_127 from U57 CKOUT2 SI5328
#set_property -dict {LOC AD39} [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_127 from U57 CKOUT2 SI5328
#set_property -dict {LOC AG34 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to U57 CKIN1 SI5328
#set_property -dict {LOC AH35 IOSTANDARD LVDS} [get_ports qsfp_recclk_n] ;# to U57 CKIN1 SI5328
#set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_modsell]
#set_property -dict {LOC AM24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_resetl]
#set_property -dict {LOC AL25 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_modprsl]
#set_property -dict {LOC AL21 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_intl]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_lpmode]
# 156.25 MHz MGT reference clock
#create_clock -period 6.400 -name qsfp_mgt_refclk_0 [get_ports qsfp_mgt_refclk_0_p]
#set_false_path -to [get_ports {qsfp_modsell qsfp_resetl qsfp_lpmode}]
#set_output_delay 0 [get_ports {qsfp_modsell qsfp_resetl qsfp_lpmode}]
#set_false_path -from [get_ports {qsfp_modprsl qsfp_intl}]
#set_input_delay 0 [get_ports {qsfp_modprsl qsfp_intl}]
# I2C interface
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_scl]
#set_property -dict {LOC AP21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports i2c_sda]
#set_false_path -to [get_ports {i2c_sda i2c_scl}]
#set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
#set_false_path -from [get_ports {i2c_sda i2c_scl}]
#set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# PCIe Interface
set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[0]}] ;# MGTHRXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[0]}] ;# MGTHRXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[0]}] ;# MGTHTXP3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[0]}] ;# MGTHTXN3_225 GTHE3_CHANNEL_X0Y7 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[1]}] ;# MGTHRXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[1]}] ;# MGTHRXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AR5 } [get_ports {pcie_tx_p[1]}] ;# MGTHTXP2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AR4 } [get_ports {pcie_tx_n[1]}] ;# MGTHTXN2_225 GTHE3_CHANNEL_X0Y6 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[2]}] ;# MGTHRXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[2]}] ;# MGTHRXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[2]}] ;# MGTHTXP1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[2]}] ;# MGTHTXN1_225 GTHE3_CHANNEL_X0Y5 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[3]}] ;# MGTHRXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[3]}] ;# MGTHRXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AU5 } [get_ports {pcie_tx_p[3]}] ;# MGTHTXP0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AU4 } [get_ports {pcie_tx_n[3]}] ;# MGTHTXN0_225 GTHE3_CHANNEL_X0Y4 / GTHE3_COMMON_X0Y1
set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[4]}] ;# MGTHRXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[4]}] ;# MGTHRXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AW5 } [get_ports {pcie_tx_p[4]}] ;# MGTHTXP3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AW4 } [get_ports {pcie_tx_n[4]}] ;# MGTHTXN3_224 GTHE3_CHANNEL_X0Y3 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[5]}] ;# MGTHRXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[5]}] ;# MGTHRXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BA5 } [get_ports {pcie_tx_p[5]}] ;# MGTHTXP2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BA4 } [get_ports {pcie_tx_n[5]}] ;# MGTHTXN2_224 GTHE3_CHANNEL_X0Y2 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AY2 } [get_ports {pcie_rx_p[6]}] ;# MGTHRXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AY1 } [get_ports {pcie_rx_n[6]}] ;# MGTHRXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BC5 } [get_ports {pcie_tx_p[6]}] ;# MGTHTXP1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BC4 } [get_ports {pcie_tx_n[6]}] ;# MGTHTXN1_224 GTHE3_CHANNEL_X0Y1 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BB2 } [get_ports {pcie_rx_p[7]}] ;# MGTHRXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BB1 } [get_ports {pcie_rx_n[7]}] ;# MGTHRXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BE5 } [get_ports {pcie_tx_p[7]}] ;# MGTHTXP0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
set_property -dict {LOC BE4 } [get_ports {pcie_tx_n[7]}] ;# MGTHTXN0_224 GTHE3_CHANNEL_X0Y0 / GTHE3_COMMON_X0Y0
set_property -dict {LOC AL9 } [get_ports pcie_mgt_refclk_p] ;# MGTREFCLK0P_225
set_property -dict {LOC AL8 } [get_ports pcie_mgt_refclk_n] ;# MGTREFCLK0N_225
set_property -dict {LOC AM17 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_mgt_refclk_p]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# BPI flash
#set_property -dict {LOC AM19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[4]}]
#set_property -dict {LOC AM18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[5]}]
#set_property -dict {LOC AN20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[6]}]
#set_property -dict {LOC AP20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[7]}]
#set_property -dict {LOC AN19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[8]}]
#set_property -dict {LOC AN18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[9]}]
#set_property -dict {LOC AR18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[10]}]
#set_property -dict {LOC AR17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[11]}]
#set_property -dict {LOC AT20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[12]}]
#set_property -dict {LOC AT19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[13]}]
#set_property -dict {LOC AT17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[14]}]
#set_property -dict {LOC AU17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_dq[15]}]
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[0]}]
#set_property -dict {LOC AR19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[1]}]
#set_property -dict {LOC AV20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[2]}]
#set_property -dict {LOC AW20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[3]}]
#set_property -dict {LOC AU19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[4]}]
#set_property -dict {LOC AU18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[5]}]
#set_property -dict {LOC AV19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[6]}]
#set_property -dict {LOC AV18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[7]}]
#set_property -dict {LOC AW18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[8]}]
#set_property -dict {LOC AY18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[9]}]
#set_property -dict {LOC AY19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[10]}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[11]}]
#set_property -dict {LOC BA17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[12]}]
#set_property -dict {LOC BB17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[13]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[14]}]
#set_property -dict {LOC BC19 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[15]}]
#set_property -dict {LOC BB18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[16]}]
#set_property -dict {LOC BC18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[17]}]
#set_property -dict {LOC AY20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[18]}]
#set_property -dict {LOC BA20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[19]}]
#set_property -dict {LOC BD18 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[20]}]
#set_property -dict {LOC BD17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[21]}]
#set_property -dict {LOC BC20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[22]}]
#set_property -dict {LOC BD20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_addr[23]}]
#set_property -dict {LOC BE20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_region[0]}]
#set_property -dict {LOC BF20 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_region[1]}]
#set_property -dict {LOC BF17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_oe_n}]
#set_property -dict {LOC BF16 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_we_n}]
#set_property -dict {LOC AW17 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {flash_adv_n}]
#set_property -dict {LOC BC23 IOSTANDARD LVCMOS18} [get_ports {flash_wait}]
#set_false_path -to [get_ports {flash_dq[*] flash_addr[*] flash_region[*] flash_oe_n flash_we_n flash_adv_n}]
#set_output_delay 0 [get_ports {flash_dq[*] flash_addr[*] flash_region[*] flash_oe_n flash_we_n flash_adv_n}]
#set_false_path -from [get_ports {flash_dq[*] flash_wait}]
#set_input_delay 0 [get_ports {flash_dq[*] flash_wait}]

View File

@ -0,0 +1,95 @@
# FPGA settings
FPGA_PART = xcvu095-ffva2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = VirtexUltrascale
# Files for synthesis
SYN_FILES = rtl/fpga.v
SYN_FILES += rtl/fpga_core.v
SYN_FILES += rtl/debounce_switch.v
SYN_FILES += rtl/sync_reset.v
SYN_FILES += rtl/sync_signal.v
SYN_FILES += 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/pcie3_ultrascale_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 BPIx16 -loadbit {up 0x0000000 $*.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 {mt28gu01gaax1e-bpi-x16}] 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.BPI_RS_PINS {25:24} [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

View File

@ -0,0 +1,31 @@
create_ip -name pcie3_ultrascale -vendor xilinx.com -library ip -module_name pcie3_ultrascale_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \
CONFIG.AXISTEN_IF_RC_STRADDLE {false} \
CONFIG.axisten_if_width {256_bit} \
CONFIG.extended_tag_field {true} \
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 {806c} \
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.PF0_INTERRUPT_PIN {NONE} \
CONFIG.PF0_MSIX_CAP_TABLE_BIR {BAR_0} \
CONFIG.PF0_MSIX_CAP_PBA_BIR {BAR_0} \
CONFIG.vendor_id {1234} \
CONFIG.en_msi_per_vec_masking {true} \
] [get_ips pcie3_ultrascale_0]

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More