mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
Add example design for DE10-Agilex
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
c5382f5e7f
commit
dbcd211ce1
19
example/DE10_Agilex/fpga/README.md
Normal file
19
example/DE10_Agilex/fpga/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Verilog PCIe Terasic DE10-Agilex Example Design
|
||||
|
||||
## Introduction
|
||||
|
||||
This example design targets the Terasic DE10-Agilex.
|
||||
|
||||
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: AGFB014R24B2E2V
|
||||
|
||||
## How to build
|
||||
|
||||
Run `make` to build. Ensure that the Intel Quartus Pro 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 DE10-Agilex with Quartus Pro. Then load the driver with `insmod example.ko`. Check dmesg for the output.
|
179
example/DE10_Agilex/fpga/common/quartus_pro.mk
Normal file
179
example/DE10_Agilex/fpga/common/quartus_pro.mk
Normal file
@ -0,0 +1,179 @@
|
||||
###################################################################
|
||||
#
|
||||
# Makefile for Intel Quartus Prime Pro
|
||||
#
|
||||
# Alex Forencich
|
||||
#
|
||||
###################################################################
|
||||
#
|
||||
# Parameters:
|
||||
# FPGA_TOP - Top module name
|
||||
# FPGA_FAMILY - FPGA family (e.g. Stratix 10 DX)
|
||||
# FPGA_DEVICE - FPGA device (e.g. 1SD280PT2F55E1VG)
|
||||
# SYN_FILES - space-separated list of source files
|
||||
# IP_FILES - space-separated list of IP files
|
||||
# IP_TCL_FILES - space-separated list of TCL files for qsys-script
|
||||
# QSF_FILES - space-separated list of settings files
|
||||
# SDC_FILES - space-separated list of timing constraint files
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# FPGA_TOP = fpga
|
||||
# FPGA_FAMILY = "Stratix 10 DX"
|
||||
# FPGA_DEVICE = 1SD280PT2F55E1VG
|
||||
# SYN_FILES = rtl/fpga.v
|
||||
# QSF_FILES = fpga.qsf
|
||||
# SDC_FILES = fpga.sdc
|
||||
# include ../common/quartus_pro.mk
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# phony targets
|
||||
.PHONY: clean fpga
|
||||
|
||||
# output files to hang on to
|
||||
.PRECIOUS: %.sof %.ipregen.rpt %.syn.rpt %.fit.rpt %.asm.rpt %.sta.rpt
|
||||
.SECONDARY:
|
||||
|
||||
# any project specific settings
|
||||
CONFIG ?= config.mk
|
||||
-include ../$(CONFIG)
|
||||
|
||||
SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES))
|
||||
|
||||
IP_FILES_REL = $(patsubst %, ../%, $(IP_FILES))
|
||||
IP_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_FILES)))
|
||||
|
||||
IP_TCL_FILES_REL = $(patsubst %, ../%, $(IP_TCL_FILES))
|
||||
IP_TCL_FILES_INT = $(patsubst %, ip/%, $(notdir $(IP_TCL_FILES)))
|
||||
IP_TCL_FILES_IP_INT = $(patsubst %.tcl, ip/%.ip, $(notdir $(IP_TCL_FILES)))
|
||||
|
||||
ifdef QSF_FILES
|
||||
QSF_FILES_REL = $(patsubst %, ../%, $(QSF_FILES))
|
||||
else
|
||||
QSF_FILES_REL = ../$(FPGA_TOP).qsf
|
||||
endif
|
||||
|
||||
SDC_FILES_REL = $(patsubst %, ../%, $(SDC_FILES))
|
||||
|
||||
ASSIGNMENT_FILES = $(FPGA_TOP).qpf $(FPGA_TOP).qsf
|
||||
|
||||
###################################################################
|
||||
# Main Targets
|
||||
#
|
||||
# all: build everything
|
||||
# clean: remove output files and database
|
||||
###################################################################
|
||||
|
||||
all: fpga
|
||||
|
||||
fpga: $(FPGA_TOP).sof
|
||||
|
||||
quartus: $(FPGA_TOP).qpf
|
||||
quartus $(FPGA_TOP).qpf
|
||||
|
||||
tmpclean:
|
||||
-rm -rf defines.v
|
||||
-rm -rf *.rpt *.summary *.done *.smsg *.chg smart.log *.htm *.eqn *.pin *.qsf *.qpf *.sld *.txt *.qws *.stp
|
||||
-rm -rf ip db qdb incremental_db reconfig_mif tmp-clearbox synth_dumps .qsys_edit
|
||||
|
||||
clean: tmpclean
|
||||
-rm -rf *.sof *.pof *.jdi *.jic *.map
|
||||
|
||||
distclean: clean
|
||||
-rm -rf rev
|
||||
|
||||
syn: smart.log output_files/$(PROJECT).syn.rpt
|
||||
fit: smart.log output_files/$(PROJECT).fit.rpt
|
||||
asm: smart.log output_files/$(PROJECT).asm.rpt
|
||||
sta: smart.log output_files/$(PROJECT).sta.rpt
|
||||
smart: smart.log
|
||||
|
||||
###################################################################
|
||||
# Executable Configuration
|
||||
###################################################################
|
||||
|
||||
IP_ARGS = --run_default_mode_op
|
||||
SYN_ARGS = --read_settings_files=on --write_settings_files=off
|
||||
FIT_ARGS = --read_settings_files=on --write_settings_files=off
|
||||
ASM_ARGS = --read_settings_files=on --write_settings_files=off
|
||||
STA_ARGS =
|
||||
|
||||
###################################################################
|
||||
# Target implementations
|
||||
###################################################################
|
||||
|
||||
STAMP = echo done >
|
||||
|
||||
define COPY_IP_RULE
|
||||
$(patsubst %, ip/%, $(notdir $(1))): $(1)
|
||||
@mkdir -p ip
|
||||
@cp -pv $(1) ip/
|
||||
endef
|
||||
$(foreach l,$(IP_FILES_REL) $(IP_TCL_FILES_REL),$(eval $(call COPY_IP_RULE,$(l))))
|
||||
|
||||
define TCL_IP_GEN_RULE
|
||||
$(patsubst %.tcl, %.ip, $(1)): $(1)
|
||||
cd ip && qsys-script --script=$(notdir $(1))
|
||||
endef
|
||||
$(foreach l,$(IP_TCL_FILES_INT),$(eval $(call TCL_IP_GEN_RULE,$(l))))
|
||||
|
||||
%.ipregen.rpt: $(FPGA_TOP).qpf $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT)
|
||||
quartus_ipgenerate $(IP_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.syn.rpt: syn.chg %.ipregen.rpt $(SYN_FILES_REL)
|
||||
quartus_syn $(SYN_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.fit.rpt: fit.chg %.syn.rpt $(SDC_FILES_REL)
|
||||
quartus_fit $(FIT_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.sta.rpt: sta.chg %.fit.rpt
|
||||
quartus_sta $(STA_ARGS) $(FPGA_TOP)
|
||||
|
||||
%.asm.rpt: asm.chg %.sta.rpt
|
||||
quartus_asm $(ASM_ARGS) $(FPGA_TOP)
|
||||
mkdir -p rev
|
||||
EXT=sof; COUNT=100; \
|
||||
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
|
||||
do let COUNT=COUNT+1; done; \
|
||||
cp $*.$$EXT rev/$*_rev$$COUNT.$$EXT; \
|
||||
echo "Output: rev/$*_rev$$COUNT.$$EXT";
|
||||
|
||||
%.sof: smart.log %.asm.rpt
|
||||
|
||||
|
||||
smart.log: $(ASSIGNMENT_FILES)
|
||||
quartus_sh --determine_smart_action $(FPGA_TOP) > smart.log
|
||||
|
||||
###################################################################
|
||||
# Project initialization
|
||||
###################################################################
|
||||
|
||||
$(ASSIGNMENT_FILES): $(QSF_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT)
|
||||
rm -f $(FPGA_TOP).qsf
|
||||
quartus_sh --prepare -f $(FPGA_FAMILY) -d $(FPGA_DEVICE) -t $(FPGA_TOP) $(FPGA_TOP)
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo "# Source files" >> $(FPGA_TOP).qsf
|
||||
for x in $(SYN_FILES_REL) $(IP_FILES_INT) $(IP_TCL_FILES_IP_INT); do \
|
||||
case $${x##*.} in \
|
||||
v|V) echo set_global_assignment -name VERILOG_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
vhd|VHD) echo set_global_assignment -name VHDL_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
qip|QIP) echo set_global_assignment -name QIP_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
ip|IP) echo set_global_assignment -name IP_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
*) echo set_global_assignment -name SOURCE_FILE $$x >> $(FPGA_TOP).qsf ;;\
|
||||
esac; \
|
||||
done
|
||||
echo >> $(FPGA_TOP).qsf
|
||||
echo "# SDC files" >> $(FPGA_TOP).qsf
|
||||
for x in $(SDC_FILES_REL); do echo set_global_assignment -name SDC_FILE $$x >> $(FPGA_TOP).qsf; done
|
||||
for x in $(QSF_FILES_REL); do printf "\n#\n# Included QSF file $$x\n#\n" >> $(FPGA_TOP).qsf; cat $$x >> $(FPGA_TOP).qsf; done
|
||||
|
||||
syn.chg:
|
||||
$(STAMP) syn.chg
|
||||
fit.chg:
|
||||
$(STAMP) fit.chg
|
||||
sta.chg:
|
||||
$(STAMP) sta.chg
|
||||
asm.chg:
|
||||
$(STAMP) asm.chg
|
1579
example/DE10_Agilex/fpga/fpga.qsf
Normal file
1579
example/DE10_Agilex/fpga/fpga.qsf
Normal file
File diff suppressed because it is too large
Load Diff
58
example/DE10_Agilex/fpga/fpga.sdc
Normal file
58
example/DE10_Agilex/fpga/fpga.sdc
Normal file
@ -0,0 +1,58 @@
|
||||
# Timing constraints for the Terasic DE10-Agilex FPGA development board
|
||||
|
||||
set_time_format -unit ns -decimal_places 3
|
||||
|
||||
# Clock constraints
|
||||
create_clock -period 10.000 -name {clk_100_b2a} [ get_ports {clk_100_b2a} ]
|
||||
create_clock -period 20.000 -name {clk_50_b3a} [ get_ports {clk_50_b3a} ]
|
||||
create_clock -period 20.000 -name {clk_50_b3c} [ get_ports {clk_50_b3c} ]
|
||||
create_clock -period 32.552 -name {clk_30m72} [ get_ports {clk_30m72} ]
|
||||
create_clock -period 20.000 -name {clk_from_si5397a_0} [ get_ports {clk_from_si5397a_p[0]} ]
|
||||
create_clock -period 20.000 -name {clk_from_si5397a_1} [ get_ports {clk_from_si5397a_p[1]} ]
|
||||
|
||||
create_clock -period 10.000 -name {pcie_refclk_0} [ get_ports {pcie_refclk_p[0]} ]
|
||||
create_clock -period 10.000 -name {pcie_refclk_1} [ get_ports {pcie_refclk_p[1]} ]
|
||||
|
||||
create_clock -period 6.400 -name {qsfpdda_refclk} [ get_ports {qsfpdda_refclk_p} ]
|
||||
create_clock -period 6.400 -name {qsfpddb_refclk} [ get_ports {qsfpddb_refclk_p} ]
|
||||
create_clock -period 6.400 -name {qsfpddrsv_refclk} [ get_ports {qsfpddrsv_refclk_p} ]
|
||||
|
||||
create_clock -period 30.000 -name {ddr4a_refclk} [ get_ports {ddr4a_refclk_p} ]
|
||||
create_clock -period 30.000 -name {ddr4b_refclk} [ get_ports {ddr4b_refclk_p} ]
|
||||
create_clock -period 30.000 -name {ddr4c_refclk} [ get_ports {ddr4c_refclk_p} ]
|
||||
create_clock -period 30.000 -name {ddr4d_refclk} [ get_ports {ddr4d_refclk_p} ]
|
||||
|
||||
derive_clock_uncertainty
|
||||
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_100_b2a} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_50_b3a} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_50_b3c} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_30m72} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_from_si5397a_0} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {clk_from_si5397a_1} ]
|
||||
|
||||
set_clock_groups -asynchronous -group [ get_clocks {pcie_refclk_0} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {pcie_refclk_1} ]
|
||||
|
||||
set_clock_groups -asynchronous -group [ get_clocks {qsfpdda_refclk} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {qsfpddb_refclk} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {qsfpddrsv_refclk} ]
|
||||
|
||||
set_clock_groups -asynchronous -group [ get_clocks {ddr4a_refclk} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {ddr4b_refclk} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {ddr4c_refclk} ]
|
||||
set_clock_groups -asynchronous -group [ get_clocks {ddr4d_refclk} ]
|
||||
|
||||
# JTAG constraints
|
||||
# create_clock -name {altera_reserved_tck} -period 40.800 {altera_reserved_tck}
|
||||
|
||||
# set_clock_groups -asynchronous -group [get_clocks {altera_reserved_tck}]
|
||||
|
||||
# IO constraints
|
||||
set_false_path -from "cpu_resetn"
|
||||
set_false_path -from "button[*]"
|
||||
set_false_path -from "sw[*]"
|
||||
set_false_path -to "led[*]"
|
||||
set_false_path -to "led_bracket[*]"
|
||||
|
||||
set_false_path -from "pcie_perst_n"
|
51
example/DE10_Agilex/fpga/fpga_24AR0/Makefile
Normal file
51
example/DE10_Agilex/fpga/fpga_24AR0/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
# FPGA settings
|
||||
FPGA_TOP = fpga
|
||||
FPGA_FAMILY = "Agilex"
|
||||
FPGA_DEVICE = AGFB014R24A2E2VR0
|
||||
|
||||
# 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_ptile.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_ptile_if.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_if_rx.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_if_tx.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_cfg.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/pcie_tlp_fifo.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo_raw.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo_mux.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_msix.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/priority_encoder.v
|
||||
SYN_FILES += lib/pcie/rtl/pulse_merge.v
|
||||
|
||||
# IP files
|
||||
IP_TCL_FILES += ip/reset_release.tcl
|
||||
IP_TCL_FILES += ip/pcie.tcl
|
||||
|
||||
# QSF files
|
||||
QSF_FILES = fpga.qsf
|
||||
|
||||
# SDC files
|
||||
SDC_FILES = fpga.sdc
|
||||
|
||||
include ../common/quartus_pro.mk
|
||||
|
||||
program: fpga
|
||||
quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof@1"
|
51
example/DE10_Agilex/fpga/fpga_24B/Makefile
Normal file
51
example/DE10_Agilex/fpga/fpga_24B/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
# FPGA settings
|
||||
FPGA_TOP = fpga
|
||||
FPGA_FAMILY = "Agilex"
|
||||
FPGA_DEVICE = AGFB014R24B2E2V
|
||||
|
||||
# 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_ptile.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_ptile_if.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_if_rx.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_if_tx.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_ptile_cfg.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/pcie_tlp_fifo.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo_raw.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo_mux.v
|
||||
SYN_FILES += lib/pcie/rtl/pcie_msix.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/priority_encoder.v
|
||||
SYN_FILES += lib/pcie/rtl/pulse_merge.v
|
||||
|
||||
# IP files
|
||||
IP_TCL_FILES += ip/reset_release.tcl
|
||||
IP_TCL_FILES += ip/pcie.tcl
|
||||
|
||||
# QSF files
|
||||
QSF_FILES = fpga.qsf
|
||||
|
||||
# SDC files
|
||||
SDC_FILES = fpga.sdc
|
||||
|
||||
include ../common/quartus_pro.mk
|
||||
|
||||
program: fpga
|
||||
quartus_pgm --no_banner --mode=jtag -o "P;$(FPGA_TOP).sof@1"
|
2294
example/DE10_Agilex/fpga/ip/pcie.tcl
Normal file
2294
example/DE10_Agilex/fpga/ip/pcie.tcl
Normal file
File diff suppressed because it is too large
Load Diff
52
example/DE10_Agilex/fpga/ip/reset_release.tcl
Normal file
52
example/DE10_Agilex/fpga/ip/reset_release.tcl
Normal file
@ -0,0 +1,52 @@
|
||||
package require -exact qsys 21.3
|
||||
|
||||
# create the system "reset_release"
|
||||
proc do_create_reset_release {} {
|
||||
# create the system
|
||||
create_system reset_release
|
||||
set_project_property DEVICE {AGFB014R24B2E2V}
|
||||
set_project_property DEVICE_FAMILY {Agilex}
|
||||
set_project_property HIDE_FROM_IP_CATALOG {true}
|
||||
set_use_testbench_naming_pattern 0 {}
|
||||
|
||||
# add HDL parameters
|
||||
|
||||
# add the components
|
||||
add_instance s10_user_rst_clkgate_0 altera_s10_user_rst_clkgate
|
||||
set_instance_parameter_value s10_user_rst_clkgate_0 {outputType} {Conduit Interface}
|
||||
set_instance_property s10_user_rst_clkgate_0 AUTO_EXPORT true
|
||||
|
||||
# add wirelevel expressions
|
||||
|
||||
# preserve ports for debug
|
||||
|
||||
# add the exports
|
||||
set_interface_property ninit_done EXPORT_OF s10_user_rst_clkgate_0.ninit_done
|
||||
|
||||
# set values for exposed HDL parameters
|
||||
|
||||
# set the the module properties
|
||||
set_module_property BONUS_DATA {<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bonusData>
|
||||
<element __value="s10_user_rst_clkgate_0">
|
||||
<datum __value="_sortIndex" value="0" type="int" />
|
||||
</element>
|
||||
</bonusData>
|
||||
}
|
||||
set_module_property FILE {reset_release.ip}
|
||||
set_module_property GENERATION_ID {0x00000000}
|
||||
set_module_property NAME {reset_release}
|
||||
|
||||
# save the system
|
||||
sync_sysinfo_parameters
|
||||
save_system reset_release
|
||||
}
|
||||
|
||||
proc do_set_exported_interface_sysinfo_parameters {} {
|
||||
}
|
||||
|
||||
# create all the systems, from bottom up
|
||||
do_create_reset_release
|
||||
|
||||
# set system info parameters on exported interface, from bottom up
|
||||
do_set_exported_interface_sysinfo_parameters
|
1
example/DE10_Agilex/fpga/lib/pcie
Symbolic link
1
example/DE10_Agilex/fpga/lib/pcie
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../
|
1
example/DE10_Agilex/fpga/rtl/common
Symbolic link
1
example/DE10_Agilex/fpga/rtl/common
Symbolic link
@ -0,0 +1 @@
|
||||
../lib/pcie/example/common/rtl/
|
93
example/DE10_Agilex/fpga/rtl/debounce_switch.v
Normal file
93
example/DE10_Agilex/fpga/rtl/debounce_switch.v
Normal 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
|
331
example/DE10_Agilex/fpga/rtl/fpga.v
Normal file
331
example/DE10_Agilex/fpga/rtl/fpga.v
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2022 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 (
|
||||
/*
|
||||
* Clock: 50 MHz, 100 MHz
|
||||
* Reset: Push button, active low
|
||||
*/
|
||||
// input wire clk_100_b2a,
|
||||
// input wire clk_50_b3a,
|
||||
// input wire clk_50_b3c,
|
||||
// input wire cpu_reset_n,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
input wire [1:0] button,
|
||||
input wire [1:0] sw,
|
||||
output wire [3:0] led,
|
||||
output wire [3:0] led_bracket,
|
||||
|
||||
/*
|
||||
* PCIe: gen 4 x16
|
||||
*/
|
||||
output wire [15:0] pcie_tx_p,
|
||||
output wire [15:0] pcie_tx_n,
|
||||
input wire [15:0] pcie_rx_p,
|
||||
input wire [15:0] pcie_rx_n,
|
||||
input wire [1:0] pcie_refclk_p,
|
||||
input wire pcie_perst_n,
|
||||
|
||||
/*
|
||||
* Ethernet: QSFP-DD
|
||||
*/
|
||||
// output wire [7:0] qsfpdda_tx_p,
|
||||
// output wire [7:0] qsfpdda_tx_n,
|
||||
// input wire [7:0] qsfpdda_rx_p,
|
||||
// input wire [7:0] qsfpdda_rx_n,
|
||||
// output wire [7:0] qsfpddb_tx_p,
|
||||
// output wire [7:0] qsfpddb_tx_n,
|
||||
// input wire [7:0] qsfpddb_rx_p,
|
||||
// input wire [7:0] qsfpddb_rx_n,
|
||||
input wire qsfpdda_refclk_p
|
||||
// input wire qsfpddb_refclk_p,
|
||||
// input wire qsfpddrsv_refclk_p,
|
||||
// output wire qsfpdda_initmode,
|
||||
// input wire qsfpdda_interrupt_n,
|
||||
// input wire qsfpdda_mod_prs_n,
|
||||
// output wire qsfpdda_mod_sel_n,
|
||||
// output wire qsfpdda_rst_n,
|
||||
// inout wire qsfpdda_scl,
|
||||
// inout wire qsfpdda_sda,
|
||||
// output wire qsfpddb_initmode,
|
||||
// input wire qsfpddb_interrupt_n,
|
||||
// input wire qsfpddb_mod_prs_n,
|
||||
// output wire qsfpddb_mod_sel_n,
|
||||
// output wire qsfpddb_rst_n,
|
||||
// inout wire qsfpddb_scl,
|
||||
// inout wire qsfpddb_sda
|
||||
);
|
||||
|
||||
parameter SEG_COUNT = 2;
|
||||
parameter SEG_DATA_WIDTH = 256;
|
||||
parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32);
|
||||
parameter SEG_HDR_WIDTH = 128;
|
||||
parameter SEG_PRFX_WIDTH = 32;
|
||||
|
||||
parameter TX_SEQ_NUM_WIDTH = 6;
|
||||
|
||||
parameter PCIE_TAG_COUNT = 256;
|
||||
parameter BAR0_APERTURE = 24;
|
||||
parameter BAR2_APERTURE = 24;
|
||||
parameter BAR4_APERTURE = 16;
|
||||
|
||||
// Clock and reset
|
||||
|
||||
wire ninit_done;
|
||||
|
||||
reset_release reset_release_inst (
|
||||
.ninit_done (ninit_done)
|
||||
);
|
||||
|
||||
// wire clk_100mhz = clk_sys_100m_p;
|
||||
// wire rst_100mhz;
|
||||
|
||||
// sync_reset #(
|
||||
// .N(20)
|
||||
// )
|
||||
// sync_reset_100mhz_inst (
|
||||
// .clk(clk_100mhz),
|
||||
// .rst(!cpu_resetn || ninit_done),
|
||||
// .out(rst_100mhz)
|
||||
// );
|
||||
|
||||
wire coreclkout_hip;
|
||||
wire reset_status_n;
|
||||
|
||||
wire clk = coreclkout_hip;
|
||||
wire rst = !reset_status_n;
|
||||
|
||||
wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data;
|
||||
wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty;
|
||||
wire [SEG_COUNT-1:0] rx_st_sop;
|
||||
wire [SEG_COUNT-1:0] rx_st_eop;
|
||||
wire [SEG_COUNT-1:0] rx_st_valid;
|
||||
wire rx_st_ready;
|
||||
wire [SEG_COUNT*SEG_HDR_WIDTH-1:0] rx_st_hdr;
|
||||
wire [SEG_COUNT*SEG_PRFX_WIDTH-1:0] rx_st_tlp_prfx;
|
||||
wire [SEG_COUNT-1:0] rx_st_vf_active = 0;
|
||||
wire [SEG_COUNT*3-1:0] rx_st_func_num = 0;
|
||||
wire [SEG_COUNT*11-1:0] rx_st_vf_num = 0;
|
||||
wire [SEG_COUNT*3-1:0] rx_st_bar_range;
|
||||
wire [SEG_COUNT-1:0] rx_st_tlp_abort;
|
||||
|
||||
wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data;
|
||||
wire [SEG_COUNT-1:0] tx_st_sop;
|
||||
wire [SEG_COUNT-1:0] tx_st_eop;
|
||||
wire [SEG_COUNT-1:0] tx_st_valid;
|
||||
wire tx_st_ready;
|
||||
wire [SEG_COUNT-1:0] tx_st_err;
|
||||
wire [SEG_COUNT*SEG_HDR_WIDTH-1:0] tx_st_hdr;
|
||||
wire [SEG_COUNT*SEG_PRFX_WIDTH-1:0] tx_st_tlp_prfx;
|
||||
|
||||
wire [11:0] rx_buffer_limit;
|
||||
wire [1:0] rx_buffer_limit_tdm_idx;
|
||||
|
||||
wire [15:0] tx_cdts_limit;
|
||||
wire [2:0] tx_cdts_limit_tdm_idx;
|
||||
|
||||
wire [15:0] tl_cfg_ctl;
|
||||
wire [4:0] tl_cfg_add;
|
||||
wire [2:0] tl_cfg_func;
|
||||
|
||||
pcie (
|
||||
.p0_rx_st_ready_i(rx_st_ready),
|
||||
.p0_rx_st_sop_o(rx_st_sop),
|
||||
.p0_rx_st_eop_o(rx_st_eop),
|
||||
.p0_rx_st_data_o(rx_st_data),
|
||||
.p0_rx_st_valid_o(rx_st_valid),
|
||||
.p0_rx_st_empty_o(rx_st_empty),
|
||||
.p0_rx_st_hdr_o(rx_st_hdr),
|
||||
.p0_rx_st_tlp_prfx_o(rx_st_tlp_prfx),
|
||||
.p0_rx_st_bar_range_o(rx_st_bar_range),
|
||||
.p0_rx_st_tlp_abort_o(rx_st_tlp_abort),
|
||||
.p0_rx_par_err_o(),
|
||||
.p0_tx_st_sop_i(tx_st_sop),
|
||||
.p0_tx_st_eop_i(tx_st_eop),
|
||||
.p0_tx_st_data_i(tx_st_data),
|
||||
.p0_tx_st_valid_i(tx_st_valid),
|
||||
.p0_tx_st_err_i(tx_st_err),
|
||||
.p0_tx_st_ready_o(tx_st_ready),
|
||||
.p0_tx_st_hdr_i(tx_st_hdr),
|
||||
.p0_tx_st_tlp_prfx_i(tx_st_tlp_prfx),
|
||||
.p0_tx_par_err_o(),
|
||||
.p0_tx_cdts_limit_o(tx_cdts_limit),
|
||||
.p0_tx_cdts_limit_tdm_idx_o(tx_cdts_limit_tdm_idx),
|
||||
.p0_tl_cfg_func_o(tl_cfg_func),
|
||||
.p0_tl_cfg_add_o(tl_cfg_add),
|
||||
.p0_tl_cfg_ctl_o(tl_cfg_ctl),
|
||||
.p0_dl_timer_update_o(),
|
||||
.p0_reset_status_n(reset_status_n),
|
||||
.p0_pin_perst_n(),
|
||||
.p0_link_up_o(),
|
||||
.p0_dl_up_o(),
|
||||
.p0_surprise_down_err_o(),
|
||||
.p0_ltssm_state_o(),
|
||||
.rx_n_in0(pcie_rx_n[0]),
|
||||
.rx_n_in1(pcie_rx_n[1]),
|
||||
.rx_n_in2(pcie_rx_n[2]),
|
||||
.rx_n_in3(pcie_rx_n[3]),
|
||||
.rx_n_in4(pcie_rx_n[4]),
|
||||
.rx_n_in5(pcie_rx_n[5]),
|
||||
.rx_n_in6(pcie_rx_n[6]),
|
||||
.rx_n_in7(pcie_rx_n[7]),
|
||||
.rx_n_in8(pcie_rx_n[8]),
|
||||
.rx_n_in9(pcie_rx_n[9]),
|
||||
.rx_n_in10(pcie_rx_n[10]),
|
||||
.rx_n_in11(pcie_rx_n[11]),
|
||||
.rx_n_in12(pcie_rx_n[12]),
|
||||
.rx_n_in13(pcie_rx_n[13]),
|
||||
.rx_n_in14(pcie_rx_n[14]),
|
||||
.rx_n_in15(pcie_rx_n[15]),
|
||||
.rx_p_in0(pcie_rx_p[0]),
|
||||
.rx_p_in1(pcie_rx_p[1]),
|
||||
.rx_p_in2(pcie_rx_p[2]),
|
||||
.rx_p_in3(pcie_rx_p[3]),
|
||||
.rx_p_in4(pcie_rx_p[4]),
|
||||
.rx_p_in5(pcie_rx_p[5]),
|
||||
.rx_p_in6(pcie_rx_p[6]),
|
||||
.rx_p_in7(pcie_rx_p[7]),
|
||||
.rx_p_in8(pcie_rx_p[8]),
|
||||
.rx_p_in9(pcie_rx_p[9]),
|
||||
.rx_p_in10(pcie_rx_p[10]),
|
||||
.rx_p_in11(pcie_rx_p[11]),
|
||||
.rx_p_in12(pcie_rx_p[12]),
|
||||
.rx_p_in13(pcie_rx_p[13]),
|
||||
.rx_p_in14(pcie_rx_p[14]),
|
||||
.rx_p_in15(pcie_rx_p[15]),
|
||||
.tx_n_out0(pcie_tx_n[0]),
|
||||
.tx_n_out1(pcie_tx_n[1]),
|
||||
.tx_n_out2(pcie_tx_n[2]),
|
||||
.tx_n_out3(pcie_tx_n[3]),
|
||||
.tx_n_out4(pcie_tx_n[4]),
|
||||
.tx_n_out5(pcie_tx_n[5]),
|
||||
.tx_n_out6(pcie_tx_n[6]),
|
||||
.tx_n_out7(pcie_tx_n[7]),
|
||||
.tx_n_out8(pcie_tx_n[8]),
|
||||
.tx_n_out9(pcie_tx_n[9]),
|
||||
.tx_n_out10(pcie_tx_n[10]),
|
||||
.tx_n_out11(pcie_tx_n[11]),
|
||||
.tx_n_out12(pcie_tx_n[12]),
|
||||
.tx_n_out13(pcie_tx_n[13]),
|
||||
.tx_n_out14(pcie_tx_n[14]),
|
||||
.tx_n_out15(pcie_tx_n[15]),
|
||||
.tx_p_out0(pcie_tx_p[0]),
|
||||
.tx_p_out1(pcie_tx_p[1]),
|
||||
.tx_p_out2(pcie_tx_p[2]),
|
||||
.tx_p_out3(pcie_tx_p[3]),
|
||||
.tx_p_out4(pcie_tx_p[4]),
|
||||
.tx_p_out5(pcie_tx_p[5]),
|
||||
.tx_p_out6(pcie_tx_p[6]),
|
||||
.tx_p_out7(pcie_tx_p[7]),
|
||||
.tx_p_out8(pcie_tx_p[8]),
|
||||
.tx_p_out9(pcie_tx_p[9]),
|
||||
.tx_p_out10(pcie_tx_p[10]),
|
||||
.tx_p_out11(pcie_tx_p[11]),
|
||||
.tx_p_out12(pcie_tx_p[12]),
|
||||
.tx_p_out13(pcie_tx_p[13]),
|
||||
.tx_p_out14(pcie_tx_p[14]),
|
||||
.tx_p_out15(pcie_tx_p[15]),
|
||||
.coreclkout_hip(coreclkout_hip),
|
||||
.refclk0(pcie_refclk_p[0]),
|
||||
.refclk1(pcie_refclk_p[1]),
|
||||
.pin_perst_n(pcie_perst_n),
|
||||
.ninit_done(ninit_done)
|
||||
);
|
||||
|
||||
fpga_core #(
|
||||
.SEG_COUNT(SEG_COUNT),
|
||||
.SEG_DATA_WIDTH(SEG_DATA_WIDTH),
|
||||
.SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH),
|
||||
.SEG_HDR_WIDTH(SEG_HDR_WIDTH),
|
||||
.SEG_PRFX_WIDTH(SEG_PRFX_WIDTH),
|
||||
.TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH),
|
||||
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
|
||||
.BAR0_APERTURE(BAR0_APERTURE),
|
||||
.BAR2_APERTURE(BAR2_APERTURE),
|
||||
.BAR4_APERTURE(BAR4_APERTURE)
|
||||
)
|
||||
fpga_core_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
.button(button),
|
||||
.sw(sw),
|
||||
.led(led),
|
||||
.led_bracket(led_bracket),
|
||||
|
||||
/*
|
||||
* P-Tile RX AVST interface
|
||||
*/
|
||||
.rx_st_data(rx_st_data),
|
||||
.rx_st_empty(rx_st_empty),
|
||||
.rx_st_sop(rx_st_sop),
|
||||
.rx_st_eop(rx_st_eop),
|
||||
.rx_st_valid(rx_st_valid),
|
||||
.rx_st_ready(rx_st_ready),
|
||||
.rx_st_hdr(rx_st_hdr),
|
||||
.rx_st_tlp_prfx(rx_st_tlp_prfx),
|
||||
.rx_st_vf_active(rx_st_vf_active),
|
||||
.rx_st_func_num(rx_st_func_num),
|
||||
.rx_st_vf_num(rx_st_vf_num),
|
||||
.rx_st_bar_range(rx_st_bar_range),
|
||||
.rx_st_tlp_abort(rx_st_tlp_abort),
|
||||
|
||||
.tx_st_data(tx_st_data),
|
||||
.tx_st_sop(tx_st_sop),
|
||||
.tx_st_eop(tx_st_eop),
|
||||
.tx_st_valid(tx_st_valid),
|
||||
.tx_st_ready(tx_st_ready),
|
||||
.tx_st_err(tx_st_err),
|
||||
.tx_st_hdr(tx_st_hdr),
|
||||
.tx_st_tlp_prfx(tx_st_tlp_prfx),
|
||||
|
||||
.rx_buffer_limit(rx_buffer_limit),
|
||||
.rx_buffer_limit_tdm_idx(rx_buffer_limit_tdm_idx),
|
||||
|
||||
.tx_cdts_limit(tx_cdts_limit),
|
||||
.tx_cdts_limit_tdm_idx(tx_cdts_limit_tdm_idx),
|
||||
|
||||
.tl_cfg_ctl(tl_cfg_ctl),
|
||||
.tl_cfg_add(tl_cfg_add),
|
||||
.tl_cfg_func(tl_cfg_func)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
175
example/DE10_Agilex/fpga/rtl/fpga_core.v
Normal file
175
example/DE10_Agilex/fpga/rtl/fpga_core.v
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2022 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 SEG_COUNT = 2,
|
||||
parameter SEG_DATA_WIDTH = 256,
|
||||
parameter SEG_EMPTY_WIDTH = $clog2(SEG_DATA_WIDTH/32),
|
||||
parameter SEG_HDR_WIDTH = 128,
|
||||
parameter SEG_PRFX_WIDTH = 32,
|
||||
parameter TX_SEQ_NUM_WIDTH = 6,
|
||||
parameter PCIE_TAG_COUNT = 256,
|
||||
parameter BAR0_APERTURE = 24,
|
||||
parameter BAR2_APERTURE = 24,
|
||||
parameter BAR4_APERTURE = 16
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/*
|
||||
* GPIO
|
||||
*/
|
||||
input wire [1:0] button,
|
||||
input wire [1:0] sw,
|
||||
output wire [3:0] led,
|
||||
output wire [3:0] led_bracket,
|
||||
|
||||
/*
|
||||
* P-Tile RX AVST interface
|
||||
*/
|
||||
input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] rx_st_data,
|
||||
input wire [SEG_COUNT*SEG_EMPTY_WIDTH-1:0] rx_st_empty,
|
||||
input wire [SEG_COUNT-1:0] rx_st_sop,
|
||||
input wire [SEG_COUNT-1:0] rx_st_eop,
|
||||
input wire [SEG_COUNT-1:0] rx_st_valid,
|
||||
output wire rx_st_ready,
|
||||
input wire [SEG_COUNT*SEG_HDR_WIDTH-1:0] rx_st_hdr,
|
||||
input wire [SEG_COUNT*SEG_PRFX_WIDTH-1:0] rx_st_tlp_prfx,
|
||||
input wire [SEG_COUNT-1:0] rx_st_vf_active,
|
||||
input wire [SEG_COUNT*3-1:0] rx_st_func_num,
|
||||
input wire [SEG_COUNT*11-1:0] rx_st_vf_num,
|
||||
input wire [SEG_COUNT*3-1:0] rx_st_bar_range,
|
||||
input wire [SEG_COUNT-1:0] rx_st_tlp_abort,
|
||||
|
||||
output wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] tx_st_data,
|
||||
output wire [SEG_COUNT-1:0] tx_st_sop,
|
||||
output wire [SEG_COUNT-1:0] tx_st_eop,
|
||||
output wire [SEG_COUNT-1:0] tx_st_valid,
|
||||
input wire tx_st_ready,
|
||||
output wire [SEG_COUNT-1:0] tx_st_err,
|
||||
output wire [SEG_COUNT*SEG_HDR_WIDTH-1:0] tx_st_hdr,
|
||||
output wire [SEG_COUNT*SEG_PRFX_WIDTH-1:0] tx_st_tlp_prfx,
|
||||
|
||||
output wire [11:0] rx_buffer_limit,
|
||||
output wire [1:0] rx_buffer_limit_tdm_idx,
|
||||
|
||||
input wire [15:0] tx_cdts_limit,
|
||||
input wire [2:0] tx_cdts_limit_tdm_idx,
|
||||
|
||||
input wire [15:0] tl_cfg_ctl,
|
||||
input wire [4:0] tl_cfg_add,
|
||||
input wire [2:0] tl_cfg_func
|
||||
);
|
||||
|
||||
assign led = 0;
|
||||
assign led_bracket = 0;
|
||||
|
||||
example_core_pcie_ptile #(
|
||||
.SEG_COUNT(SEG_COUNT),
|
||||
.SEG_DATA_WIDTH(SEG_DATA_WIDTH),
|
||||
.SEG_EMPTY_WIDTH(SEG_EMPTY_WIDTH),
|
||||
.SEG_HDR_WIDTH(SEG_HDR_WIDTH),
|
||||
.SEG_PRFX_WIDTH(SEG_PRFX_WIDTH),
|
||||
.IMM_ENABLE(1),
|
||||
.IMM_WIDTH(32),
|
||||
.TX_SEQ_NUM_WIDTH(TX_SEQ_NUM_WIDTH),
|
||||
.TX_SEQ_NUM_ENABLE(1),
|
||||
.PCIE_TAG_COUNT(PCIE_TAG_COUNT),
|
||||
.READ_OP_TABLE_SIZE(PCIE_TAG_COUNT),
|
||||
.READ_TX_LIMIT(2**TX_SEQ_NUM_WIDTH),
|
||||
.READ_TX_FC_ENABLE(0),
|
||||
.WRITE_OP_TABLE_SIZE(2**TX_SEQ_NUM_WIDTH),
|
||||
.WRITE_TX_LIMIT(2**TX_SEQ_NUM_WIDTH),
|
||||
.WRITE_TX_FC_ENABLE(0),
|
||||
.BAR0_APERTURE(BAR0_APERTURE),
|
||||
.BAR2_APERTURE(BAR2_APERTURE),
|
||||
.BAR4_APERTURE(BAR4_APERTURE)
|
||||
)
|
||||
core_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
/*
|
||||
* P-Tile RX AVST interface
|
||||
*/
|
||||
.rx_st_data(rx_st_data),
|
||||
.rx_st_empty(rx_st_empty),
|
||||
.rx_st_sop(rx_st_sop),
|
||||
.rx_st_eop(rx_st_eop),
|
||||
.rx_st_valid(rx_st_valid),
|
||||
.rx_st_ready(rx_st_ready),
|
||||
.rx_st_hdr(rx_st_hdr),
|
||||
.rx_st_tlp_prfx(rx_st_tlp_prfx),
|
||||
.rx_st_vf_active(rx_st_vf_active),
|
||||
.rx_st_func_num(rx_st_func_num),
|
||||
.rx_st_vf_num(rx_st_vf_num),
|
||||
.rx_st_bar_range(rx_st_bar_range),
|
||||
.rx_st_tlp_abort(rx_st_tlp_abort),
|
||||
|
||||
/*
|
||||
* P-Tile TX AVST interface
|
||||
*/
|
||||
.tx_st_data(tx_st_data),
|
||||
.tx_st_sop(tx_st_sop),
|
||||
.tx_st_eop(tx_st_eop),
|
||||
.tx_st_valid(tx_st_valid),
|
||||
.tx_st_ready(tx_st_ready),
|
||||
.tx_st_err(tx_st_err),
|
||||
.tx_st_hdr(tx_st_hdr),
|
||||
.tx_st_tlp_prfx(tx_st_tlp_prfx),
|
||||
|
||||
/*
|
||||
* P-Tile RX flow control
|
||||
*/
|
||||
.rx_buffer_limit(rx_buffer_limit),
|
||||
.rx_buffer_limit_tdm_idx(rx_buffer_limit_tdm_idx),
|
||||
|
||||
/*
|
||||
* P-Tile TX flow control
|
||||
*/
|
||||
.tx_cdts_limit(tx_cdts_limit),
|
||||
.tx_cdts_limit_tdm_idx(tx_cdts_limit_tdm_idx),
|
||||
|
||||
/*
|
||||
* P-Tile configuration interface
|
||||
*/
|
||||
.tl_cfg_ctl(tl_cfg_ctl),
|
||||
.tl_cfg_add(tl_cfg_add),
|
||||
.tl_cfg_func(tl_cfg_func)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
61
example/DE10_Agilex/fpga/rtl/sync_reset.v
Normal file
61
example/DE10_Agilex/fpga/rtl/sync_reset.v
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-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
|
||||
|
||||
/*
|
||||
* Synchronizes an active-high asynchronous reset signal to a given clock by
|
||||
* using a pipeline of N registers.
|
||||
*/
|
||||
module sync_reset #
|
||||
(
|
||||
// depth of synchronizer
|
||||
parameter N = 2
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
output wire out
|
||||
);
|
||||
|
||||
(* srl_style = "register" *)
|
||||
reg [N-1:0] sync_reg = {N{1'b1}};
|
||||
|
||||
assign out = sync_reg[N-1];
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
sync_reg <= {N{1'b1}};
|
||||
end else begin
|
||||
sync_reg <= {sync_reg[N-2:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
62
example/DE10_Agilex/fpga/rtl/sync_signal.v
Normal file
62
example/DE10_Agilex/fpga/rtl/sync_signal.v
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014-2018 Alex Forencich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog-2001
|
||||
|
||||
`resetall
|
||||
`timescale 1 ns / 1 ps
|
||||
`default_nettype none
|
||||
|
||||
/*
|
||||
* Synchronizes an asyncronous signal to a given clock by using a pipeline of
|
||||
* two registers.
|
||||
*/
|
||||
module sync_signal #(
|
||||
parameter WIDTH=1, // width of the input and output signals
|
||||
parameter N=2 // depth of synchronizer
|
||||
)(
|
||||
input wire clk,
|
||||
input wire [WIDTH-1:0] in,
|
||||
output wire [WIDTH-1:0] out
|
||||
);
|
||||
|
||||
reg [WIDTH-1:0] sync_reg[N-1:0];
|
||||
|
||||
/*
|
||||
* The synchronized output is the last register in the pipeline.
|
||||
*/
|
||||
assign out = sync_reg[N-1];
|
||||
|
||||
integer k;
|
||||
|
||||
always @(posedge clk) begin
|
||||
sync_reg[0] <= in;
|
||||
for (k = 1; k < N; k = k + 1) begin
|
||||
sync_reg[k] <= sync_reg[k-1];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`resetall
|
120
example/DE10_Agilex/fpga/tb/fpga_core/Makefile
Normal file
120
example/DE10_Agilex/fpga/tb/fpga_core/Makefile
Normal file
@ -0,0 +1,120 @@
|
||||
# Copyright (c) 2022 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_ptile.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_ptile_if.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_ptile_if_rx.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_ptile_if_tx.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_ptile_cfg.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/pcie_tlp_fifo.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_fifo_raw.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tlp_fifo_mux.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_msix.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/priority_encoder.v
|
||||
VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v
|
||||
|
||||
# module parameters
|
||||
export PARAM_SEG_COUNT ?= 2
|
||||
export PARAM_SEG_DATA_WIDTH ?= 256
|
||||
export PARAM_SEG_EMPTY_WIDTH ?= $(shell python -c "print((($(PARAM_SEG_DATA_WIDTH)//32)-1).bit_length())" )
|
||||
export PARAM_SEG_HDR_WIDTH ?= 128
|
||||
export PARAM_SEG_PRFX_WIDTH ?= 32
|
||||
export PARAM_TX_SEQ_NUM_WIDTH ?= 6
|
||||
export PARAM_PCIE_TAG_COUNT ?= 64
|
||||
export PARAM_BAR0_APERTURE ?= 24
|
||||
export PARAM_BAR2_APERTURE ?= 24
|
||||
export PARAM_BAR4_APERTURE ?= 16
|
||||
|
||||
ifeq ($(SIM), icarus)
|
||||
PLUSARGS += -fst
|
||||
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).SEG_COUNT=$(PARAM_SEG_COUNT)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).SEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).SEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).SEG_HDR_WIDTH=$(PARAM_SEG_HDR_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).SEG_PRFX_WIDTH=$(PARAM_SEG_PRFX_WIDTH)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).TX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH)
|
||||
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)
|
||||
COMPILE_ARGS += -P $(TOPLEVEL).BAR4_APERTURE=$(PARAM_BAR4_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 += -GSEG_COUNT=$(PARAM_SEG_COUNT)
|
||||
COMPILE_ARGS += -GSEG_DATA_WIDTH=$(PARAM_SEG_DATA_WIDTH)
|
||||
COMPILE_ARGS += -GSEG_EMPTY_WIDTH=$(PARAM_SEG_EMPTY_WIDTH)
|
||||
COMPILE_ARGS += -GSEG_HDR_WIDTH=$(PARAM_SEG_HDR_WIDTH)
|
||||
COMPILE_ARGS += -GSEG_PRFX_WIDTH=$(PARAM_SEG_PRFX_WIDTH)
|
||||
COMPILE_ARGS += -GTX_SEQ_NUM_WIDTH=$(PARAM_TX_SEQ_NUM_WIDTH)
|
||||
COMPILE_ARGS += -GPCIE_TAG_COUNT=$(PARAM_PCIE_TAG_COUNT)
|
||||
COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE)
|
||||
COMPILE_ARGS += -GBAR2_APERTURE=$(PARAM_BAR2_APERTURE)
|
||||
COMPILE_ARGS += -GBAR4_APERTURE=$(PARAM_BAR4_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
|
530
example/DE10_Agilex/fpga/tb/fpga_core/test_fpga_core.py
Normal file
530
example/DE10_Agilex/fpga/tb/fpga_core/test_fpga_core.py
Normal file
@ -0,0 +1,530 @@
|
||||
"""
|
||||
|
||||
Copyright (c) 2022 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.pcie.core import RootComplex
|
||||
from cocotbext.pcie.intel.ptile import PTilePcieDevice, PTileRxBus, PTileTxBus
|
||||
|
||||
|
||||
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 = PTilePcieDevice(
|
||||
# configuration options
|
||||
pcie_generation=3,
|
||||
# pcie_link_width=2,
|
||||
# pld_clk_frequency=250e6,
|
||||
pf_count=1,
|
||||
max_payload_size=512,
|
||||
enable_extended_tag=True,
|
||||
|
||||
pf0_msi_enable=False,
|
||||
pf0_msi_count=1,
|
||||
pf1_msi_enable=False,
|
||||
pf1_msi_count=1,
|
||||
pf2_msi_enable=False,
|
||||
pf2_msi_count=1,
|
||||
pf3_msi_enable=False,
|
||||
pf3_msi_count=1,
|
||||
pf0_msix_enable=False,
|
||||
pf0_msix_table_size=63,
|
||||
pf0_msix_table_bir=4,
|
||||
pf0_msix_table_offset=0x00000000,
|
||||
pf0_msix_pba_bir=4,
|
||||
pf0_msix_pba_offset=0x00008000,
|
||||
pf1_msix_enable=False,
|
||||
pf1_msix_table_size=0,
|
||||
pf1_msix_table_bir=0,
|
||||
pf1_msix_table_offset=0x00000000,
|
||||
pf1_msix_pba_bir=0,
|
||||
pf1_msix_pba_offset=0x00000000,
|
||||
pf2_msix_enable=False,
|
||||
pf2_msix_table_size=0,
|
||||
pf2_msix_table_bir=0,
|
||||
pf2_msix_table_offset=0x00000000,
|
||||
pf2_msix_pba_bir=0,
|
||||
pf2_msix_pba_offset=0x00000000,
|
||||
pf3_msix_enable=False,
|
||||
pf3_msix_table_size=0,
|
||||
pf3_msix_table_bir=0,
|
||||
pf3_msix_table_offset=0x00000000,
|
||||
pf3_msix_pba_bir=0,
|
||||
pf3_msix_pba_offset=0x00000000,
|
||||
|
||||
# signals
|
||||
# Clock and reset
|
||||
reset_status=dut.rst,
|
||||
# reset_status_n=dut.reset_status_n,
|
||||
coreclkout_hip=dut.clk,
|
||||
# refclk0=dut.refclk0,
|
||||
# refclk1=dut.refclk1,
|
||||
# pin_perst_n=dut.pin_perst_n,
|
||||
|
||||
# RX interface
|
||||
rx_bus=PTileRxBus.from_prefix(dut, "rx_st"),
|
||||
# rx_par_err=dut.rx_par_err,
|
||||
|
||||
# TX interface
|
||||
tx_bus=PTileTxBus.from_prefix(dut, "tx_st"),
|
||||
# tx_par_err=dut.tx_par_err,
|
||||
|
||||
# RX flow control
|
||||
rx_buffer_limit=dut.rx_buffer_limit,
|
||||
rx_buffer_limit_tdm_idx=dut.rx_buffer_limit_tdm_idx,
|
||||
|
||||
# TX flow control
|
||||
tx_cdts_limit=dut.tx_cdts_limit,
|
||||
tx_cdts_limit_tdm_idx=dut.tx_cdts_limit_tdm_idx,
|
||||
|
||||
# Power management and hard IP status interface
|
||||
# link_up=dut.link_up,
|
||||
# dl_up=dut.dl_up,
|
||||
# surprise_down_err=dut.surprise_down_err,
|
||||
# ltssm_state=dut.ltssm_state,
|
||||
# pm_state=dut.pm_state,
|
||||
# pm_dstate=dut.pm_dstate,
|
||||
# apps_pm_xmt_pme=dut.apps_pm_xmt_pme,
|
||||
# app_req_retry_en=dut.app_req_retry_en,
|
||||
|
||||
# Interrupt interface
|
||||
# app_int=dut.app_int,
|
||||
# msi_pnd_func=dut.msi_pnd_func,
|
||||
# msi_pnd_byte=dut.msi_pnd_byte,
|
||||
# msi_pnd_addr=dut.msi_pnd_addr,
|
||||
|
||||
# Error interface
|
||||
# serr_out=dut.serr_out,
|
||||
# hip_enter_err_mode=dut.hip_enter_err_mode,
|
||||
# app_err_valid=dut.app_err_valid,
|
||||
# app_err_hdr=dut.app_err_hdr,
|
||||
# app_err_info=dut.app_err_info,
|
||||
# app_err_func_num=dut.app_err_func_num,
|
||||
|
||||
# Completion timeout interface
|
||||
# cpl_timeout=dut.cpl_timeout,
|
||||
# cpl_timeout_avmm_clk=dut.cpl_timeout_avmm_clk,
|
||||
# cpl_timeout_avmm_address=dut.cpl_timeout_avmm_address,
|
||||
# cpl_timeout_avmm_read=dut.cpl_timeout_avmm_read,
|
||||
# cpl_timeout_avmm_readdata=dut.cpl_timeout_avmm_readdata,
|
||||
# cpl_timeout_avmm_readdatavalid=dut.cpl_timeout_avmm_readdatavalid,
|
||||
# cpl_timeout_avmm_write=dut.cpl_timeout_avmm_write,
|
||||
# cpl_timeout_avmm_writedata=dut.cpl_timeout_avmm_writedata,
|
||||
# cpl_timeout_avmm_waitrequest=dut.cpl_timeout_avmm_waitrequest,
|
||||
|
||||
# Configuration output
|
||||
tl_cfg_func=dut.tl_cfg_func,
|
||||
tl_cfg_add=dut.tl_cfg_add,
|
||||
tl_cfg_ctl=dut.tl_cfg_ctl,
|
||||
# dl_timer_update=dut.dl_timer_update,
|
||||
|
||||
# Configuration intercept interface
|
||||
# cii_req=dut.cii_req,
|
||||
# cii_hdr_poisoned=dut.cii_hdr_poisoned,
|
||||
# cii_hdr_first_be=dut.cii_hdr_first_be,
|
||||
# cii_func_num=dut.cii_func_num,
|
||||
# cii_wr_vf_active=dut.cii_wr_vf_active,
|
||||
# cii_vf_num=dut.cii_vf_num,
|
||||
# cii_wr=dut.cii_wr,
|
||||
# cii_addr=dut.cii_addr,
|
||||
# cii_dout=dut.cii_dout,
|
||||
# cii_override_en=dut.cii_override_en,
|
||||
# cii_override_din=dut.cii_override_din,
|
||||
# cii_halt=dut.cii_halt,
|
||||
|
||||
# Hard IP reconfiguration interface
|
||||
# hip_reconfig_clk=dut.hip_reconfig_clk,
|
||||
# hip_reconfig_address=dut.hip_reconfig_address,
|
||||
# hip_reconfig_read=dut.hip_reconfig_read,
|
||||
# hip_reconfig_readdata=dut.hip_reconfig_readdata,
|
||||
# hip_reconfig_readdatavalid=dut.hip_reconfig_readdatavalid,
|
||||
# hip_reconfig_write=dut.hip_reconfig_write,
|
||||
# hip_reconfig_writedata=dut.hip_reconfig_writedata,
|
||||
# hip_reconfig_waitrequest=dut.hip_reconfig_waitrequest,
|
||||
|
||||
# Page request service
|
||||
# prs_event_valid=dut.prs_event_valid,
|
||||
# prs_event_func=dut.prs_event_func,
|
||||
# prs_event=dut.prs_event,
|
||||
|
||||
# SR-IOV (VF error)
|
||||
# vf_err_ur_posted_s0=dut.vf_err_ur_posted_s0,
|
||||
# vf_err_ur_posted_s1=dut.vf_err_ur_posted_s1,
|
||||
# vf_err_ur_posted_s2=dut.vf_err_ur_posted_s2,
|
||||
# vf_err_ur_posted_s3=dut.vf_err_ur_posted_s3,
|
||||
# vf_err_func_num_s0=dut.vf_err_func_num_s0,
|
||||
# vf_err_func_num_s1=dut.vf_err_func_num_s1,
|
||||
# vf_err_func_num_s2=dut.vf_err_func_num_s2,
|
||||
# vf_err_func_num_s3=dut.vf_err_func_num_s3,
|
||||
# vf_err_ca_postedreq_s0=dut.vf_err_ca_postedreq_s0,
|
||||
# vf_err_ca_postedreq_s1=dut.vf_err_ca_postedreq_s1,
|
||||
# vf_err_ca_postedreq_s2=dut.vf_err_ca_postedreq_s2,
|
||||
# vf_err_ca_postedreq_s3=dut.vf_err_ca_postedreq_s3,
|
||||
# vf_err_vf_num_s0=dut.vf_err_vf_num_s0,
|
||||
# vf_err_vf_num_s1=dut.vf_err_vf_num_s1,
|
||||
# vf_err_vf_num_s2=dut.vf_err_vf_num_s2,
|
||||
# vf_err_vf_num_s3=dut.vf_err_vf_num_s3,
|
||||
# vf_err_poisonedwrreq_s0=dut.vf_err_poisonedwrreq_s0,
|
||||
# vf_err_poisonedwrreq_s1=dut.vf_err_poisonedwrreq_s1,
|
||||
# vf_err_poisonedwrreq_s2=dut.vf_err_poisonedwrreq_s2,
|
||||
# vf_err_poisonedwrreq_s3=dut.vf_err_poisonedwrreq_s3,
|
||||
# vf_err_poisonedcompl_s0=dut.vf_err_poisonedcompl_s0,
|
||||
# vf_err_poisonedcompl_s1=dut.vf_err_poisonedcompl_s1,
|
||||
# vf_err_poisonedcompl_s2=dut.vf_err_poisonedcompl_s2,
|
||||
# vf_err_poisonedcompl_s3=dut.vf_err_poisonedcompl_s3,
|
||||
# user_vfnonfatalmsg_func_num=dut.user_vfnonfatalmsg_func_num,
|
||||
# user_vfnonfatalmsg_vfnum=dut.user_vfnonfatalmsg_vfnum,
|
||||
# user_sent_vfnonfatalmsg=dut.user_sent_vfnonfatalmsg,
|
||||
# vf_err_overflow=dut.vf_err_overflow,
|
||||
|
||||
# FLR
|
||||
# flr_rcvd_pf=dut.flr_rcvd_pf,
|
||||
# flr_rcvd_vf=dut.flr_rcvd_vf,
|
||||
# flr_rcvd_pf_num=dut.flr_rcvd_pf_num,
|
||||
# flr_rcvd_vf_num=dut.flr_rcvd_vf_num,
|
||||
# flr_completed_pf=dut.flr_completed_pf,
|
||||
# flr_completed_vf=dut.flr_completed_vf,
|
||||
# flr_completed_pf_num=dut.flr_completed_pf_num,
|
||||
# flr_completed_vf_num=dut.flr_completed_vf_num,
|
||||
|
||||
# VirtIO
|
||||
# virtio_pcicfg_vfaccess=dut.virtio_pcicfg_vfaccess,
|
||||
# virtio_pcicfg_vfnum=dut.virtio_pcicfg_vfnum,
|
||||
# virtio_pcicfg_pfnum=dut.virtio_pcicfg_pfnum,
|
||||
# virtio_pcicfg_bar=dut.virtio_pcicfg_bar,
|
||||
# virtio_pcicfg_length=dut.virtio_pcicfg_length,
|
||||
# virtio_pcicfg_baroffset=dut.virtio_pcicfg_baroffset,
|
||||
# virtio_pcicfg_cfgdata=dut.virtio_pcicfg_cfgdata,
|
||||
# virtio_pcicfg_cfgwr=dut.virtio_pcicfg_cfgwr,
|
||||
# virtio_pcicfg_cfgrd=dut.virtio_pcicfg_cfgrd,
|
||||
# virtio_pcicfg_appvfnum=dut.virtio_pcicfg_appvfnum,
|
||||
# virtio_pcicfg_apppfnum=dut.virtio_pcicfg_apppfnum,
|
||||
# virtio_pcicfg_rdack=dut.virtio_pcicfg_rdack,
|
||||
# virtio_pcicfg_rdbe=dut.virtio_pcicfg_rdbe,
|
||||
# virtio_pcicfg_data=dut.virtio_pcicfg_data,
|
||||
)
|
||||
|
||||
# self.dev.log.setLevel(logging.DEBUG)
|
||||
|
||||
self.rc.make_port().connect(self.dev)
|
||||
|
||||
self.dev.functions[0].configure_bar(0, 2**len(dut.core_inst.core_pcie_inst.axil_ctrl_awaddr))
|
||||
self.dev.functions[0].configure_bar(2, 2**len(dut.core_inst.core_pcie_inst.axi_ram_awaddr))
|
||||
|
||||
async def init(self):
|
||||
|
||||
await FallingEdge(self.dut.rst)
|
||||
await Timer(100, 'ns')
|
||||
|
||||
await self.rc.enumerate()
|
||||
|
||||
dev = self.rc.find_device(self.dev.functions[0].pcie_id)
|
||||
await dev.enable_device()
|
||||
await dev.set_master()
|
||||
await dev.alloc_irq_vectors(32, 32)
|
||||
|
||||
|
||||
@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 = tb.rc.find_device(tb.dev.functions[0].pcie_id)
|
||||
|
||||
dev_pf0_bar0 = dev.bar_window[0]
|
||||
dev_pf0_bar2 = dev.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)
|
||||
# enable interrupts
|
||||
await dev_pf0_bar0.write_dword(0x000008, 0x3)
|
||||
|
||||
# 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 immediate write")
|
||||
|
||||
# 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, 0x44332211)
|
||||
await dev_pf0_bar0.write_dword(0x000210, 0x4)
|
||||
await dev_pf0_bar0.write_dword(0x000214, 0x800000AA)
|
||||
|
||||
await Timer(2000, 'ns')
|
||||
|
||||
# read status
|
||||
val = await dev_pf0_bar0.read_dword(0x000218)
|
||||
tb.log.info("Status: 0x%x", val)
|
||||
assert val == 0x800000AA
|
||||
|
||||
tb.log.info("%s", mem.hexdump_str(0x1000, 64))
|
||||
|
||||
assert mem[0x1000:0x1000+4] == b'\x11\x22\x33\x44'
|
||||
|
||||
tb.log.info("Test DMA block operations")
|
||||
|
||||
region_len = 0x2000
|
||||
src_offset = 0x0000
|
||||
dest_offset = 0x4000
|
||||
|
||||
block_size = 256
|
||||
block_stride = block_size
|
||||
block_count = 32
|
||||
|
||||
# write packet data
|
||||
mem[src_offset:src_offset+region_len] = bytearray([x % 256 for x in range(region_len)])
|
||||
|
||||
# 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+src_offset) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x001084, (mem_base+src_offset >> 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, region_len-1)
|
||||
await dev_pf0_bar0.write_dword(0x001094, 0)
|
||||
# DMA stride
|
||||
await dev_pf0_bar0.write_dword(0x001098, block_stride)
|
||||
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, region_len-1)
|
||||
await dev_pf0_bar0.write_dword(0x0010d4, 0)
|
||||
# RAM stride
|
||||
await dev_pf0_bar0.write_dword(0x0010d8, block_stride)
|
||||
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, block_size)
|
||||
# block count
|
||||
await dev_pf0_bar0.write_dword(0x001018, block_count)
|
||||
await dev_pf0_bar0.write_dword(0x00101c, 0)
|
||||
# start
|
||||
await dev_pf0_bar0.write_dword(0x001000, 1)
|
||||
|
||||
for k in range(10):
|
||||
cnt = await dev_pf0_bar0.read_dword(0x001018)
|
||||
await Timer(1000, 'ns')
|
||||
if cnt == 0:
|
||||
break
|
||||
|
||||
# configure operation (write)
|
||||
# DMA base address
|
||||
await dev_pf0_bar0.write_dword(0x001180, (mem_base+dest_offset) & 0xffffffff)
|
||||
await dev_pf0_bar0.write_dword(0x001184, (mem_base+dest_offset >> 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, region_len-1)
|
||||
await dev_pf0_bar0.write_dword(0x001194, 0)
|
||||
# DMA stride
|
||||
await dev_pf0_bar0.write_dword(0x001198, block_stride)
|
||||
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, region_len-1)
|
||||
await dev_pf0_bar0.write_dword(0x0011d4, 0)
|
||||
# RAM stride
|
||||
await dev_pf0_bar0.write_dword(0x0011d8, block_stride)
|
||||
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, block_size)
|
||||
# block count
|
||||
await dev_pf0_bar0.write_dword(0x001118, block_count)
|
||||
await dev_pf0_bar0.write_dword(0x00111c, 0)
|
||||
# start
|
||||
await dev_pf0_bar0.write_dword(0x001100, 1)
|
||||
|
||||
for k in range(10):
|
||||
cnt = await dev_pf0_bar0.read_dword(0x001118)
|
||||
await Timer(1000, 'ns')
|
||||
if cnt == 0:
|
||||
break
|
||||
|
||||
tb.log.info("%s", mem.hexdump_str(dest_offset, region_len))
|
||||
|
||||
assert mem[src_offset:src_offset+region_len] == mem[dest_offset:dest_offset+region_len]
|
||||
|
||||
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_ptile.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_ptile_if.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_ptile_if_rx.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_ptile_if_tx.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_ptile_cfg.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, "pcie_tlp_fifo.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_tlp_fifo_raw.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_tlp_fifo_mux.v"),
|
||||
os.path.join(pcie_rtl_dir, "pcie_msix.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, "priority_encoder.v"),
|
||||
os.path.join(pcie_rtl_dir, "pulse_merge.v"),
|
||||
]
|
||||
|
||||
parameters = {}
|
||||
|
||||
parameters['SEG_COUNT'] = 2
|
||||
parameters['SEG_DATA_WIDTH'] = 256
|
||||
parameters['SEG_EMPTY_WIDTH'] = (parameters['SEG_DATA_WIDTH'] // 32 - 1).bit_length()
|
||||
parameters['SEG_HDR_WIDTH'] = 128
|
||||
parameters['SEG_PRFX_WIDTH'] = 32
|
||||
parameters['TX_SEQ_NUM_WIDTH'] = 6
|
||||
parameters['PCIE_TAG_COUNT'] = 64
|
||||
parameters['BAR0_APERTURE'] = 24
|
||||
parameters['BAR2_APERTURE'] = 24
|
||||
parameters['BAR4_APERTURE'] = 16
|
||||
|
||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||
|
||||
sim_build = os.path.join(tests_dir, "sim_build",
|
||||
request.node.name.replace('[', '-').replace(']', ''))
|
||||
|
||||
cocotb_test.simulator.run(
|
||||
python_search=[tests_dir],
|
||||
verilog_sources=verilog_sources,
|
||||
toplevel=toplevel,
|
||||
module=module,
|
||||
parameters=parameters,
|
||||
sim_build=sim_build,
|
||||
extra_env=extra_env,
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user