mirror of
https://github.com/corundum/corundum.git
synced 2025-02-06 08:38:23 +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