From cabad17552c5ec26bcd66d96ec1d2319eb147a87 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 18 Dec 2020 22:10:32 -0800 Subject: [PATCH] Migrate example design testbenches to cocotb --- .../ADM_PCIE_9V3/fpga_axi_x8/tb/axis_ep.py | 1 - .../fpga_axi_x8/tb/fpga_core/Makefile | 107 ++++ .../tb/fpga_core/test_fpga_core.py | 378 +++++++++++++ example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie.py | 1 - .../ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_us.py | 1 - .../ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_usp.py | 1 - .../fpga_axi_x8/tb/test_fpga_core.py | 512 ----------------- .../fpga_axi_x8/tb/test_fpga_core.v | 243 -------- example/AU200/fpga_axi/tb/axis_ep.py | 1 - example/AU200/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 380 +++++++++++++ example/AU200/fpga_axi/tb/pcie.py | 1 - example/AU200/fpga_axi/tb/pcie_us.py | 1 - example/AU200/fpga_axi/tb/pcie_usp.py | 1 - example/AU200/fpga_axi/tb/test_fpga_core.py | 520 ------------------ example/AU200/fpga_axi/tb/test_fpga_core.v | 243 -------- example/AU250/fpga_axi/tb/axis_ep.py | 1 - example/AU250/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 380 +++++++++++++ example/AU250/fpga_axi/tb/pcie.py | 1 - example/AU250/fpga_axi/tb/pcie_us.py | 1 - example/AU250/fpga_axi/tb/pcie_usp.py | 1 - example/AU250/fpga_axi/tb/test_fpga_core.py | 520 ------------------ example/AU250/fpga_axi/tb/test_fpga_core.v | 243 -------- example/AU280/fpga_axi/tb/axis_ep.py | 1 - example/AU280/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 378 +++++++++++++ example/AU280/fpga_axi/tb/pcie.py | 1 - example/AU280/fpga_axi/tb/pcie_us.py | 1 - example/AU280/fpga_axi/tb/pcie_usp.py | 1 - example/AU280/fpga_axi/tb/test_fpga_core.py | 506 ----------------- example/AU280/fpga_axi/tb/test_fpga_core.v | 234 -------- example/AU50/fpga_axi/tb/axis_ep.py | 1 - example/AU50/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 378 +++++++++++++ example/AU50/fpga_axi/tb/pcie.py | 1 - example/AU50/fpga_axi/tb/pcie_us.py | 1 - example/AU50/fpga_axi/tb/pcie_usp.py | 1 - example/AU50/fpga_axi/tb/test_fpga_core.py | 506 ----------------- example/AU50/fpga_axi/tb/test_fpga_core.v | 234 -------- example/ExaNIC_X10/fpga_axi/tb/axis_ep.py | 1 - .../ExaNIC_X10/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 376 +++++++++++++ example/ExaNIC_X10/fpga_axi/tb/pcie.py | 1 - example/ExaNIC_X10/fpga_axi/tb/pcie_us.py | 1 - .../ExaNIC_X10/fpga_axi/tb/test_fpga_core.py | 512 ----------------- .../ExaNIC_X10/fpga_axi/tb/test_fpga_core.v | 243 -------- example/ExaNIC_X25/fpga_axi/tb/axis_ep.py | 1 - .../ExaNIC_X25/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 378 +++++++++++++ example/ExaNIC_X25/fpga_axi/tb/pcie.py | 1 - example/ExaNIC_X25/fpga_axi/tb/pcie_us.py | 1 - example/ExaNIC_X25/fpga_axi/tb/pcie_usp.py | 1 - .../ExaNIC_X25/fpga_axi/tb/test_fpga_core.py | 512 ----------------- .../ExaNIC_X25/fpga_axi/tb/test_fpga_core.v | 243 -------- example/VCU108/fpga_axi/tb/axis_ep.py | 1 - example/VCU108/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 383 +++++++++++++ example/VCU108/fpga_axi/tb/pcie.py | 1 - example/VCU108/fpga_axi/tb/pcie_us.py | 1 - example/VCU108/fpga_axi/tb/test_fpga_core.py | 515 ----------------- example/VCU108/fpga_axi/tb/test_fpga_core.v | 242 -------- example/VCU118/fpga_axi_x8/tb/axis_ep.py | 1 - .../VCU118/fpga_axi_x8/tb/fpga_core/Makefile | 107 ++++ .../tb/fpga_core/test_fpga_core.py | 385 +++++++++++++ example/VCU118/fpga_axi_x8/tb/pcie.py | 1 - example/VCU118/fpga_axi_x8/tb/pcie_us.py | 1 - example/VCU118/fpga_axi_x8/tb/pcie_usp.py | 1 - .../VCU118/fpga_axi_x8/tb/test_fpga_core.py | 520 ------------------ .../VCU118/fpga_axi_x8/tb/test_fpga_core.v | 258 --------- example/VCU1525/fpga_axi/tb/axis_ep.py | 1 - .../VCU1525/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 380 +++++++++++++ example/VCU1525/fpga_axi/tb/pcie.py | 1 - example/VCU1525/fpga_axi/tb/pcie_us.py | 1 - example/VCU1525/fpga_axi/tb/pcie_usp.py | 1 - example/VCU1525/fpga_axi/tb/test_fpga_core.py | 520 ------------------ example/VCU1525/fpga_axi/tb/test_fpga_core.v | 243 -------- example/ZCU106/fpga_axi/tb/axis_ep.py | 1 - example/ZCU106/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 385 +++++++++++++ example/ZCU106/fpga_axi/tb/pcie.py | 1 - example/ZCU106/fpga_axi/tb/pcie_us.py | 1 - example/ZCU106/fpga_axi/tb/pcie_usp.py | 1 - example/ZCU106/fpga_axi/tb/test_fpga_core.py | 520 ------------------ example/ZCU106/fpga_axi/tb/test_fpga_core.v | 258 --------- example/fb2CG/fpga_axi/tb/axis_ep.py | 1 - example/fb2CG/fpga_axi/tb/fpga_core/Makefile | 107 ++++ .../fpga_axi/tb/fpga_core/test_fpga_core.py | 378 +++++++++++++ example/fb2CG/fpga_axi/tb/pcie.py | 1 - example/fb2CG/fpga_axi/tb/pcie_us.py | 1 - example/fb2CG/fpga_axi/tb/pcie_usp.py | 1 - example/fb2CG/fpga_axi/tb/test_fpga_core.py | 514 ----------------- example/fb2CG/fpga_axi/tb/test_fpga_core.v | 246 --------- 94 files changed, 5843 insertions(+), 9153 deletions(-) delete mode 120000 example/ADM_PCIE_9V3/fpga_axi_x8/tb/axis_ep.py create mode 100644 example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/Makefile create mode 100644 example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/test_fpga_core.py delete mode 120000 example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie.py delete mode 120000 example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_us.py delete mode 120000 example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_usp.py delete mode 100755 example/ADM_PCIE_9V3/fpga_axi_x8/tb/test_fpga_core.py delete mode 100644 example/ADM_PCIE_9V3/fpga_axi_x8/tb/test_fpga_core.v delete mode 120000 example/AU200/fpga_axi/tb/axis_ep.py create mode 100644 example/AU200/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/AU200/fpga_axi/tb/pcie.py delete mode 120000 example/AU200/fpga_axi/tb/pcie_us.py delete mode 120000 example/AU200/fpga_axi/tb/pcie_usp.py delete mode 100755 example/AU200/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/AU200/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/AU250/fpga_axi/tb/axis_ep.py create mode 100644 example/AU250/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/AU250/fpga_axi/tb/pcie.py delete mode 120000 example/AU250/fpga_axi/tb/pcie_us.py delete mode 120000 example/AU250/fpga_axi/tb/pcie_usp.py delete mode 100755 example/AU250/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/AU250/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/AU280/fpga_axi/tb/axis_ep.py create mode 100644 example/AU280/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/AU280/fpga_axi/tb/pcie.py delete mode 120000 example/AU280/fpga_axi/tb/pcie_us.py delete mode 120000 example/AU280/fpga_axi/tb/pcie_usp.py delete mode 100755 example/AU280/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/AU280/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/AU50/fpga_axi/tb/axis_ep.py create mode 100644 example/AU50/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/AU50/fpga_axi/tb/pcie.py delete mode 120000 example/AU50/fpga_axi/tb/pcie_us.py delete mode 120000 example/AU50/fpga_axi/tb/pcie_usp.py delete mode 100755 example/AU50/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/AU50/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/ExaNIC_X10/fpga_axi/tb/axis_ep.py create mode 100644 example/ExaNIC_X10/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/ExaNIC_X10/fpga_axi/tb/pcie.py delete mode 120000 example/ExaNIC_X10/fpga_axi/tb/pcie_us.py delete mode 100755 example/ExaNIC_X10/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/ExaNIC_X10/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/ExaNIC_X25/fpga_axi/tb/axis_ep.py create mode 100644 example/ExaNIC_X25/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/ExaNIC_X25/fpga_axi/tb/pcie.py delete mode 120000 example/ExaNIC_X25/fpga_axi/tb/pcie_us.py delete mode 120000 example/ExaNIC_X25/fpga_axi/tb/pcie_usp.py delete mode 100755 example/ExaNIC_X25/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/ExaNIC_X25/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/VCU108/fpga_axi/tb/axis_ep.py create mode 100644 example/VCU108/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/VCU108/fpga_axi/tb/pcie.py delete mode 120000 example/VCU108/fpga_axi/tb/pcie_us.py delete mode 100755 example/VCU108/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/VCU108/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/VCU118/fpga_axi_x8/tb/axis_ep.py create mode 100644 example/VCU118/fpga_axi_x8/tb/fpga_core/Makefile create mode 100644 example/VCU118/fpga_axi_x8/tb/fpga_core/test_fpga_core.py delete mode 120000 example/VCU118/fpga_axi_x8/tb/pcie.py delete mode 120000 example/VCU118/fpga_axi_x8/tb/pcie_us.py delete mode 120000 example/VCU118/fpga_axi_x8/tb/pcie_usp.py delete mode 100755 example/VCU118/fpga_axi_x8/tb/test_fpga_core.py delete mode 100644 example/VCU118/fpga_axi_x8/tb/test_fpga_core.v delete mode 120000 example/VCU1525/fpga_axi/tb/axis_ep.py create mode 100644 example/VCU1525/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/VCU1525/fpga_axi/tb/pcie.py delete mode 120000 example/VCU1525/fpga_axi/tb/pcie_us.py delete mode 120000 example/VCU1525/fpga_axi/tb/pcie_usp.py delete mode 100755 example/VCU1525/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/VCU1525/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/ZCU106/fpga_axi/tb/axis_ep.py create mode 100644 example/ZCU106/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/ZCU106/fpga_axi/tb/pcie.py delete mode 120000 example/ZCU106/fpga_axi/tb/pcie_us.py delete mode 120000 example/ZCU106/fpga_axi/tb/pcie_usp.py delete mode 100755 example/ZCU106/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/ZCU106/fpga_axi/tb/test_fpga_core.v delete mode 120000 example/fb2CG/fpga_axi/tb/axis_ep.py create mode 100644 example/fb2CG/fpga_axi/tb/fpga_core/Makefile create mode 100644 example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py delete mode 120000 example/fb2CG/fpga_axi/tb/pcie.py delete mode 120000 example/fb2CG/fpga_axi/tb/pcie_us.py delete mode 120000 example/fb2CG/fpga_axi/tb/pcie_usp.py delete mode 100755 example/fb2CG/fpga_axi/tb/test_fpga_core.py delete mode 100644 example/fb2CG/fpga_axi/tb/test_fpga_core.v diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/axis_ep.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/axis_ep.py deleted file mode 120000 index 101b21c..0000000 --- a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/axis_ep.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/Makefile b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/Makefile new file mode 100644 index 0000000..d8b7d22 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/Makefile @@ -0,0 +1,107 @@ +# Copyright (c) 2020 Alex Forencich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/axi_ram.v +VERILOG_SOURCES += ../../rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_dma.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_dma_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_dma_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_master_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axi_master_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axis_cq_demux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/pcie/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +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 sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..4ae9e63 --- /dev/null +++ b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,378 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_us.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_usp.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_axi_x8/tb/test_fpga_core.py deleted file mode 100755 index cbf4aa0..0000000 --- a/example/ADM_PCIE_9V3/fpga_axi_x8/tb/test_fpga_core.py +++ /dev/null @@ -1,512 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - user_led_g = Signal(intbv(0)[2:]) - user_led_r = Signal(bool(0)) - front_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - user_led_g=user_led_g, - user_led_r=user_led_r, - front_led=front_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..4dbec9a --- /dev/null +++ b/example/AU200/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,380 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/AU200/fpga_axi/tb/pcie.py b/example/AU200/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/AU200/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/AU200/fpga_axi/tb/pcie_us.py b/example/AU200/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/AU200/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/AU200/fpga_axi/tb/pcie_usp.py b/example/AU200/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/AU200/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/AU200/fpga_axi/tb/test_fpga_core.py b/example/AU200/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 478bc3d..0000000 --- a/example/AU200/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..4dbec9a --- /dev/null +++ b/example/AU250/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,380 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/AU250/fpga_axi/tb/pcie.py b/example/AU250/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/AU250/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/AU250/fpga_axi/tb/pcie_us.py b/example/AU250/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/AU250/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/AU250/fpga_axi/tb/pcie_usp.py b/example/AU250/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/AU250/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/AU250/fpga_axi/tb/test_fpga_core.py b/example/AU250/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 478bc3d..0000000 --- a/example/AU250/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..ce862a0 --- /dev/null +++ b/example/AU280/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,378 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/AU280/fpga_axi/tb/pcie.py b/example/AU280/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/AU280/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/AU280/fpga_axi/tb/pcie_us.py b/example/AU280/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/AU280/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/AU280/fpga_axi/tb/pcie_usp.py b/example/AU280/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/AU280/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/AU280/fpga_axi/tb/test_fpga_core.py b/example/AU280/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index d1d902c..0000000 --- a/example/AU280/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,506 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..ce862a0 --- /dev/null +++ b/example/AU50/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,378 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/AU50/fpga_axi/tb/pcie.py b/example/AU50/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/AU50/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/AU50/fpga_axi/tb/pcie_us.py b/example/AU50/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/AU50/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/AU50/fpga_axi/tb/pcie_usp.py b/example/AU50/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/AU50/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/AU50/fpga_axi/tb/test_fpga_core.py b/example/AU50/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index d1d902c..0000000 --- a/example/AU50/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,506 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..bd056fd --- /dev/null +++ b/example/ExaNIC_X10/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,376 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice +from cocotbext.axi.utils import hexdump_str + + +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 = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + + 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, + ) diff --git a/example/ExaNIC_X10/fpga_axi/tb/pcie.py b/example/ExaNIC_X10/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/ExaNIC_X10/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga_axi/tb/pcie_us.py b/example/ExaNIC_X10/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/ExaNIC_X10/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/ExaNIC_X10/fpga_axi/tb/test_fpga_core.py b/example/ExaNIC_X10/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 5651467..0000000 --- a/example/ExaNIC_X10/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,512 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_us - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num=pcie_rq_seq_num, - #pcie_rq_seq_num_vld=pcie_rq_seq_num_vld, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sma_led=sma_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..4ae9e63 --- /dev/null +++ b/example/ExaNIC_X25/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,378 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/ExaNIC_X25/fpga_axi/tb/pcie.py b/example/ExaNIC_X25/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/ExaNIC_X25/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/ExaNIC_X25/fpga_axi/tb/pcie_us.py b/example/ExaNIC_X25/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/ExaNIC_X25/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/ExaNIC_X25/fpga_axi/tb/pcie_usp.py b/example/ExaNIC_X25/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/ExaNIC_X25/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/ExaNIC_X25/fpga_axi/tb/test_fpga_core.py b/example/ExaNIC_X25/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index e7fa795..0000000 --- a/example/ExaNIC_X25/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,512 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sma_led=sma_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..f3d494c --- /dev/null +++ b/example/VCU108/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,383 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice +from cocotbext.axi.utils import hexdump_str + + +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 = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + + 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, + ) diff --git a/example/VCU108/fpga_axi/tb/pcie.py b/example/VCU108/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/VCU108/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/VCU108/fpga_axi/tb/pcie_us.py b/example/VCU108/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/VCU108/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/VCU108/fpga_axi/tb/test_fpga_core.py b/example/VCU108/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 0e0f0c5..0000000 --- a/example/VCU108/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,515 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_us - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[256:]) - s_axis_rc_tkeep = Signal(intbv(0)[8:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[75:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[256:]) - s_axis_cq_tkeep = Signal(intbv(0)[8:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[85:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[256:]) - m_axis_rq_tkeep = Signal(intbv(0)[8:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[60:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[256:]) - m_axis_cc_tkeep = Signal(intbv(0)[8:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[33:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num=pcie_rq_seq_num, - #pcie_rq_seq_num_vld=pcie_rq_seq_num_vld, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/VCU118/fpga_axi_x8/tb/fpga_core/test_fpga_core.py b/example/VCU118/fpga_axi_x8/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..133d054 --- /dev/null +++ b/example/VCU118/fpga_axi_x8/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,385 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/VCU118/fpga_axi_x8/tb/pcie.py b/example/VCU118/fpga_axi_x8/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/VCU118/fpga_axi_x8/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/VCU118/fpga_axi_x8/tb/pcie_us.py b/example/VCU118/fpga_axi_x8/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/VCU118/fpga_axi_x8/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/VCU118/fpga_axi_x8/tb/pcie_usp.py b/example/VCU118/fpga_axi_x8/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/VCU118/fpga_axi_x8/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/VCU118/fpga_axi_x8/tb/test_fpga_core.py b/example/VCU118/fpga_axi_x8/tb/test_fpga_core.py deleted file mode 100755 index e28bdd2..0000000 --- a/example/VCU118/fpga_axi_x8/tb/test_fpga_core.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..4dbec9a --- /dev/null +++ b/example/VCU1525/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,380 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/VCU1525/fpga_axi/tb/pcie.py b/example/VCU1525/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/VCU1525/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/VCU1525/fpga_axi/tb/pcie_us.py b/example/VCU1525/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/VCU1525/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/VCU1525/fpga_axi/tb/pcie_usp.py b/example/VCU1525/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/VCU1525/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/VCU1525/fpga_axi/tb/test_fpga_core.py b/example/VCU1525/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 478bc3d..0000000 --- a/example/VCU1525/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..b16e113 --- /dev/null +++ b/example/ZCU106/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,385 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=4, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 128 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/ZCU106/fpga_axi/tb/pcie.py b/example/ZCU106/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/ZCU106/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/ZCU106/fpga_axi/tb/pcie_us.py b/example/ZCU106/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/ZCU106/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/ZCU106/fpga_axi/tb/pcie_usp.py b/example/ZCU106/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/ZCU106/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/ZCU106/fpga_axi/tb/test_fpga_core.py b/example/ZCU106/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index 48d5e00..0000000 --- a/example/ZCU106/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2020 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 128 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[8:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led = Signal(intbv(0)[8:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 4 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack(' $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py b/example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py new file mode 100644 index 0000000..ce862a0 --- /dev/null +++ b/example/fb2CG/fpga_axi/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,378 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice +from cocotbext.axi.utils import hexdump_str + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk, + user_reset=dut.rst, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + # pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + # pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + # pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + # pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + # cfg_fc_ph=dut.cfg_fc_ph, + # cfg_fc_pd=dut.cfg_fc_pd, + # cfg_fc_nph=dut.cfg_fc_nph, + # cfg_fc_npd=dut.cfg_fc_npd, + # cfg_fc_cplh=dut.cfg_fc_cplh, + # cfg_fc_cpld=dut.cfg_fc_cpld, + # cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**22) + self.dev.functions[0].configure_bar(1, 2**22) + + async def init(self): + + await FallingEdge(self.dut.rst) + await Timer(100, 'ns') + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + mem_base, mem_data = tb.rc.alloc_region(16*1024*1024) + + dev_pf0_bar0 = tb.rc.tree[0][0].bar_addr[0] + dev_pf0_bar1 = tb.rc.tree[0][0].bar_addr[1] + + tb.log.info("Test memory write to BAR 1") + + await tb.rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') + + await Timer(100, 'ns') + + tb.log.info("Test memory read from BAR 1") + + val = await tb.rc.mem_read(dev_pf0_bar1, 4, 1000) + tb.log.info("Read data: %s", val) + assert val == b'\x11\x22\x33\x44' + + tb.log.info("Test DMA") + + # write packet data + mem_data[0:1024] = bytearray([x % 256 for x in range(1024)]) + + # enable DMA + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100000, 1) + + # write pcie read descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100100, (mem_base+0x0000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100104, (mem_base+0x0000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100108, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10010C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100110, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100114, 0xAA) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100118) + tb.log.info("Status: 0x%x", val) + assert val == 0xAA + + # write pcie write descriptor + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100200, (mem_base+0x1000) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100204, (mem_base+0x1000 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100208, (0x100) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x10020C, (0x100 >> 32) & 0xffffffff) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100210, 0x400) + await tb.rc.mem_write_dword(dev_pf0_bar0+0x100214, 0x55) + + await Timer(2000, 'ns') + + # read status + val = await tb.rc.mem_read_dword(dev_pf0_bar0+0x100218) + tb.log.info("Status: 0x%x", val) + assert val == 0x55 + + tb.log.info("%s", hexdump_str(mem_data, 0x1000, 64)) + + assert mem_data[0:1024] == mem_data[0x1000:0x1000+1024] + + 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, "axi_ram.v"), + os.path.join(rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "axis_arb_mux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_dma_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_rd.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axi_master_wr.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axis_cq_demux.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "arbiter.v"), + os.path.join(pcie_rtl_dir, "priority_encoder.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + + 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, + ) diff --git a/example/fb2CG/fpga_axi/tb/pcie.py b/example/fb2CG/fpga_axi/tb/pcie.py deleted file mode 120000 index abea2f9..0000000 --- a/example/fb2CG/fpga_axi/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/example/fb2CG/fpga_axi/tb/pcie_us.py b/example/fb2CG/fpga_axi/tb/pcie_us.py deleted file mode 120000 index ef028ec..0000000 --- a/example/fb2CG/fpga_axi/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/example/fb2CG/fpga_axi/tb/pcie_usp.py b/example/fb2CG/fpga_axi/tb/pcie_usp.py deleted file mode 120000 index 8ce355a..0000000 --- a/example/fb2CG/fpga_axi/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/example/fb2CG/fpga_axi/tb/test_fpga_core.py b/example/fb2CG/fpga_axi/tb/test_fpga_core.py deleted file mode 100755 index eca194d..0000000 --- a/example/fb2CG/fpga_axi/tb/test_fpga_core.py +++ /dev/null @@ -1,514 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright (c) 2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -""" - -from myhdl import * -import os -import struct - -import pcie -import pcie_usp - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/axi_ram.v") -srcs.append("../rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/axis_arb_mux.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_dma_wr.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_rd.v") -srcs.append("../lib/pcie/rtl/pcie_us_axi_master_wr.v") -srcs.append("../lib/pcie/rtl/pcie_us_axis_cq_demux.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/arbiter.v") -srcs.append("../lib/pcie/rtl/priority_encoder.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - - # Outputs - led_red = Signal(intbv(0)[8:]) - led_green = Signal(intbv(0)[8:]) - led_bmc = Signal(intbv(0)[2:]) - led_exp = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - mem_base, mem_data = rc.alloc_region(16*1024*1024) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 4*1024*1024) - dev.functions[0].configure_bar(1, 4*1024*1024) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - #pcie_rq_seq_num0=pcie_rq_seq_num0, - #pcie_rq_seq_num_vld0=pcie_rq_seq_num_vld0, - #pcie_rq_seq_num1=pcie_rq_seq_num1, - #pcie_rq_seq_num_vld1=pcie_rq_seq_num_vld1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - #cfg_fc_ph=cfg_fc_ph, - #cfg_fc_pd=cfg_fc_pd, - #cfg_fc_nph=cfg_fc_nph, - #cfg_fc_npd=cfg_fc_npd, - #cfg_fc_cplh=cfg_fc_cplh, - #cfg_fc_cpld=cfg_fc_cpld, - #cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - #user_lnk_up=user_lnk_up, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=user_clk, - rst=user_reset, - current_test=current_test, - led_red=led_red, - led_green=led_green, - led_bmc=led_bmc, - led_exp=led_exp, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - dev_pf0_bar0 = dev.functions[0].bar[0] & 0xfffffffc - dev_pf0_bar1 = dev.functions[0].bar[1] & 0xfffffffc - - yield delay(100) - - yield clk.posedge - print("test 2: memory write to bar 1") - current_test.next = 2 - - yield rc.mem_write(dev_pf0_bar1, b'\x11\x22\x33\x44') - - yield delay(100) - - yield clk.posedge - print("test 3: memory read from bar 1") - current_test.next = 3 - - val = yield from rc.mem_read(dev_pf0_bar1, 4, 1000) - print(val) - assert val == b'\x11\x22\x33\x44' - - yield delay(100) - - yield clk.posedge - print("test 4: test DMA") - current_test.next = 4 - - # write packet data - mem_data[0:1024] = bytearray([x%256 for x in range(1024)]) - - # enable DMA - yield rc.mem_write(dev_pf0_bar0+0x100000, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100108, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100110, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100208, struct.pack('> 32) & 0xffffffff)) - yield rc.mem_write(dev_pf0_bar0+0x100210, struct.pack('