mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-06-28 09:16:22 -04:00
Spike Tandem Implementation using VCS simulator (#1561)
This commit is contained in:
parent
3c45510934
commit
220f534b6d
31 changed files with 354 additions and 638 deletions
42
.github/workflows/ci.yml
vendored
42
.github/workflows/ci.yml
vendored
|
@ -7,8 +7,30 @@ name: ci
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
riscv-tests:
|
build-riscv-tests:
|
||||||
name: riscv-tests
|
name: build-riscv-tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RISCV: /riscv
|
||||||
|
NUM_JOBS: 4
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
ci/setup.sh
|
||||||
|
tar -cf tools.tar tools
|
||||||
|
tar -cf tmp.tar tmp
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: compiled-tools
|
||||||
|
path: |
|
||||||
|
tools.tar
|
||||||
|
tmp.tar
|
||||||
|
execute-riscv-tests:
|
||||||
|
name: execute-riscv-tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -16,11 +38,19 @@ jobs:
|
||||||
target: [cv64a6_imafdc_sv39, cv64a6_imafdc_sv39_wb]
|
target: [cv64a6_imafdc_sv39, cv64a6_imafdc_sv39_wb]
|
||||||
env:
|
env:
|
||||||
RISCV: /riscv
|
RISCV: /riscv
|
||||||
|
needs:
|
||||||
|
build-riscv-tests
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Prepare
|
- name: Download a single artifact
|
||||||
run: ci/setup.sh
|
uses: actions/download-artifact@v3
|
||||||
- name: run tests
|
with:
|
||||||
run: make run-${{ matrix.testcase}}-verilator target=${{ matrix.target }}
|
name: compiled-tools
|
||||||
|
- name: Run Tests
|
||||||
|
run: |
|
||||||
|
tar xf tools.tar
|
||||||
|
tar xf tmp.tar
|
||||||
|
source verif/regress/install-cva6.sh
|
||||||
|
make run-${{ matrix.testcase}}-verilator target=${{ matrix.target }}
|
||||||
|
|
|
@ -139,6 +139,24 @@ smoke:
|
||||||
- source verif/regress/smoke-tests.sh
|
- source verif/regress/smoke-tests.sh
|
||||||
- !reference [.simu_after_script]
|
- !reference [.simu_after_script]
|
||||||
|
|
||||||
|
smoke-tandem:
|
||||||
|
extends:
|
||||||
|
- .fe_smoke_test
|
||||||
|
variables:
|
||||||
|
DASHBOARD_JOB_TITLE: "Smoke test $DV_SIMULATORS with tandem"
|
||||||
|
DASHBOARD_JOB_DESCRIPTION: "Short tests to challenge most architectures with most testbenchs configurations"
|
||||||
|
DASHBOARD_SORT_INDEX: 0
|
||||||
|
DASHBOARD_JOB_CATEGORY: "Basic"
|
||||||
|
SPIKE_TANDEM: 1
|
||||||
|
parallel:
|
||||||
|
matrix:
|
||||||
|
- DV_SIMULATORS:
|
||||||
|
- "vcs-testharness,spike"
|
||||||
|
- "vcs-uvm,spike"
|
||||||
|
script:
|
||||||
|
- source verif/regress/smoke-tests.sh
|
||||||
|
- !reference [.simu_after_script]
|
||||||
|
|
||||||
gen_smoke:
|
gen_smoke:
|
||||||
extends:
|
extends:
|
||||||
- .fe_smoke_test
|
- .fe_smoke_test
|
||||||
|
|
64
Makefile
64
Makefile
|
@ -25,17 +25,18 @@ VCOM ?= vcom$(questa_version)
|
||||||
VLIB ?= vlib$(questa_version)
|
VLIB ?= vlib$(questa_version)
|
||||||
VMAP ?= vmap$(questa_version)
|
VMAP ?= vmap$(questa_version)
|
||||||
# verilator version
|
# verilator version
|
||||||
verilator ?= $(PWD)/tmp/verilator-v5.008/verilator/bin/verilator
|
VERILATOR_INSTALL_DIR ?= $(PWD)/tmp/verilator-v5.008/verilator/
|
||||||
|
verilator ?= verilator
|
||||||
# traget option
|
# traget option
|
||||||
target-options ?=
|
target-options ?=
|
||||||
# additional definess
|
# additional defines
|
||||||
defines ?=
|
defines ?=
|
||||||
# test name for torture runs (binary name)
|
# test name for torture runs (binary name)
|
||||||
test-location ?= output/test
|
test-location ?= output/test
|
||||||
# set to either nothing or -log
|
# set to either nothing or -log
|
||||||
torture-logs :=
|
torture-logs :=
|
||||||
# custom elf bin to run with sim or sim-verilator
|
# custom elf bin to run with sim or sim-verilator
|
||||||
elf-bin ?= tmp/riscv-tests/build/benchmarks/dhrystone.riscv
|
elf_file ?= tmp/riscv-tests/build/benchmarks/dhrystone.riscv
|
||||||
# board name for bitstream generation. Currently supported: kc705, genesys2
|
# board name for bitstream generation. Currently supported: kc705, genesys2
|
||||||
BOARD ?= genesys2
|
BOARD ?= genesys2
|
||||||
# root path
|
# root path
|
||||||
|
@ -58,7 +59,9 @@ ifndef RISCV
|
||||||
$(error RISCV not set - please point your RISCV variable to your RISCV installation)
|
$(error RISCV not set - please point your RISCV variable to your RISCV installation)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# By default assume spike resides at $(root-dir)/tools/spike prefix.
|
# Spike tandem mode: default to environment setting (DISABLED if envariable SPIKE_TANDEM is not set).
|
||||||
|
spike-tandem ?= $(SPIKE_TANDEM)
|
||||||
|
|
||||||
SPIKE_INSTALL_DIR ?= $(root-dir)/tools/spike
|
SPIKE_INSTALL_DIR ?= $(root-dir)/tools/spike
|
||||||
|
|
||||||
# setting additional xilinx board parameters for the selected board
|
# setting additional xilinx board parameters for the selected board
|
||||||
|
@ -79,11 +82,10 @@ $(error Unknown board - please specify a supported FPGA board)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# spike tandem verification
|
# spike tandem verification
|
||||||
ifdef spike-tandem
|
ifneq ($(spike-tandem),)
|
||||||
compile_flag += -define SPIKE_TANDEM
|
compile_flag += -define SPIKE_TANDEM
|
||||||
ifndef preload
|
CFLAGS += -I. -I$(SPIKE_INSTALL_DIR)/include/riscv
|
||||||
$(error Tandem verification requires preloading)
|
defines += +SPIKE_TANDEM=1
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# target takes one of the following cva6 hardware configuration:
|
# target takes one of the following cva6 hardware configuration:
|
||||||
|
@ -123,7 +125,7 @@ test_pkg := $(wildcard tb/test/*/*sequence_pkg.sv*) \
|
||||||
dpi := $(patsubst corev_apu/tb/dpi/%.cc, ${dpi-library}/%.o, $(wildcard corev_apu/tb/dpi/*.cc))
|
dpi := $(patsubst corev_apu/tb/dpi/%.cc, ${dpi-library}/%.o, $(wildcard corev_apu/tb/dpi/*.cc))
|
||||||
|
|
||||||
# filter spike stuff if tandem is not activated
|
# filter spike stuff if tandem is not activated
|
||||||
ifndef spike-tandem
|
ifeq ($(spike-tandem),)
|
||||||
dpi := $(filter-out ${dpi-library}/spike.o ${dpi-library}/sim_spike.o, $(dpi))
|
dpi := $(filter-out ${dpi-library}/spike.o ${dpi-library}/sim_spike.o, $(dpi))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -131,6 +133,7 @@ dpi_hdr := $(wildcard corev_apu/tb/dpi/*.h)
|
||||||
dpi_hdr := $(addprefix $(root-dir), $(dpi_hdr))
|
dpi_hdr := $(addprefix $(root-dir), $(dpi_hdr))
|
||||||
CFLAGS += -I$(QUESTASIM_HOME)/include \
|
CFLAGS += -I$(QUESTASIM_HOME)/include \
|
||||||
-I$(VCS_HOME)/include \
|
-I$(VCS_HOME)/include \
|
||||||
|
-I$(VL_INC_DIR)/vltstd \
|
||||||
-I$(RISCV)/include \
|
-I$(RISCV)/include \
|
||||||
-I$(SPIKE_INSTALL_DIR)/include \
|
-I$(SPIKE_INSTALL_DIR)/include \
|
||||||
-std=c++17 -I../corev_apu/tb/dpi -O3
|
-std=c++17 -I../corev_apu/tb/dpi -O3
|
||||||
|
@ -141,13 +144,10 @@ else
|
||||||
$(warning XCELIUM_HOME not set which is necessary for compiling DPIs when using XCELIUM)
|
$(warning XCELIUM_HOME not set which is necessary for compiling DPIs when using XCELIUM)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef spike-tandem
|
|
||||||
CFLAGS += -Itb/riscv-isa-sim/install/include/spike
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# this list contains the standalone components
|
# this list contains the standalone components
|
||||||
src := core/include/$(target)_config_pkg.sv \
|
src := core/include/$(target)_config_pkg.sv \
|
||||||
|
$(if $(spike-tandem),verif/tb/core/rvfi_pkg.sv) \
|
||||||
|
$(if $(spike-tandem),corev_apu/tb/common/spike.sv) \
|
||||||
corev_apu/src/ariane.sv \
|
corev_apu/src/ariane.sv \
|
||||||
$(wildcard corev_apu/bootrom/*.sv) \
|
$(wildcard corev_apu/bootrom/*.sv) \
|
||||||
$(wildcard corev_apu/clint/*.sv) \
|
$(wildcard corev_apu/clint/*.sv) \
|
||||||
|
@ -215,6 +215,7 @@ fpga_src := $(addprefix $(root-dir), $(fpga_src))
|
||||||
|
|
||||||
# look for testbenches
|
# look for testbenches
|
||||||
tbs := core/include/$(target)_config_pkg.sv corev_apu/tb/ariane_tb.sv corev_apu/tb/ariane_testharness.sv
|
tbs := core/include/$(target)_config_pkg.sv corev_apu/tb/ariane_tb.sv corev_apu/tb/ariane_testharness.sv
|
||||||
|
|
||||||
tbs := $(addprefix $(root-dir), $(tbs))
|
tbs := $(addprefix $(root-dir), $(tbs))
|
||||||
|
|
||||||
# RISCV asm tests and benchmark setup (used for CI)
|
# RISCV asm tests and benchmark setup (used for CI)
|
||||||
|
@ -233,7 +234,9 @@ riscv-fp-tests := $(shell xargs printf '\n%s' < $(riscv-fp-tests-list
|
||||||
riscv-benchmarks := $(shell xargs printf '\n%s' < $(riscv-benchmarks-list) | cut -b 1-)
|
riscv-benchmarks := $(shell xargs printf '\n%s' < $(riscv-benchmarks-list) | cut -b 1-)
|
||||||
|
|
||||||
# Search here for include files (e.g.: non-standalone components)
|
# Search here for include files (e.g.: non-standalone components)
|
||||||
incdir := vendor/pulp-platform/common_cells/include/ vendor/pulp-platform/axi/include/ corev_apu/register_interface/include/
|
incdir := $(CVA6_REPO_DIR)/vendor/pulp-platform/common_cells/include/ $(CVA6_REPO_DIR)/vendor/pulp-platform/axi/include/ \
|
||||||
|
$(CVA6_REPO_DIR)/corev_apu/register_interface/include/ $(CVA6_REPO_DIR)/corev_apu/tb/common/ \
|
||||||
|
$(CVA6_REPO_DIR)/vendor/pulp-platform/axi/include/ $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_rvfi/
|
||||||
|
|
||||||
# Compile and sim flags
|
# Compile and sim flags
|
||||||
compile_flag += +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive -svinputport=compat +define+$(defines)
|
compile_flag += +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive -svinputport=compat +define+$(defines)
|
||||||
|
@ -263,11 +266,11 @@ endif
|
||||||
# we want to preload the memories
|
# we want to preload the memories
|
||||||
ifdef preload
|
ifdef preload
|
||||||
questa-cmd += +PRELOAD=$(preload)
|
questa-cmd += +PRELOAD=$(preload)
|
||||||
elf-bin = none
|
elf_file = none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef spike-tandem
|
ifdef spike-tandem
|
||||||
questa-cmd += -gblso tb/riscv-isa-sim/install/lib/libriscv.so
|
questa-cmd += -gblso $(SPIKE_INSTALL_DIR)/lib/libriscv.so
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# remote bitbang is enabled
|
# remote bitbang is enabled
|
||||||
|
@ -280,16 +283,19 @@ endif
|
||||||
vcs_build: $(dpi-library)/ariane_dpi.so
|
vcs_build: $(dpi-library)/ariane_dpi.so
|
||||||
mkdir -p $(vcs-library)
|
mkdir -p $(vcs-library)
|
||||||
cd $(vcs-library) &&\
|
cd $(vcs-library) &&\
|
||||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) -assert svaext -f ../core/Flist.cva6 &&\
|
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) -assert svaext -f ../core/Flist.cva6 $(list_incdir) &&\
|
||||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) $(filter %.sv,$(ariane_pkg)) +incdir+core/include/+$(VCS_HOME)/etc/uvm-1.2/dpi &&\
|
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) $(filter %.sv,$(ariane_pkg)) +incdir+core/include/+$(VCS_HOME)/etc/uvm-1.2/dpi &&\
|
||||||
vhdlan $(if $(VERDI), -kdb,) -full64 -nc $(filter %.vhd,$(uart_src)) &&\
|
vhdlan $(if $(VERDI), -kdb,) -full64 -nc $(filter %.vhd,$(uart_src)) &&\
|
||||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -assert svaext +define+$(defines) $(filter %.sv,$(src)) +incdir+../vendor/pulp-platform/common_cells/include/+../vendor/pulp-platform/axi/include/+../corev_apu/register_interface/include/ &&\
|
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -assert svaext +define+$(defines) +incdir+$(VCS_HOME)/etc/uvm/src $(VCS_HOME)/etc/uvm/src/uvm_pkg.sv $(filter %.sv,$(src)) $(list_incdir) &&\
|
||||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 &&\
|
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 &&\
|
||||||
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 $(tbs) +define+$(defines) +incdir+../vendor/pulp-platform/axi/include/ &&\
|
vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 $(tbs) +define+$(defines) $(list_incdir) &&\
|
||||||
vcs $(if $(VERDI), -kdb -debug_access+all -lca,) -full64 -timescale=1ns/1ns -ntb_opts uvm-1.2 work.ariane_tb -error="IWNF"
|
vcs $(if $(VERDI), -kdb -debug_access+all -lca,) -full64 -timescale=1ns/1ns -ntb_opts uvm-1.2 work.ariane_tb -error="IWNF"
|
||||||
|
|
||||||
vcs: vcs_build
|
vcs: vcs_build
|
||||||
cd $(vcs-library) && ./simv $(if $(VERDI), -verdi -do $(root-dir)/util/init_testharness.do,) +permissive -sv_lib ../work-dpi/ariane_dpi +PRELOAD=$(elf-bin) +permissive-off ++$(elf-bin)| tee vcs.log
|
cd $(vcs-library) && \
|
||||||
|
./simv +permissive $(if $(VERDI), -verdi -do $(root-dir)/init_testharness.do,) \
|
||||||
|
+elf_file=$(elf_file) ++$(elf_file) $(if $(spike-tandem),-sv_lib $(SPIKE_INSTALL_DIR)/libriscv) \
|
||||||
|
-sv_lib ../work-dpi/ariane_dpi | tee vcs.log
|
||||||
|
|
||||||
# Build the TB and module using QuestaSim
|
# Build the TB and module using QuestaSim
|
||||||
build: $(library) $(library)/.build-srcs $(library)/.build-tb $(dpi-library)/ariane_dpi.so
|
build: $(library) $(library)/.build-srcs $(library)/.build-tb $(dpi-library)/ariane_dpi.so
|
||||||
|
@ -322,20 +328,20 @@ $(dpi-library)/%.o: corev_apu/tb/dpi/%.cc $(dpi_hdr)
|
||||||
$(dpi-library)/ariane_dpi.so: $(dpi)
|
$(dpi-library)/ariane_dpi.so: $(dpi)
|
||||||
mkdir -p $(dpi-library)
|
mkdir -p $(dpi-library)
|
||||||
# Compile C-code and generate .so file
|
# Compile C-code and generate .so file
|
||||||
$(CXX) -shared -m64 -o $(dpi-library)/ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr
|
$(CXX) -shared -m64 -o $(dpi-library)/ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv
|
||||||
|
|
||||||
# single test runs on Questa can be started by calling make <testname>, e.g. make towers.riscv
|
# single test runs on Questa can be started by calling make <testname>, e.g. make towers.riscv
|
||||||
# the test names are defined in ci/riscv-asm-tests.list, and in ci/riscv-benchmarks.list
|
# the test names are defined in ci/riscv-asm-tests.list, and in ci/riscv-benchmarks.list
|
||||||
# if you want to run in batch mode, use make <testname> batch-mode=1
|
# if you want to run in batch mode, use make <testname> batch-mode=1
|
||||||
# alternatively you can call make sim elf-bin=<path/to/elf-bin> in order to load an arbitrary binary
|
# alternatively you can call make sim elf_file=<path/to/elf_file> in order to load an arbitrary binary
|
||||||
generate-trace-vsim:
|
generate-trace-vsim:
|
||||||
make sim preload=$(preload) elf-bin= batch-mode=1
|
make sim preload=$(preload) elf_file= batch-mode=1
|
||||||
make generate-trace
|
make generate-trace
|
||||||
|
|
||||||
sim: build
|
sim: build
|
||||||
$(VSIM) +permissive $(questa-flags) $(questa-cmd) -lib $(library) +MAX_CYCLES=$(max_cycles) +UVM_TESTNAME=$(test_case) \
|
$(VSIM) +permissive $(questa-flags) $(questa-cmd) -lib $(library) +MAX_CYCLES=$(max_cycles) +UVM_TESTNAME=$(test_case) \
|
||||||
+BASEDIR=$(riscv-test-dir) $(uvm-flags) $(QUESTASIM_FLAGS) -gblso $(SPIKE_INSTALL_DIR)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
|
+BASEDIR=$(riscv-test-dir) $(uvm-flags) $(QUESTASIM_FLAGS) -gblso $(SPIKE_INSTALL_DIR)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
|
||||||
${top_level}_optimized +permissive-off ++$(elf-bin) ++$(target-options) | tee sim.log
|
${top_level}_optimized +permissive-off ++$(elf_file) ++$(target-options) | tee sim.log
|
||||||
|
|
||||||
$(riscv-asm-tests): build
|
$(riscv-asm-tests): build
|
||||||
$(VSIM) +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
|
$(VSIM) +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
|
||||||
|
@ -463,7 +469,7 @@ xrun_sim: xrun_comp
|
||||||
+UVM_TESTNAME=$(test_case) \
|
+UVM_TESTNAME=$(test_case) \
|
||||||
-l $(XRUN_RUN_LOG) \
|
-l $(XRUN_RUN_LOG) \
|
||||||
+permissive-off \
|
+permissive-off \
|
||||||
++$(elf-bin)
|
++$(elf_file)
|
||||||
|
|
||||||
#-e "set_severity_pack_assert_off {warning}; set_pack_assert_off {numeric_std}" TODO: This will remove assertion warning at the beginning of the simulation.
|
#-e "set_severity_pack_assert_off {warning}; set_pack_assert_off {numeric_std}" TODO: This will remove assertion warning at the beginning of the simulation.
|
||||||
|
|
||||||
|
@ -561,8 +567,9 @@ verilate_command := $(verilator) --no-timing verilator_config.vlt
|
||||||
$(if $(DEBUG), --trace-structs,) \
|
$(if $(DEBUG), --trace-structs,) \
|
||||||
$(if $(TRACE_COMPACT), --trace-fst $(VL_INC_DIR)/verilated_fst_c.cpp) \
|
$(if $(TRACE_COMPACT), --trace-fst $(VL_INC_DIR)/verilated_fst_c.cpp) \
|
||||||
$(if $(TRACE_FAST), --trace $(VL_INC_DIR)/verilated_vcd_c.cpp) \
|
$(if $(TRACE_FAST), --trace $(VL_INC_DIR)/verilated_vcd_c.cpp) \
|
||||||
-LDFLAGS "-L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr$(if $(PROFILE), -g -pg,) -lpthread $(if $(TRACE_COMPACT), -lz,)" \
|
-LDFLAGS "-L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv $(if $(PROFILE), -g -pg,) -lpthread $(if $(TRACE_COMPACT), -lz,)" \
|
||||||
-CFLAGS "$(CFLAGS)$(if $(PROFILE), -g -pg,) -DVL_DEBUG" \
|
-CFLAGS "$(CFLAGS)$(if $(PROFILE), -g -pg,) -DVL_DEBUG" \
|
||||||
|
$(if $(SPIKE_TANDEM), +define+SPIKE_TANDEM, ) \
|
||||||
--cc --vpi \
|
--cc --vpi \
|
||||||
$(list_incdir) --top-module ariane_testharness \
|
$(list_incdir) --top-module ariane_testharness \
|
||||||
--threads-dpi none \
|
--threads-dpi none \
|
||||||
|
@ -570,7 +577,6 @@ verilate_command := $(verilator) --no-timing verilator_config.vlt
|
||||||
--exe corev_apu/tb/ariane_tb.cpp corev_apu/tb/dpi/SimDTM.cc corev_apu/tb/dpi/SimJTAG.cc \
|
--exe corev_apu/tb/ariane_tb.cpp corev_apu/tb/dpi/SimDTM.cc corev_apu/tb/dpi/SimJTAG.cc \
|
||||||
corev_apu/tb/dpi/remote_bitbang.cc corev_apu/tb/dpi/msim_helper.cc
|
corev_apu/tb/dpi/remote_bitbang.cc corev_apu/tb/dpi/msim_helper.cc
|
||||||
|
|
||||||
|
|
||||||
# User Verilator, at some point in the future this will be auto-generated
|
# User Verilator, at some point in the future this will be auto-generated
|
||||||
verilate:
|
verilate:
|
||||||
@echo "[Verilator] Building Model$(if $(PROFILE), for Profiling,)"
|
@echo "[Verilator] Building Model$(if $(PROFILE), for Profiling,)"
|
||||||
|
@ -578,7 +584,7 @@ verilate:
|
||||||
cd $(ver-library) && $(MAKE) -j${NUM_JOBS} -f Variane_testharness.mk
|
cd $(ver-library) && $(MAKE) -j${NUM_JOBS} -f Variane_testharness.mk
|
||||||
|
|
||||||
sim-verilator: verilate
|
sim-verilator: verilate
|
||||||
$(ver-library)/Variane_testharness $(elf-bin)
|
$(ver-library)/Variane_testharness $(elf_file)
|
||||||
|
|
||||||
$(addsuffix -verilator,$(riscv-asm-tests)): verilate
|
$(addsuffix -verilator,$(riscv-asm-tests)): verilate
|
||||||
$(ver-library)/Variane_testharness $(riscv-test-dir)/$(subst -verilator,,$@)
|
$(ver-library)/Variane_testharness $(riscv-test-dir)/$(subst -verilator,,$@)
|
||||||
|
|
10
ci/setup.sh
10
ci/setup.sh
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
export ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
export ROOT_PROJECT=$ROOT
|
||||||
|
|
||||||
export PATH=$RISCV/bin:/bin:$PATH
|
export PATH=$RISCV/bin:/bin:$PATH
|
||||||
export LIBRARY_PATH=$RISCV/lib
|
export LIBRARY_PATH=$RISCV/lib
|
||||||
|
@ -15,13 +16,14 @@ sudo apt install device-tree-compiler
|
||||||
|
|
||||||
ci/make-tmp.sh
|
ci/make-tmp.sh
|
||||||
|
|
||||||
ci/install-verilator.sh
|
|
||||||
|
|
||||||
sudo mkdir -p $RISCV && sudo chmod 777 $RISCV
|
sudo mkdir -p $RISCV && sudo chmod 777 $RISCV
|
||||||
RISCV64_UNKNOWN_ELF_GCC=riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-linux-ubuntu14.tar.gz
|
RISCV64_UNKNOWN_ELF_GCC=riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-linux-ubuntu14.tar.gz
|
||||||
if [ ! -f "$RISCV64_UNKNOWN_ELF_GCC" ]; then
|
if [ ! -f "$RISCV64_UNKNOWN_ELF_GCC" ]; then
|
||||||
wget https://static.dev.sifive.com/dev-tools/$RISCV64_UNKNOWN_ELF_GCC
|
wget https://static.dev.sifive.com/dev-tools/$RISCV64_UNKNOWN_ELF_GCC
|
||||||
fi
|
fi
|
||||||
tar -x -f $RISCV64_UNKNOWN_ELF_GCC --strip-components=1 -C $RISCV
|
tar -x -f $RISCV64_UNKNOWN_ELF_GCC --strip-components=1 -C $RISCV
|
||||||
ci/install-fesvr.sh
|
|
||||||
|
sudo apt install libfl-dev help2man
|
||||||
|
|
||||||
|
verif/regress/install-cva6.sh
|
||||||
ci/build-riscv-tests.sh
|
ci/build-riscv-tests.sh
|
||||||
|
|
|
@ -562,7 +562,7 @@ module csr_regfile
|
||||||
end
|
end
|
||||||
instret_d = instret;
|
instret_d = instret;
|
||||||
// increment the cycle count
|
// increment the cycle count
|
||||||
if (ENABLE_CYCLE_COUNT && !mcountinhibit_q[0]) cycle_d = cycle_q + 1'b1;
|
if (!mcountinhibit_q[0]) cycle_d = cycle_q + 1'b1;
|
||||||
else cycle_d = instret;
|
else cycle_d = instret;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
18
core/cva6.sv
18
core/cva6.sv
|
@ -1348,27 +1348,15 @@ module cva6
|
||||||
if (IsRVFI) begin
|
if (IsRVFI) begin
|
||||||
always_comb begin
|
always_comb begin
|
||||||
for (int i = 0; i < CVA6ExtendCfg.NrCommitPorts; i++) begin
|
for (int i = 0; i < CVA6ExtendCfg.NrCommitPorts; i++) begin
|
||||||
logic exception, mem_exception;
|
logic exception;
|
||||||
exception = commit_instr_id_commit[i].valid && ex_commit.valid;
|
exception = commit_instr_id_commit[i].valid && ex_commit.valid;
|
||||||
mem_exception = exception &&
|
|
||||||
(ex_commit.cause == riscv::INSTR_ADDR_MISALIGNED ||
|
|
||||||
ex_commit.cause == riscv::INSTR_ACCESS_FAULT ||
|
|
||||||
ex_commit.cause == riscv::ILLEGAL_INSTR ||
|
|
||||||
ex_commit.cause == riscv::LD_ADDR_MISALIGNED ||
|
|
||||||
ex_commit.cause == riscv::LD_ACCESS_FAULT ||
|
|
||||||
ex_commit.cause == riscv::ST_ADDR_MISALIGNED ||
|
|
||||||
ex_commit.cause == riscv::ST_ACCESS_FAULT ||
|
|
||||||
ex_commit.cause == riscv::INSTR_PAGE_FAULT ||
|
|
||||||
ex_commit.cause == riscv::LOAD_PAGE_FAULT ||
|
|
||||||
ex_commit.cause == riscv::STORE_PAGE_FAULT);
|
|
||||||
// when rvfi_valid, the instruction is executed
|
|
||||||
rvfi_o[i].valid = (commit_ack[i] && !ex_commit.valid) ||
|
rvfi_o[i].valid = (commit_ack[i] && !ex_commit.valid) ||
|
||||||
(exception && (ex_commit.cause == riscv::ENV_CALL_MMODE ||
|
(exception && (ex_commit.cause == riscv::ENV_CALL_MMODE ||
|
||||||
ex_commit.cause == riscv::ENV_CALL_SMODE ||
|
ex_commit.cause == riscv::ENV_CALL_SMODE ||
|
||||||
ex_commit.cause == riscv::ENV_CALL_UMODE));
|
ex_commit.cause == riscv::ENV_CALL_UMODE));
|
||||||
rvfi_o[i].insn = ex_commit.valid ? ex_commit.tval[31:0] : commit_instr_id_commit[i].ex.tval[31:0];
|
rvfi_o[i].insn = ex_commit.valid ? ex_commit.tval[31:0] : commit_instr_id_commit[i].ex.tval[31:0];
|
||||||
// when trap, the instruction is not executed
|
// when trap, the instruction is not executed
|
||||||
rvfi_o[i].trap = mem_exception;
|
rvfi_o[i].trap = exception;
|
||||||
rvfi_o[i].cause = ex_commit.cause;
|
rvfi_o[i].cause = ex_commit.cause;
|
||||||
rvfi_o[i].mode = (CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl;
|
rvfi_o[i].mode = (CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl;
|
||||||
rvfi_o[i].ixl = riscv::XLEN == 64 ? 2 : 1;
|
rvfi_o[i].ixl = riscv::XLEN == 64 ? 2 : 1;
|
||||||
|
|
|
@ -183,7 +183,7 @@ module decoder
|
||||||
end
|
end
|
||||||
// WFI
|
// WFI
|
||||||
12'b1_0000_0101: begin
|
12'b1_0000_0101: begin
|
||||||
if (ENABLE_WFI) instruction_o.op = ariane_pkg::WFI;
|
instruction_o.op = ariane_pkg::WFI;
|
||||||
// if timeout wait is set, trap on an illegal instruction in S Mode
|
// if timeout wait is set, trap on an illegal instruction in S Mode
|
||||||
// (after 0 cycles timeout)
|
// (after 0 cycles timeout)
|
||||||
if (CVA6Cfg.RVS && priv_lvl_i == riscv::PRIV_LVL_S && tw_i) begin
|
if (CVA6Cfg.RVS && priv_lvl_i == riscv::PRIV_LVL_S && tw_i) begin
|
||||||
|
|
|
@ -107,22 +107,17 @@ package ariane_pkg;
|
||||||
// enables a commit log which matches spikes commit log format for easier trace comparison
|
// enables a commit log which matches spikes commit log format for easier trace comparison
|
||||||
localparam bit ENABLE_SPIKE_COMMIT_LOG = 1'b1;
|
localparam bit ENABLE_SPIKE_COMMIT_LOG = 1'b1;
|
||||||
|
|
||||||
// ------------- Dangerouse -------------
|
// ------------- Dangerous -------------
|
||||||
// if set to zero a flush will not invalidate the cache-lines, in a single core environment
|
// if set to zero a flush will not invalidate the cache-lines, in a single core environment
|
||||||
// where coherence is not necessary this can improve performance. This needs to be switched on
|
// where coherence is not necessary this can improve performance. This needs to be switched on
|
||||||
// when more than one core is in a system
|
// when more than one core is in a system
|
||||||
localparam logic INVALIDATE_ON_FLUSH = 1'b1;
|
localparam logic INVALIDATE_ON_FLUSH = 1'b1;
|
||||||
|
|
||||||
`ifdef SPIKE_TANDEM
|
`ifdef SPIKE_TANDEM
|
||||||
// enable performance cycle counter, if set to zero mcycle will be incremented
|
// Spike still places 0 in TVAL for ENV_CALL_* exceptions.
|
||||||
// with instret (non RISC-V conformal)
|
// This may eventually go away when Spike starts to handle TVAL for *all* exceptions.
|
||||||
localparam bit ENABLE_CYCLE_COUNT = 1'b0;
|
|
||||||
// mark WIF as nop
|
|
||||||
localparam bit ENABLE_WFI = 1'b0;
|
|
||||||
// Spike zeros tval on all exception except memory faults
|
|
||||||
localparam bit ZERO_TVAL = 1'b1;
|
localparam bit ZERO_TVAL = 1'b1;
|
||||||
`else
|
`else
|
||||||
localparam bit ENABLE_CYCLE_COUNT = 1'b1;
|
|
||||||
localparam bit ENABLE_WFI = 1'b1;
|
|
||||||
localparam bit ZERO_TVAL = 1'b0;
|
localparam bit ZERO_TVAL = 1'b0;
|
||||||
`endif
|
`endif
|
||||||
// read mask for SSTATUS over MMSTATUS
|
// read mask for SSTATUS over MMSTATUS
|
||||||
|
|
|
@ -62,6 +62,12 @@ void handle_sigterm(int sig) {
|
||||||
dtm->stop();
|
dtm->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void read_elf(const char* filename);
|
||||||
|
extern "C" int64_t read_symbol(const char* symbol, uint64_t* address);
|
||||||
|
extern "C" char get_section (long long* address, long long* len);
|
||||||
|
extern "C" void read_section_void(long long address, void * buffer, uint64_t size = 0);
|
||||||
|
|
||||||
// Called by $time in Verilog converts to double, to match what SystemC does
|
// Called by $time in Verilog converts to double, to match what SystemC does
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp () {
|
||||||
return main_time;
|
return main_time;
|
||||||
|
@ -285,11 +291,7 @@ done_processing:
|
||||||
|
|
||||||
std::unique_ptr<Variane_testharness> top(new Variane_testharness);
|
std::unique_ptr<Variane_testharness> top(new Variane_testharness);
|
||||||
|
|
||||||
// Use an hitf hexwriter to read the binary data.
|
read_elf(htif_argv[1]);
|
||||||
htif_hexwriter_t htif(0x0, 1, -1);
|
|
||||||
memif_t memif(&htif);
|
|
||||||
reg_t entry;
|
|
||||||
load_elf(htif_argv[1], &memif, &entry);
|
|
||||||
|
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||||
|
@ -335,15 +337,22 @@ done_processing:
|
||||||
top->rst_ni = 1;
|
top->rst_ni = 1;
|
||||||
|
|
||||||
// Preload memory.
|
// Preload memory.
|
||||||
size_t mem_size = 0xFFFFFF;
|
|
||||||
#if (VERILATOR_VERSION_INTEGER >= 5000000)
|
#if (VERILATOR_VERSION_INTEGER >= 5000000)
|
||||||
// Verilator v5: Use rootp pointer and .data() accessor.
|
// Verilator v5: Use rootp pointer and .data() accessor.
|
||||||
memif.read(0x80000000, mem_size, (void *)top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram.m_storage);
|
#define MEM top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram.m_storage
|
||||||
#else
|
#else
|
||||||
// Verilator v4
|
// Verilator v4
|
||||||
memif.read(0x80000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram);
|
#define MEM top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram
|
||||||
#endif
|
#endif
|
||||||
// memif.read(0x84000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__gen_mem_user__DOT__i_tc_sram_wrapper_user__DOT__i_tc_sram__DOT__sram);
|
long long addr;
|
||||||
|
long long len;
|
||||||
|
|
||||||
|
size_t mem_size = 0xFFFFFF;
|
||||||
|
while(get_section(&addr, &len))
|
||||||
|
{
|
||||||
|
if (addr == 0x80000000)
|
||||||
|
read_section_void(addr, (void *) MEM , mem_size);
|
||||||
|
}
|
||||||
|
|
||||||
while (!dtm->done() && !jtag->done() && !(top->exit_o & 0x1)) {
|
while (!dtm->done() && !jtag->done() && !(top->exit_o & 0x1)) {
|
||||||
top->clk_i = 0;
|
top->clk_i = 0;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import uvm_pkg::*;
|
||||||
|
|
||||||
import "DPI-C" function read_elf(input string filename);
|
import "DPI-C" function read_elf(input string filename);
|
||||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
import "DPI-C" function byte get_section(output longint address, output longint len);
|
||||||
import "DPI-C" context function void read_section(input longint address, inout byte buffer[]);
|
import "DPI-C" context function void read_section_sv(input longint address, inout byte buffer[]);
|
||||||
|
|
||||||
module ariane_tb;
|
module ariane_tb;
|
||||||
|
|
||||||
|
@ -91,26 +91,6 @@ module ariane_tb;
|
||||||
.exit_o
|
.exit_o
|
||||||
);
|
);
|
||||||
|
|
||||||
`ifdef SPIKE_TANDEM
|
|
||||||
spike #(
|
|
||||||
.CVA6Cfg ( CVA6Cfg ),
|
|
||||||
.Size ( NUM_WORDS * 8 )
|
|
||||||
) i_spike (
|
|
||||||
.clk_i,
|
|
||||||
.rst_ni,
|
|
||||||
.clint_tick_i ( rtc_i ),
|
|
||||||
.commit_instr_i ( dut.i_ariane.commit_instr_id_commit ),
|
|
||||||
.commit_ack_i ( dut.i_ariane.commit_ack ),
|
|
||||||
.exception_i ( dut.i_ariane.ex_commit ),
|
|
||||||
.waddr_i ( dut.i_ariane.waddr_commit_id ),
|
|
||||||
.wdata_i ( dut.i_ariane.wdata_commit_id ),
|
|
||||||
.priv_lvl_i ( dut.i_ariane.priv_lvl )
|
|
||||||
);
|
|
||||||
initial begin
|
|
||||||
$display("Running binary in tandem mode");
|
|
||||||
end
|
|
||||||
`endif
|
|
||||||
|
|
||||||
// Clock process
|
// Clock process
|
||||||
initial begin
|
initial begin
|
||||||
clk_i = 1'b0;
|
clk_i = 1'b0;
|
||||||
|
@ -158,7 +138,7 @@ module ariane_tb;
|
||||||
automatic logic [7:0][7:0] mem_row;
|
automatic logic [7:0][7:0] mem_row;
|
||||||
longint address, len;
|
longint address, len;
|
||||||
byte buffer[];
|
byte buffer[];
|
||||||
void'(uvcl.get_arg_value("+PRELOAD=", binary));
|
void'(uvcl.get_arg_value("+elf_file=", binary));
|
||||||
|
|
||||||
if (binary != "") begin
|
if (binary != "") begin
|
||||||
`uvm_info( "Core Test", $sformatf("Preloading ELF: %s", binary), UVM_LOW)
|
`uvm_info( "Core Test", $sformatf("Preloading ELF: %s", binary), UVM_LOW)
|
||||||
|
@ -170,10 +150,9 @@ module ariane_tb;
|
||||||
// while there are more sections to process
|
// while there are more sections to process
|
||||||
while (get_section(address, len)) begin
|
while (get_section(address, len)) begin
|
||||||
automatic int num_words = (len+7)/8;
|
automatic int num_words = (len+7)/8;
|
||||||
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len),
|
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_LOW)
|
||||||
UVM_LOW)
|
|
||||||
buffer = new [num_words*8];
|
buffer = new [num_words*8];
|
||||||
void'(read_section(address, buffer));
|
void'(read_section_sv(address, buffer));
|
||||||
// preload memories
|
// preload memories
|
||||||
// 64-bit
|
// 64-bit
|
||||||
for (int i = 0; i < num_words; i++) begin
|
for (int i = 0; i < num_words; i++) begin
|
||||||
|
|
|
@ -584,12 +584,7 @@ module ariane_testharness #(
|
||||||
.AxiIdWidth ( ariane_axi_soc::IdWidthSlave ),
|
.AxiIdWidth ( ariane_axi_soc::IdWidthSlave ),
|
||||||
.AxiUserWidth ( AXI_USER_WIDTH ),
|
.AxiUserWidth ( AXI_USER_WIDTH ),
|
||||||
`ifndef VERILATOR
|
`ifndef VERILATOR
|
||||||
// disable UART when using Spike, as we need to rely on the mockuart
|
|
||||||
`ifdef SPIKE_TANDEM
|
|
||||||
.InclUART ( 1'b0 ),
|
|
||||||
`else
|
|
||||||
.InclUART ( 1'b1 ),
|
.InclUART ( 1'b1 ),
|
||||||
`endif
|
|
||||||
`else
|
`else
|
||||||
.InclUART ( 1'b0 ),
|
.InclUART ( 1'b0 ),
|
||||||
`endif
|
`endif
|
||||||
|
@ -691,6 +686,22 @@ module ariane_testharness #(
|
||||||
.end_of_test_o(rvfi_exit)
|
.end_of_test_o(rvfi_exit)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
`ifdef SPIKE_TANDEM
|
||||||
|
spike #(
|
||||||
|
.CVA6Cfg ( CVA6Cfg ),
|
||||||
|
.rvfi_instr_t(rvfi_instr_t)
|
||||||
|
) i_spike (
|
||||||
|
.clk_i,
|
||||||
|
.rst_ni,
|
||||||
|
.clint_tick_i ( rtc_i ),
|
||||||
|
.rvfi_i ( rvfi )
|
||||||
|
);
|
||||||
|
initial begin
|
||||||
|
$display("Running binary in tandem mode");
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
`ifdef AXI_SVA
|
`ifdef AXI_SVA
|
||||||
// AXI 4 Assertion IP integration - You will need to get your own copy of this IP if you want
|
// AXI 4 Assertion IP integration - You will need to get your own copy of this IP if you want
|
||||||
// to use it
|
// to use it
|
||||||
|
|
|
@ -12,111 +12,91 @@
|
||||||
// Date: 3/11/2018
|
// Date: 3/11/2018
|
||||||
// Description: Wrapped Spike Model for Tandem Verification
|
// Description: Wrapped Spike Model for Tandem Verification
|
||||||
|
|
||||||
import uvm_pkg::*;
|
import ariane_pkg::*;
|
||||||
|
import rvfi_pkg::*;
|
||||||
|
|
||||||
`include "uvm_macros.svh"
|
import "DPI-C" function void spike_step(inout st_rvfi rvfi);
|
||||||
|
|
||||||
import "DPI-C" function int spike_create(string filename, longint unsigned dram_base, int unsigned size);
|
|
||||||
|
|
||||||
typedef riscv::commit_log_t riscv_commit_log_t;
|
|
||||||
import "DPI-C" function void spike_tick(output riscv_commit_log_t commit_log);
|
|
||||||
|
|
||||||
import "DPI-C" function void clint_tick();
|
|
||||||
|
|
||||||
module spike #(
|
module spike #(
|
||||||
parameter longint unsigned DramBase = 'h8000_0000,
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg,
|
||||||
parameter int unsigned Size = 64 * 1024 * 1024 // 64 Mega Byte
|
parameter type rvfi_instr_t = struct packed {
|
||||||
|
logic [config_pkg::NRET-1:0] valid;
|
||||||
|
logic [config_pkg::NRET*64-1:0] order;
|
||||||
|
logic [config_pkg::NRET*config_pkg::ILEN-1:0] insn;
|
||||||
|
logic [config_pkg::NRET-1:0] trap;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] cause;
|
||||||
|
logic [config_pkg::NRET-1:0] halt;
|
||||||
|
logic [config_pkg::NRET-1:0] intr;
|
||||||
|
logic [config_pkg::NRET*2-1:0] mode;
|
||||||
|
logic [config_pkg::NRET*2-1:0] ixl;
|
||||||
|
logic [config_pkg::NRET*5-1:0] rs1_addr;
|
||||||
|
logic [config_pkg::NRET*5-1:0] rs2_addr;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] rs1_rdata;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] rs2_rdata;
|
||||||
|
logic [config_pkg::NRET*5-1:0] rd_addr;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] rd_wdata;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_rdata;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_wdata;
|
||||||
|
logic [config_pkg::NRET*riscv::VLEN-1:0] mem_addr;
|
||||||
|
logic [config_pkg::NRET*riscv::PLEN-1:0] mem_paddr;
|
||||||
|
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_rmask;
|
||||||
|
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_wmask;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata;
|
||||||
|
logic [config_pkg::NRET*riscv::XLEN-1:0] mem_wdata;
|
||||||
|
},
|
||||||
|
parameter longint unsigned DramBase = 'h8000_0000,
|
||||||
|
parameter int unsigned Size = 64 * 1024 * 1024 // 64 Mega Byte
|
||||||
)(
|
)(
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
input logic clint_tick_i,
|
input logic clint_tick_i,
|
||||||
input ariane_pkg::scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i,
|
input rvfi_instr_t[CVA6Cfg.NrCommitPorts-1:0] rvfi_i
|
||||||
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i,
|
|
||||||
input ariane_pkg::exception_t exception_i,
|
|
||||||
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i,
|
|
||||||
input logic [CVA6Cfg.NrCommitPorts-1:0][63:0] wdata_i,
|
|
||||||
input riscv::priv_lvl_t priv_lvl_i
|
|
||||||
);
|
);
|
||||||
static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
|
||||||
|
|
||||||
string binary = "";
|
string binary = "";
|
||||||
|
string rtl_isa = "";
|
||||||
logic fake_clk;
|
|
||||||
|
|
||||||
logic clint_tick_q, clint_tick_qq, clint_tick_qqq, clint_tick_qqqq;
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
void'(uvcl.get_arg_value("+PRELOAD=", binary));
|
rvfi_initialize_spike('h1);
|
||||||
assert(binary != "") else $error("We need a preloaded binary for tandem verification");
|
|
||||||
void'(spike_create(binary, DramBase, Size));
|
|
||||||
end
|
end
|
||||||
|
|
||||||
riscv_commit_log_t commit_log;
|
st_rvfi t_core, t_reference_model;
|
||||||
logic [31:0] instr;
|
logic [63:0] pc64;
|
||||||
|
logic [31:0] rtl_instr;
|
||||||
|
logic [31:0] spike_instr;
|
||||||
|
string cause;
|
||||||
|
string instr;
|
||||||
|
|
||||||
always_ff @(posedge clk_i) begin
|
always_ff @(posedge clk_i) begin
|
||||||
if (rst_ni) begin
|
if (rst_ni) begin
|
||||||
|
|
||||||
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
||||||
if ((commit_instr_i[i].valid && commit_ack_i[i]) || (commit_instr_i[i].valid && exception_i.valid)) begin
|
|
||||||
spike_tick(commit_log);
|
if (rvfi_i[i].valid || rvfi_i[i].trap) begin
|
||||||
instr = (commit_log.instr[1:0] != 2'b11) ? {16'b0, commit_log.instr[15:0]} : commit_log.instr;
|
spike_step(t_reference_model);
|
||||||
// $display("\x1B[32m%h %h\x1B[0m", commit_log.pc, instr);
|
t_core.order = rvfi_i[i].order;
|
||||||
// $display("%p", commit_log);
|
t_core.insn = rvfi_i[i].insn;
|
||||||
// $display("\x1B[37m%h %h\x1B[0m", commit_instr_i[i].pc, commit_instr_i[i].ex.tval[31:0]);
|
t_core.trap = rvfi_i[i].trap;
|
||||||
assert (commit_log.pc === commit_instr_i[i].pc) else begin
|
t_core.cause = rvfi_i[i].cause;
|
||||||
$warning("\x1B[33m[Tandem] PCs Mismatch\x1B[0m");
|
t_core.halt = rvfi_i[i].halt;
|
||||||
// $stop;
|
t_core.intr = rvfi_i[i].intr;
|
||||||
end
|
t_core.mode = rvfi_i[i].mode;
|
||||||
assert (commit_log.was_exception === exception_i.valid) else begin
|
t_core.ixl = rvfi_i[i].ixl;
|
||||||
$warning("\x1B[33m[Tandem] Exception not detected\x1B[0m");
|
t_core.rs1_addr = rvfi_i[i].rs1_addr;
|
||||||
// $stop;
|
t_core.rs2_addr = rvfi_i[i].rs2_addr;
|
||||||
$display("Spike: %p", commit_log);
|
t_core.rs1_rdata = rvfi_i[i].rs1_rdata;
|
||||||
$display("Ariane: %p", commit_instr_i[i]);
|
t_core.rs2_rdata = rvfi_i[i].rs2_rdata;
|
||||||
end
|
t_core.rd1_addr = rvfi_i[i].rd_addr;
|
||||||
if (!exception_i.valid) begin
|
t_core.rd1_wdata = rvfi_i[i].rd_wdata;
|
||||||
assert (commit_log.priv === priv_lvl_i) else begin
|
t_core.pc_rdata = rvfi_i[i].pc_rdata;
|
||||||
$warning("\x1B[33m[Tandem] Privilege level mismatches\x1B[0m");
|
t_core.pc_wdata = rvfi_i[i].pc_wdata;
|
||||||
// $stop;
|
t_core.mem_addr = rvfi_i[i].mem_addr;
|
||||||
$display("\x1B[37m %2d == %2d @ PC %h\x1B[0m", priv_lvl_i, commit_log.priv, commit_log.pc);
|
t_core.mem_rmask = rvfi_i[i].mem_rmask;
|
||||||
end
|
t_core.mem_wmask = rvfi_i[i].mem_wmask;
|
||||||
assert (instr === commit_instr_i[i].ex.tval) else begin
|
t_core.mem_rdata = rvfi_i[i].mem_rdata;
|
||||||
$warning("\x1B[33m[Tandem] Decoded instructions mismatch\x1B[0m");
|
t_core.mem_wdata = rvfi_i[i].mem_wdata;
|
||||||
// $stop;
|
|
||||||
$display("\x1B[37m%h === %h @ PC %h\x1B[0m", commit_instr_i[i].ex.tval, instr, commit_log.pc);
|
rvfi_compare(t_core, t_reference_model);
|
||||||
end
|
|
||||||
// TODO(zarubaf): Adapt for floating point instructions
|
|
||||||
if (commit_instr_i[i].rd != 0) begin
|
|
||||||
// check the return value
|
|
||||||
// $display("\x1B[37m%h === %h\x1B[0m", commit_instr_i[i].rd, commit_log.rd);
|
|
||||||
assert (waddr_i[i] === commit_log.rd) else begin
|
|
||||||
$warning("\x1B[33m[Tandem] Destination register mismatches\x1B[0m");
|
|
||||||
// $stop;
|
|
||||||
end
|
|
||||||
assert (wdata_i[i] === commit_log.data) else begin
|
|
||||||
$warning("\x1B[33m[Tandem] Write back data mismatches\x1B[0m");
|
|
||||||
$display("\x1B[37m%h === %h @ PC %h\x1B[0m", wdata_i[i], commit_log.data, commit_log.pc);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// we want to schedule the timer increment at the end of this cycle
|
|
||||||
assign #1ps fake_clk = clk_i;
|
|
||||||
|
|
||||||
always_ff @(posedge fake_clk) begin
|
|
||||||
clint_tick_q <= clint_tick_i;
|
|
||||||
clint_tick_qq <= clint_tick_q;
|
|
||||||
clint_tick_qqq <= clint_tick_qq;
|
|
||||||
clint_tick_qqqq <= clint_tick_qqq;
|
|
||||||
end
|
|
||||||
|
|
||||||
always_ff @(posedge clint_tick_qqqq) begin
|
|
||||||
if (rst_ni) begin
|
|
||||||
void'(clint_tick());
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
// See LICENSE for license details.
|
|
||||||
|
|
||||||
#include "sim_spike.h"
|
|
||||||
#include "mmu.h"
|
|
||||||
#include "dts.h"
|
|
||||||
#include <map>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cassert>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
sim_spike_t::sim_spike_t(const char* isa, size_t nprocs,
|
|
||||||
std::vector<std::pair<reg_t, mem_t*>> mems,
|
|
||||||
const std::vector<std::string>& args)
|
|
||||||
: mems(mems), procs(std::max(nprocs, size_t(1))),
|
|
||||||
current_step(0), current_proc(0), debug(false), log(true),
|
|
||||||
histogram_enabled(false), dtb_enabled(true), remote_bitbang(NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (auto& x : mems)
|
|
||||||
bus.add_device(x.first, x.second);
|
|
||||||
|
|
||||||
debug_mmu = new mmu_t(this, NULL);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < procs.size(); i++) {
|
|
||||||
procs[i] = new processor_t(isa, this, i, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
clint.reset(new clint_t(procs));
|
|
||||||
// we need to bring the clint to a reproducible default value
|
|
||||||
clint.get()->reset();
|
|
||||||
bus.add_device(CLINT_BASE, clint.get());
|
|
||||||
uart.reset(new uart_t());
|
|
||||||
bus.add_device(UART_BASE, uart.get());
|
|
||||||
make_bootrom();
|
|
||||||
set_procs_debug(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
sim_spike_t::~sim_spike_t()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < procs.size(); i++)
|
|
||||||
delete procs[i];
|
|
||||||
delete debug_mmu;
|
|
||||||
}
|
|
||||||
|
|
||||||
commit_log_t sim_spike_t::tick(size_t n)
|
|
||||||
{
|
|
||||||
commit_log_t commit_log;
|
|
||||||
|
|
||||||
reg_t pc = procs[0]->get_state()->pc;
|
|
||||||
auto& reg = procs[0]->get_state()->log_reg_write;
|
|
||||||
// execute instruction
|
|
||||||
procs[0]->step(n);
|
|
||||||
int priv = procs[0]->get_state()->last_inst_priv;
|
|
||||||
int xlen = procs[0]->get_state()->last_inst_xlen;
|
|
||||||
int flen = procs[0]->get_state()->last_inst_flen;
|
|
||||||
|
|
||||||
commit_log.priv = priv;
|
|
||||||
commit_log.pc = pc;
|
|
||||||
commit_log.is_fp = reg.addr & 1;
|
|
||||||
commit_log.rd = reg.addr >> 1;
|
|
||||||
commit_log.data = reg.data.v[0];
|
|
||||||
commit_log.instr = procs[0]->get_state()->last_insn;
|
|
||||||
commit_log.was_exception = procs[0]->get_state()->was_exception;
|
|
||||||
|
|
||||||
return commit_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::clint_tick() {
|
|
||||||
clint->increment(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::set_debug(bool value)
|
|
||||||
{
|
|
||||||
debug = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::set_log(bool value)
|
|
||||||
{
|
|
||||||
log = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::set_histogram(bool value)
|
|
||||||
{
|
|
||||||
histogram_enabled = value;
|
|
||||||
for (size_t i = 0; i < procs.size(); i++) {
|
|
||||||
procs[i]->set_histogram(histogram_enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::set_procs_debug(bool value)
|
|
||||||
{
|
|
||||||
for (size_t i=0; i< procs.size(); i++)
|
|
||||||
procs[i]->set_debug(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sim_spike_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes)
|
|
||||||
{
|
|
||||||
if (addr + len < addr)
|
|
||||||
return false;
|
|
||||||
return bus.load(addr, len, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sim_spike_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
|
|
||||||
{
|
|
||||||
if (addr + len < addr)
|
|
||||||
return false;
|
|
||||||
return bus.store(addr, len, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_spike_t::make_bootrom()
|
|
||||||
{
|
|
||||||
start_pc = 0x80000000;
|
|
||||||
|
|
||||||
#include "bootrom.h"
|
|
||||||
|
|
||||||
std::vector<char> rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec));
|
|
||||||
|
|
||||||
boot_rom.reset(new rom_device_t(rom));
|
|
||||||
bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
char* sim_spike_t::addr_to_mem(reg_t addr) {
|
|
||||||
auto desc = bus.find_device(addr);
|
|
||||||
if (auto mem = dynamic_cast<mem_t*>(desc.second))
|
|
||||||
if (addr - desc.first < mem->size())
|
|
||||||
return mem->contents() + (addr - desc.first);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
// See LICENSE for license details.
|
|
||||||
|
|
||||||
#ifndef _RISCV_SPIKE_H
|
|
||||||
#define _RISCV_SPIKE_H
|
|
||||||
|
|
||||||
#include "processor.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "debug_module.h"
|
|
||||||
#include "simif.h"
|
|
||||||
#include <fesvr/htif.h>
|
|
||||||
#include <fesvr/context.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
class mmu_t;
|
|
||||||
class remote_bitbang_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char priv;
|
|
||||||
uint64_t pc;
|
|
||||||
char is_fp;
|
|
||||||
char rd;
|
|
||||||
uint64_t data;
|
|
||||||
uint32_t instr;
|
|
||||||
char was_exception;
|
|
||||||
} commit_log_t;
|
|
||||||
|
|
||||||
// this class encapsulates the processors and memory in a RISC-V machine.
|
|
||||||
class sim_spike_t : public simif_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
sim_spike_t(const char* isa, size_t _nprocs,
|
|
||||||
std::vector<std::pair<reg_t, mem_t*>> mems,
|
|
||||||
const std::vector<std::string>& args);
|
|
||||||
~sim_spike_t();
|
|
||||||
|
|
||||||
int init_sim();
|
|
||||||
void producer_thread();
|
|
||||||
void clint_tick();
|
|
||||||
commit_log_t tick(size_t n); // step through simulation
|
|
||||||
void set_debug(bool value);
|
|
||||||
void set_log(bool value);
|
|
||||||
void set_histogram(bool value);
|
|
||||||
void set_procs_debug(bool value);
|
|
||||||
void set_dtb_enabled(bool value) {
|
|
||||||
this->dtb_enabled = value;
|
|
||||||
}
|
|
||||||
void set_remote_bitbang(remote_bitbang_t* remote_bitbang) {
|
|
||||||
this->remote_bitbang = remote_bitbang;
|
|
||||||
}
|
|
||||||
const char* get_dts() { return dts.c_str(); }
|
|
||||||
processor_t* get_core(size_t i) { return procs.at(i); }
|
|
||||||
unsigned nprocs() const { return procs.size(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::pair<reg_t, mem_t*>> mems;
|
|
||||||
mmu_t* debug_mmu; // debug port into main memory
|
|
||||||
std::vector<processor_t*> procs;
|
|
||||||
reg_t start_pc;
|
|
||||||
std::string dts;
|
|
||||||
std::unique_ptr<rom_device_t> boot_rom;
|
|
||||||
std::unique_ptr<clint_t> clint;
|
|
||||||
std::unique_ptr<uart_t> uart;
|
|
||||||
bus_t bus;
|
|
||||||
std::thread t1;
|
|
||||||
|
|
||||||
processor_t* get_core(const std::string& i);
|
|
||||||
static const size_t INTERLEAVE = 5000;
|
|
||||||
static const size_t INSNS_PER_RTC_TICK = 100; // 10 MHz clock for 1 BIPS core
|
|
||||||
static const size_t CPU_HZ = 1000000000; // 1GHz CPU
|
|
||||||
size_t current_step;
|
|
||||||
size_t current_proc;
|
|
||||||
bool debug;
|
|
||||||
bool log;
|
|
||||||
bool histogram_enabled; // provide a histogram of PCs
|
|
||||||
bool dtb_enabled;
|
|
||||||
remote_bitbang_t* remote_bitbang;
|
|
||||||
|
|
||||||
// memory-mapped I/O routines
|
|
||||||
char* addr_to_mem(reg_t addr);
|
|
||||||
bool mmio_load(reg_t addr, size_t len, uint8_t* bytes);
|
|
||||||
bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes);
|
|
||||||
void proc_reset(unsigned id) {};
|
|
||||||
|
|
||||||
void make_bootrom();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,133 +0,0 @@
|
||||||
#include <fesvr/elf.h>
|
|
||||||
#include <fesvr/memif.h>
|
|
||||||
|
|
||||||
#include "sim_spike.h"
|
|
||||||
#include "msim_helper.h"
|
|
||||||
|
|
||||||
#include <vpi_user.h>
|
|
||||||
#include "svdpi.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <map>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
sim_spike_t* sim;
|
|
||||||
std::vector<std::pair<reg_t, mem_t*>> mem;
|
|
||||||
commit_log_t commit_log_val;
|
|
||||||
|
|
||||||
#define SHT_PROGBITS 0x1
|
|
||||||
#define SHT_GROUP 0x11
|
|
||||||
|
|
||||||
void write_spike_mem (reg_t address, size_t len, uint8_t* buf) {
|
|
||||||
memcpy(mem[0].second->contents() + (address & ~(1 << 31)), buf,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_elf(const char* filename) {
|
|
||||||
int fd = open(filename, O_RDONLY);
|
|
||||||
struct stat s;
|
|
||||||
assert(fd != -1);
|
|
||||||
if (fstat(fd, &s) < 0)
|
|
||||||
abort();
|
|
||||||
size_t size = s.st_size;
|
|
||||||
|
|
||||||
char* buf = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
||||||
assert(buf != MAP_FAILED);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
assert(size >= sizeof(Elf64_Ehdr));
|
|
||||||
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
|
|
||||||
assert(IS_ELF32(*eh64) || IS_ELF64(*eh64));
|
|
||||||
|
|
||||||
std::vector<uint8_t> zeros;
|
|
||||||
|
|
||||||
#define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t) do { \
|
|
||||||
ehdr_t* eh = (ehdr_t*)buf; \
|
|
||||||
phdr_t* ph = (phdr_t*)(buf + eh->e_phoff); \
|
|
||||||
assert(size >= eh->e_phoff + eh->e_phnum*sizeof(*ph)); \
|
|
||||||
for (unsigned i = 0; i < eh->e_phnum; i++) { \
|
|
||||||
if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { \
|
|
||||||
if (ph[i].p_filesz) { \
|
|
||||||
assert(size >= ph[i].p_offset + ph[i].p_filesz); \
|
|
||||||
write_spike_mem(ph[i].p_paddr, ph[i].p_filesz, (uint8_t*)buf + ph[i].p_offset); \
|
|
||||||
} \
|
|
||||||
zeros.resize(ph[i].p_memsz - ph[i].p_filesz); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
shdr_t* sh = (shdr_t*)(buf + eh->e_shoff); \
|
|
||||||
assert(size >= eh->e_shoff + eh->e_shnum*sizeof(*sh)); \
|
|
||||||
assert(eh->e_shstrndx < eh->e_shnum); \
|
|
||||||
assert(size >= sh[eh->e_shstrndx].sh_offset + sh[eh->e_shstrndx].sh_size); \
|
|
||||||
char *shstrtab = buf + sh[eh->e_shstrndx].sh_offset; \
|
|
||||||
unsigned strtabidx = 0, symtabidx = 0; \
|
|
||||||
for (unsigned i = 0; i < eh->e_shnum; i++) { \
|
|
||||||
unsigned max_len = sh[eh->e_shstrndx].sh_size - sh[i].sh_name; \
|
|
||||||
if ((sh[i].sh_type & SHT_GROUP) && strcmp(shstrtab + sh[i].sh_name, ".strtab") != 0 && strcmp(shstrtab + sh[i].sh_name, ".shstrtab") != 0) \
|
|
||||||
assert(strnlen(shstrtab + sh[i].sh_name, max_len) < max_len); \
|
|
||||||
if (sh[i].sh_type & SHT_PROGBITS) continue; \
|
|
||||||
if (strcmp(shstrtab + sh[i].sh_name, ".strtab") == 0) \
|
|
||||||
strtabidx = i; \
|
|
||||||
if (strcmp(shstrtab + sh[i].sh_name, ".symtab") == 0) \
|
|
||||||
symtabidx = i; \
|
|
||||||
} \
|
|
||||||
if (strtabidx && symtabidx) { \
|
|
||||||
char* strtab = buf + sh[strtabidx].sh_offset; \
|
|
||||||
sym_t* sym = (sym_t*)(buf + sh[symtabidx].sh_offset); \
|
|
||||||
for (unsigned i = 0; i < sh[symtabidx].sh_size/sizeof(sym_t); i++) { \
|
|
||||||
unsigned max_len = sh[strtabidx].sh_size - sym[i].st_name; \
|
|
||||||
assert(sym[i].st_name < sh[strtabidx]. sh_size); \
|
|
||||||
assert(strnlen(strtab + sym[i].st_name, max_len) < max_len); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
if (IS_ELF32(*eh64))
|
|
||||||
LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym);
|
|
||||||
else
|
|
||||||
LOAD_ELF(Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Sym);
|
|
||||||
|
|
||||||
munmap(buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void spike_create(const char* filename, uint64_t dram_base, unsigned int size)
|
|
||||||
{
|
|
||||||
|
|
||||||
mem = std::vector<std::pair<reg_t, mem_t*>>(1, std::make_pair(reg_t(dram_base), new mem_t(size)));
|
|
||||||
// zero out memory
|
|
||||||
memset(mem[0].second->contents(), 0, size_t(size));
|
|
||||||
|
|
||||||
read_elf(filename);
|
|
||||||
|
|
||||||
if (!sim) {
|
|
||||||
std::vector<std::string> htif_args = sanitize_args();
|
|
||||||
|
|
||||||
sim = new sim_spike_t("rv64imac", 1, mem, htif_args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// advance Spike and get the retired instruction
|
|
||||||
extern "C" void spike_tick(commit_log_t* commit_log)
|
|
||||||
{
|
|
||||||
commit_log_val = sim->tick(1);
|
|
||||||
commit_log->priv = commit_log_val.priv;
|
|
||||||
commit_log->pc = commit_log_val.pc;
|
|
||||||
commit_log->is_fp = commit_log_val.is_fp;
|
|
||||||
commit_log->rd = commit_log_val.rd;
|
|
||||||
commit_log->data = commit_log_val.data;
|
|
||||||
commit_log->instr = commit_log_val.instr;
|
|
||||||
commit_log->was_exception = commit_log_val.was_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void clint_tick()
|
|
||||||
{
|
|
||||||
sim->clint_tick();
|
|
||||||
}
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a687a6023b3204881a9fa2ba10d394f5f3e8f8b2
|
Subproject commit 67791932df6128671344015584109d7a177d9a9a
|
8
verif/env/uvme/uvme_cva6_cfg.sv
vendored
8
verif/env/uvme/uvme_cva6_cfg.sv
vendored
|
@ -31,7 +31,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
// Integrals
|
// Integrals
|
||||||
rand bit enabled;
|
rand bit enabled;
|
||||||
|
|
||||||
rand bit scoreboarding_enabled;
|
rand bit scoreboard_enabled;
|
||||||
rand bit cov_model_enabled;
|
rand bit cov_model_enabled;
|
||||||
rand bit cov_cvxif_model_enabled;
|
rand bit cov_cvxif_model_enabled;
|
||||||
rand bit cov_isa_model_enabled;
|
rand bit cov_isa_model_enabled;
|
||||||
|
@ -51,7 +51,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
`uvm_object_utils_begin(uvme_cva6_cfg_c)
|
`uvm_object_utils_begin(uvme_cva6_cfg_c)
|
||||||
`uvm_field_int ( enabled , UVM_DEFAULT )
|
`uvm_field_int ( enabled , UVM_DEFAULT )
|
||||||
`uvm_field_enum(uvm_active_passive_enum, is_active , UVM_DEFAULT )
|
`uvm_field_enum(uvm_active_passive_enum, is_active , UVM_DEFAULT )
|
||||||
`uvm_field_int ( scoreboarding_enabled , UVM_DEFAULT )
|
`uvm_field_int ( scoreboard_enabled , UVM_DEFAULT )
|
||||||
`uvm_field_int ( cov_model_enabled , UVM_DEFAULT )
|
`uvm_field_int ( cov_model_enabled , UVM_DEFAULT )
|
||||||
`uvm_field_int ( trn_log_enabled , UVM_DEFAULT )
|
`uvm_field_int ( trn_log_enabled , UVM_DEFAULT )
|
||||||
`uvm_field_int ( ext_zicond_supported , UVM_DEFAULT )
|
`uvm_field_int ( ext_zicond_supported , UVM_DEFAULT )
|
||||||
|
@ -73,7 +73,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
constraint defaults_cons {
|
constraint defaults_cons {
|
||||||
soft enabled == 1;
|
soft enabled == 1;
|
||||||
soft is_active == UVM_ACTIVE;
|
soft is_active == UVM_ACTIVE;
|
||||||
soft scoreboarding_enabled == 1;
|
soft scoreboard_enabled == 1;
|
||||||
soft cov_model_enabled == 1;
|
soft cov_model_enabled == 1;
|
||||||
soft trn_log_enabled == 1;
|
soft trn_log_enabled == 1;
|
||||||
soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv
|
soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv
|
||||||
|
@ -154,7 +154,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
isacov_cfg.seq_instr_x2_enabled == 1;
|
isacov_cfg.seq_instr_x2_enabled == 1;
|
||||||
isacov_cfg.reg_crosses_enabled == 0;
|
isacov_cfg.reg_crosses_enabled == 0;
|
||||||
isacov_cfg.reg_hazards_enabled == 1;
|
isacov_cfg.reg_hazards_enabled == 1;
|
||||||
rvfi_cfg.nret == RVFI_NRET;
|
rvfi_cfg.nret == cva6_config_pkg::CVA6ConfigNrCommitPorts;
|
||||||
|
|
||||||
if (is_active == UVM_ACTIVE) {
|
if (is_active == UVM_ACTIVE) {
|
||||||
clknrst_cfg.is_active == UVM_ACTIVE;
|
clknrst_cfg.is_active == UVM_ACTIVE;
|
||||||
|
|
1
verif/env/uvme/uvme_cva6_constants.sv
vendored
1
verif/env/uvme/uvme_cva6_constants.sv
vendored
|
@ -26,6 +26,5 @@ parameter uvme_cva6_debug_default_clk_period = 10_000; // 10ns
|
||||||
|
|
||||||
parameter XLEN = 32;
|
parameter XLEN = 32;
|
||||||
parameter ILEN = 32;
|
parameter ILEN = 32;
|
||||||
parameter RVFI_NRET = 1;
|
|
||||||
|
|
||||||
`endif // __UVME_CVA6_CONSTANTS_SV__
|
`endif // __UVME_CVA6_CONSTANTS_SV__
|
||||||
|
|
18
verif/env/uvme/uvme_cva6_env.sv
vendored
18
verif/env/uvme/uvme_cva6_env.sv
vendored
|
@ -38,6 +38,8 @@ class uvme_cva6_env_c extends uvm_env;
|
||||||
uvme_cva6_vsqr_c vsequencer;
|
uvme_cva6_vsqr_c vsequencer;
|
||||||
uvme_cva6_cov_model_c cov_model;
|
uvme_cva6_cov_model_c cov_model;
|
||||||
|
|
||||||
|
uvmc_rvfi_reference_model m_reference_model;
|
||||||
|
|
||||||
// Agents
|
// Agents
|
||||||
uvma_clknrst_agent_c clknrst_agent;
|
uvma_clknrst_agent_c clknrst_agent;
|
||||||
uvma_cvxif_agent_c cvxif_agent;
|
uvma_cvxif_agent_c cvxif_agent;
|
||||||
|
@ -168,6 +170,9 @@ function void uvme_cva6_env_c::build_phase(uvm_phase phase);
|
||||||
cntxt = uvme_cva6_cntxt_c::type_id::create("cntxt");
|
cntxt = uvme_cva6_cntxt_c::type_id::create("cntxt");
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if ($test$plusargs("scoreboard_enabled"))
|
||||||
|
$value$plusargs("scoreboard_enabled=%b",cfg.scoreboard_enabled);
|
||||||
|
|
||||||
retrieve_vif();
|
retrieve_vif();
|
||||||
assign_cfg ();
|
assign_cfg ();
|
||||||
assign_cntxt ();
|
assign_cntxt ();
|
||||||
|
@ -195,7 +200,7 @@ function void uvme_cva6_env_c::connect_phase(uvm_phase phase);
|
||||||
super.connect_phase(phase);
|
super.connect_phase(phase);
|
||||||
|
|
||||||
if (cfg.enabled) begin
|
if (cfg.enabled) begin
|
||||||
if (cfg.scoreboarding_enabled) begin
|
if (cfg.scoreboard_enabled) begin
|
||||||
connect_predictor ();
|
connect_predictor ();
|
||||||
connect_scoreboard();
|
connect_scoreboard();
|
||||||
end
|
end
|
||||||
|
@ -269,9 +274,10 @@ endfunction: create_agents
|
||||||
|
|
||||||
function void uvme_cva6_env_c::create_env_components();
|
function void uvme_cva6_env_c::create_env_components();
|
||||||
|
|
||||||
if (cfg.scoreboarding_enabled) begin
|
if (cfg.scoreboard_enabled) begin
|
||||||
predictor = uvme_cva6_prd_c::type_id::create("predictor", this);
|
predictor = uvme_cva6_prd_c::type_id::create("predictor", this);
|
||||||
sb = uvme_cva6_sb_c ::type_id::create("sb" , this);
|
sb = uvme_cva6_sb_c ::type_id::create("sb" , this);
|
||||||
|
m_reference_model = uvmc_rvfi_reference_model#(ILEN,XLEN)::type_id::create("m_reference_model", this);
|
||||||
end
|
end
|
||||||
|
|
||||||
if (cfg.cov_model_enabled) begin
|
if (cfg.cov_model_enabled) begin
|
||||||
|
@ -321,6 +327,10 @@ function void uvme_cva6_env_c::connect_scoreboard();
|
||||||
// TODO Connect predictor -> scoreboard
|
// TODO Connect predictor -> scoreboard
|
||||||
// Ex: predictor.debug_ap.connect(sb.debug_sb.exp_export);
|
// Ex: predictor.debug_ap.connect(sb.debug_sb.exp_export);
|
||||||
|
|
||||||
|
rvfi_agent.rvfi_core_ap.connect(sb.m_rvfi_scoreboard.m_imp_core);
|
||||||
|
rvfi_agent.rvfi_core_ap.connect(m_reference_model.m_analysis_imp);
|
||||||
|
m_reference_model.m_analysis_port.connect(sb.m_rvfi_scoreboard.m_imp_reference_model);
|
||||||
|
|
||||||
endfunction: connect_scoreboard
|
endfunction: connect_scoreboard
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,11 +371,9 @@ function void uvme_cva6_env_c::connect_coverage_model();
|
||||||
if (cfg.cov_isa_model_enabled) begin
|
if (cfg.cov_isa_model_enabled) begin
|
||||||
isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export);
|
isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export);
|
||||||
end
|
end
|
||||||
foreach (rvfi_agent.instr_mon_ap[i]) begin
|
|
||||||
rvfi_agent.instr_mon_ap[i].connect(isacov_agent.monitor.rvfi_instr_imp);
|
|
||||||
end
|
|
||||||
|
|
||||||
clknrst_agent.mon_ap.connect(cov_model.reset_export);
|
clknrst_agent.mon_ap.connect(cov_model.reset_export);
|
||||||
|
rvfi_agent.rvfi_core_ap.connect(isacov_agent.monitor.rvfi_instr_imp);
|
||||||
|
|
||||||
endfunction: connect_coverage_model
|
endfunction: connect_coverage_model
|
||||||
|
|
||||||
|
|
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
|
@ -37,6 +37,7 @@
|
||||||
*/
|
*/
|
||||||
package uvme_cva6_pkg;
|
package uvme_cva6_pkg;
|
||||||
|
|
||||||
|
import cva6_config_pkg ::*;
|
||||||
import uvm_pkg ::*;
|
import uvm_pkg ::*;
|
||||||
import uvml_hrtbt_pkg ::*;
|
import uvml_hrtbt_pkg ::*;
|
||||||
import uvml_sb_pkg ::*;
|
import uvml_sb_pkg ::*;
|
||||||
|
@ -47,6 +48,8 @@ package uvme_cva6_pkg;
|
||||||
import uvml_mem_pkg ::*;
|
import uvml_mem_pkg ::*;
|
||||||
import uvma_core_cntrl_pkg::*;
|
import uvma_core_cntrl_pkg::*;
|
||||||
import uvma_rvfi_pkg::*;
|
import uvma_rvfi_pkg::*;
|
||||||
|
import uvmc_rvfi_scoreboard_pkg::*;
|
||||||
|
import uvmc_rvfi_reference_model_pkg::*;
|
||||||
import uvma_isacov_pkg::*;
|
import uvma_isacov_pkg::*;
|
||||||
|
|
||||||
// Constants / Structs / Enums
|
// Constants / Structs / Enums
|
||||||
|
|
3
verif/env/uvme/uvme_cva6_sb.sv
vendored
3
verif/env/uvme/uvme_cva6_sb.sv
vendored
|
@ -35,6 +35,8 @@ class uvme_cva6_sb_c extends uvm_scoreboard;
|
||||||
// TODO Add sub-scoreboards
|
// TODO Add sub-scoreboards
|
||||||
// Ex: uvme_cva6_sb_simplex_c egress_sb;
|
// Ex: uvme_cva6_sb_simplex_c egress_sb;
|
||||||
// uvme_cva6_sb_simplex_c ingress_sb;
|
// uvme_cva6_sb_simplex_c ingress_sb;
|
||||||
|
uvmc_rvfi_scoreboard_c#(ILEN,XLEN) m_rvfi_scoreboard;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`uvm_component_utils_begin(uvme_cva6_sb_c)
|
`uvm_component_utils_begin(uvme_cva6_sb_c)
|
||||||
|
@ -129,6 +131,7 @@ function void uvme_cva6_sb_c::create_sbs();
|
||||||
// TODO Implement uvme_cva6_sb_c::create_sbs()
|
// TODO Implement uvme_cva6_sb_c::create_sbs()
|
||||||
// Ex: egress_sb = uvme_cva6_sb_simplex_c::type_id::create("egress_sb" , this);
|
// Ex: egress_sb = uvme_cva6_sb_simplex_c::type_id::create("egress_sb" , this);
|
||||||
// ingress_sb = uvme_cva6_sb_simplex_c::type_id::create("ingress_sb", this);
|
// ingress_sb = uvme_cva6_sb_simplex_c::type_id::create("ingress_sb", this);
|
||||||
|
m_rvfi_scoreboard = uvmc_rvfi_scoreboard_c#(ILEN,XLEN)::type_id::create("m_rvfi_scoreboard", this);
|
||||||
|
|
||||||
endfunction : create_sbs
|
endfunction : create_sbs
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,9 @@ else
|
||||||
# Build and install Spike (including extensions).
|
# Build and install Spike (including extensions).
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
../configure --prefix="$SPIKE_INSTALL_DIR"
|
if [[ ! -f config.log ]]; then
|
||||||
|
../configure --prefix="$SPIKE_INSTALL_DIR"
|
||||||
|
fi
|
||||||
make -j${NUM_JOBS}
|
make -j${NUM_JOBS}
|
||||||
echo "Installing Spike in '$SPIKE_INSTALL_DIR'..."
|
echo "Installing Spike in '$SPIKE_INSTALL_DIR'..."
|
||||||
make install
|
make install
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# Original Author: Jean-Roch COULON - Thales
|
# Original Author: Jean-Roch COULON - Thales
|
||||||
|
|
||||||
if [ -z "$NUM_JOBS" ]; then
|
if [ -z "$NUM_JOBS" ]; then
|
||||||
NUM_JOBS=1
|
NUM_JOBS=4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure the location of tools is known (usually, .../core-v-verif/tools).
|
# Ensure the location of tools is known (usually, .../core-v-verif/tools).
|
||||||
|
@ -51,6 +51,7 @@ if [ ! -f "$VERILATOR_INSTALL_DIR/bin/verilator" ]; then
|
||||||
echo "VERILATOR_BRANCH=$VERILATOR_BRANCH"
|
echo "VERILATOR_BRANCH=$VERILATOR_BRANCH"
|
||||||
echo "VERILATOR_HASH=$VERILATOR_HASH"
|
echo "VERILATOR_HASH=$VERILATOR_HASH"
|
||||||
echo "VERILATOR_PATCH=$VERILATOR_PATCH"
|
echo "VERILATOR_PATCH=$VERILATOR_PATCH"
|
||||||
|
echo "NUM_JOBS=$NUM_JOBS"
|
||||||
mkdir -p $VERILATOR_BUILD_DIR
|
mkdir -p $VERILATOR_BUILD_DIR
|
||||||
cd $VERILATOR_BUILD_DIR
|
cd $VERILATOR_BUILD_DIR
|
||||||
# Clone only if the ".git" directory does not exist.
|
# Clone only if the ".git" directory does not exist.
|
||||||
|
|
|
@ -14,6 +14,7 @@ ifndef CVA6_REPO_DIR
|
||||||
$(warning must set CVA6_REPO_DIR to point at the root of CVA6 sources and CVA6_TB_DIR to point here -- doing it for you...)
|
$(warning must set CVA6_REPO_DIR to point at the root of CVA6 sources and CVA6_TB_DIR to point here -- doing it for you...)
|
||||||
export CVA6_REPO_DIR = $(abspath $(root-dir)../..)
|
export CVA6_REPO_DIR = $(abspath $(root-dir)../..)
|
||||||
export CVA6_TB_DIR = $(root-dir)/../tb/core
|
export CVA6_TB_DIR = $(root-dir)/../tb/core
|
||||||
|
export CORE_V_VERIF = $(root-dir)/../core-v-verif
|
||||||
endif
|
endif
|
||||||
ifndef TARGET_CFG
|
ifndef TARGET_CFG
|
||||||
export TARGET_CFG = $(target)
|
export TARGET_CFG = $(target)
|
||||||
|
@ -27,6 +28,7 @@ export HPDCACHE_TARGET_CFG
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
FLIST_TB := $(CVA6_TB_DIR)/Flist.cva6_tb
|
FLIST_TB := $(CVA6_TB_DIR)/Flist.cva6_tb
|
||||||
|
|
||||||
# target takes one of the following cva6 hardware configuration:
|
# target takes one of the following cva6 hardware configuration:
|
||||||
# cv64a6_imafdc_sv39, cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32
|
# cv64a6_imafdc_sv39, cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32
|
||||||
target ?= cv64a6_imafdc_sv39
|
target ?= cv64a6_imafdc_sv39
|
||||||
|
@ -42,6 +44,10 @@ issrun_opts ?=
|
||||||
isspostrun_opts ?=
|
isspostrun_opts ?=
|
||||||
log ?=
|
log ?=
|
||||||
variant ?=
|
variant ?=
|
||||||
|
|
||||||
|
# Spike tandem mode: default to environment setting (DISABLED if envariable SPIKE_TANDEM is not set).
|
||||||
|
export spike-tandem ?= $(SPIKE_TANDEM)
|
||||||
|
|
||||||
# Set Spike step count limit if the caller provided a step count value in variable 'steps'.
|
# Set Spike step count limit if the caller provided a step count value in variable 'steps'.
|
||||||
ifneq ($(steps),)
|
ifneq ($(steps),)
|
||||||
spike_stepout = --steps=$(steps)
|
spike_stepout = --steps=$(steps)
|
||||||
|
@ -121,17 +127,19 @@ spike:
|
||||||
# testharness specific commands, variables
|
# testharness specific commands, variables
|
||||||
###############################################################################
|
###############################################################################
|
||||||
vcs-testharness:
|
vcs-testharness:
|
||||||
make -C $(path_var) vcs_build target=$(target) defines=$(subst +define+,,$(isscomp_opts))
|
make -C $(path_var) work-dpi/ariane_dpi.so
|
||||||
$(path_var)/work-vcs/simv +vcs+lic+wait $(if $(VERDI), -verdi -do $(path_var)/init_testharness.do,) +permissive -sv_lib $(path_var)/work-dpi/ariane_dpi \
|
make -C $(path_var) vcs_build target=$(target) defines=$(subst +define+,,$(isscomp_opts))$(if $(spike-tandem),SPIKE_TANDEM=1)
|
||||||
|
$(path_var)/work-vcs/simv $(if $(VERDI), -verdi -do $(path_var)/init_testharness.do,) +permissive \
|
||||||
+tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
|
+tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
|
||||||
+PRELOAD=$(elf) +permissive-off ++$(elf) $(issrun_opts)
|
+elf_file=$(elf) +permissive-off ++$(elf) $(issrun_opts) $(if $(spike-tandem),-sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv) \
|
||||||
|
-sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr
|
||||||
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
|
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
|
||||||
grep $(isspostrun_opts) ./trace_rvfi_hart_00.dasm
|
grep $(isspostrun_opts) ./trace_rvfi_hart_00.dasm
|
||||||
|
|
||||||
veri-testharness:
|
veri-testharness:
|
||||||
make -C $(path_var) verilate verilator="verilator --no-timing" target=$(target) defines=$(subst +define+,,$(isscomp_opts))
|
make -C $(path_var) verilate verilator="verilator --no-timing" target=$(target) defines=$(subst +define+,,$(isscomp_opts))
|
||||||
$(path_var)/work-ver/Variane_testharness $(if $(TRACE_COMPACT), -f verilator.fst) $(if $(TRACE_FAST), -v verilator.vcd) $(elf) $(issrun_opts) +PRELOAD=$(elf) \
|
$(path_var)/work-ver/Variane_testharness $(if $(TRACE_COMPACT), -f verilator.fst) $(if $(TRACE_FAST), -v verilator.vcd) $(elf) $(issrun_opts) \
|
||||||
+tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1)
|
+elf_file=$(elf) +tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1)
|
||||||
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
|
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
|
||||||
# If present, move default trace files to per-test directory.
|
# If present, move default trace files to per-test directory.
|
||||||
[ ! -f verilator.fst ] || mv verilator.fst `dirname $(log)`/`basename $(log) .log`.$(target).fst
|
[ ! -f verilator.fst ] || mv verilator.fst `dirname $(log)`/`basename $(log) .log`.$(target).fst
|
||||||
|
@ -140,7 +148,7 @@ veri-testharness:
|
||||||
|
|
||||||
questa-testharness:
|
questa-testharness:
|
||||||
mkdir -p $(path_var)/tmp
|
mkdir -p $(path_var)/tmp
|
||||||
make -C $(path_var) sim target=$(target) defines=$(subst +define+,,$(isscomp_opts)) batch-mode=1 elf-bin=$(elf) $(issrun_opts)
|
make -C $(path_var) sim target=$(target) defines=$(subst +define+,,$(isscomp_opts)) batch-mode=1 $(issrun_opts)
|
||||||
$(tool_path)/spike-dasm --isa=$(variant) < $(path_var)/trace_rvfi_hart_00.dasm > $(log)
|
$(tool_path)/spike-dasm --isa=$(variant) < $(path_var)/trace_rvfi_hart_00.dasm > $(log)
|
||||||
grep $(isspostrun_opts) $(path_var)/trace_rvfi_hart_00.dasm
|
grep $(isspostrun_opts) $(path_var)/trace_rvfi_hart_00.dasm
|
||||||
|
|
||||||
|
@ -156,31 +164,29 @@ export CVA6_UVMT_PATH = $(CVA6_REPO_DIR)/verif/tb/uvmt
|
||||||
export CVA6_UVME_PATH = $(CVA6_REPO_DIR)/verif/env/uvme
|
export CVA6_UVME_PATH = $(CVA6_REPO_DIR)/verif/env/uvme
|
||||||
export CV_CORE_LC = cva6
|
export CV_CORE_LC = cva6
|
||||||
export CV_CORE_UC = CVA6
|
export CV_CORE_UC = CVA6
|
||||||
export DV_UVMT_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/$(CV_CORE_LC)/tb/uvmt
|
export DV_UVMT_PATH = $(CVA6_REPO_DIR)/verif/tb/uvmt
|
||||||
export DV_UVME_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/$(CV_CORE_LC)/env/uvme
|
export DV_UVME_PATH = $(CVA6_REPO_DIR)/verif/env/uvme
|
||||||
export DV_UVML_HRTBT_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_libs/uvml_hrtbt
|
export DV_UVML_HRTBT_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_hrtbt
|
||||||
export DV_UVMA_CORE_CNTRL_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_core_cntrl
|
export DV_UVMA_CORE_CNTRL_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_core_cntrl
|
||||||
export DV_UVMA_RVFI_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_rvfi
|
export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi
|
||||||
export DV_UVMA_ISACOV_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_isacov
|
export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov
|
||||||
export DV_UVMA_CLKNRST_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_clknrst
|
export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst
|
||||||
export DV_UVMA_CVXIF_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_cvxif
|
export DV_UVMA_CVXIF_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_cvxif
|
||||||
export DV_UVMA_AXI_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_axi
|
export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi
|
||||||
export DV_UVMA_INTERRUPT_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_interrupt
|
export DV_UVMA_INTERRUPT_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_interrupt
|
||||||
export DV_UVMA_DEBUG_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_debug
|
export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug
|
||||||
export DV_UVMA_OBI_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_agents/uvma_obi
|
export DV_UVMA_OBI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_obi
|
||||||
export DV_UVML_TRN_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_libs/uvml_trn
|
export DV_UVMC_RVFI_SB_PATH = $(CORE_V_VERIF)/lib/uvm_components/uvmc_rvfi_scoreboard/
|
||||||
export DV_UVML_MEM_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_libs/uvml_mem
|
export DV_UVMC_RVFI_REFERENCE_MODEL_PATH = $(CORE_V_VERIF)/lib/uvm_components/uvmc_rvfi_reference_model/
|
||||||
export DV_UVML_LOGS_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_libs/uvml_logs
|
export DV_UVML_TRN_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_trn
|
||||||
export DV_UVML_SB_PATH = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/uvm_libs/uvml_sb
|
export DV_UVML_MEM_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_mem
|
||||||
export CV_CORE_PKG = $(CVA6_REPO_DIR)/verif/core-v-verif/core-v-cores/$(CV_CORE_LC)
|
export DV_UVML_LOGS_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_logs
|
||||||
|
export DV_UVML_SB_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_sb
|
||||||
|
export CV_CORE_PKG = $(CORE_V_VERIF)/core-v-cores/$(CV_CORE_LC)
|
||||||
export DESIGN_RTL_DIR = $(CV_CORE_PKG)/rtl
|
export DESIGN_RTL_DIR = $(CV_CORE_PKG)/rtl
|
||||||
|
|
||||||
DPI_DASM_PKG = $(CVA6_REPO_DIR)/verif/core-v-verif/lib/dpi_dasm
|
|
||||||
DPI_DASM_SPIKE_PKG = $(CVA6_REPO_DIR)/verif/core-v-verif/$(CV_CORE_LC)/vendor_lib/dpi_dasm_spike
|
|
||||||
export DPI_DASM_ROOT = $(DPI_DASM_PKG)
|
|
||||||
export DPI_DASM_SPIKE_ROOT = $(DPI_DASM_SPIKE_PKG)
|
|
||||||
export TBSRC_HOME = $(CVA6_REPO_DIR)/verif/tb
|
export TBSRC_HOME = $(CVA6_REPO_DIR)/verif/tb
|
||||||
export DV_OVPM_HOME = $(CVA6_REPO_DIR)/verif/core-v-verif/$(CV_CORE_LC)/vendor_lib/imperas
|
export DV_OVPM_HOME = $(CORE_V_VERIF)/$(CV_CORE_LC)/vendor_lib/imperas
|
||||||
export DV_OVPM_MODEL = $(DV_OVPM_HOME)/riscv_$(CV_CORE_UC)_OVPsim
|
export DV_OVPM_MODEL = $(DV_OVPM_HOME)/riscv_$(CV_CORE_UC)_OVPsim
|
||||||
export DV_OVPM_DESIGN = $(DV_OVPM_HOME)/design
|
export DV_OVPM_DESIGN = $(DV_OVPM_HOME)/design
|
||||||
|
|
||||||
|
@ -188,12 +194,13 @@ ALL_UVM_FLAGS = -lca -sverilog +incdir+$(VCS_HOME)/etc/uvm/src \
|
||||||
$(VCS_HOME)/etc/uvm/src/uvm_pkg.sv +UVM_VERBOSITY=UVM_MEDIUM -ntb_opts uvm-1.2 -timescale=1ns/1ps \
|
$(VCS_HOME)/etc/uvm/src/uvm_pkg.sv +UVM_VERBOSITY=UVM_MEDIUM -ntb_opts uvm-1.2 -timescale=1ns/1ps \
|
||||||
-assert svaext -race=all -ignore unique_checks -full64 -q +incdir+$(VCS_HOME)/etc/uvm/src \
|
-assert svaext -race=all -ignore unique_checks -full64 -q +incdir+$(VCS_HOME)/etc/uvm/src \
|
||||||
+incdir+$(CVA6_REPO_DIR)/verif/env/uvme +incdir+$(CVA6_REPO_DIR)/verif/tb/uvmt \
|
+incdir+$(CVA6_REPO_DIR)/verif/env/uvme +incdir+$(CVA6_REPO_DIR)/verif/tb/uvmt \
|
||||||
$(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb) $(if $(TRACE_COMPACT),+vcs+fsdbon))\
|
$(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb) $(if $(TRACE_COMPACT),+vcs+fsdbon)) \
|
||||||
-cm_seqnoconst -diag noconst
|
-cm_seqnoconst -diag noconst \
|
||||||
|
$(if $(spike-tandem), +define+SPIKE_TANDEM=1)
|
||||||
|
|
||||||
ALL_SIMV_UVM_FLAGS = +vcs+lic+wait $(issrun_opts) \
|
ALL_SIMV_UVM_FLAGS = +vcs+lic+wait $(issrun_opts) \
|
||||||
-sv_lib $(CVA6_REPO_DIR)/verif/core-v-verif/lib/dpi_dasm/lib/Linux64/libdpi_dasm +signature=I-ADD-01.signature_output \
|
-sv_lib $(CVA6_REPO_DIR)/tools/spike/lib/libdisasm \
|
||||||
+UVM_TESTNAME=uvmt_cva6_firmware_test_c
|
+signature=I-ADD-01.signature_output +UVM_TESTNAME=uvmt_cva6_firmware_test_c
|
||||||
|
|
||||||
ifneq ($(DEBUG),) # If RTL DEBUG support requested
|
ifneq ($(DEBUG),) # If RTL DEBUG support requested
|
||||||
ifneq ($(VERDI),) # If VERDI interactive mode requested, use GUI and do not run simulation
|
ifneq ($(VERDI),) # If VERDI interactive mode requested, use GUI and do not run simulation
|
||||||
|
@ -213,15 +220,13 @@ ifneq ($(DEBUG),) # If RTL DEBUG support requested
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dpi-library = $(VCS_WORK_DIR)/work-dpi
|
ifneq ($(SPIKE_TANDEM),)
|
||||||
dpi_build:
|
ALL_SIMV_UVM_FLAGS += +scoreboard_enabled=1
|
||||||
mkdir -p $(dpi-library)
|
else
|
||||||
g++ -shared -fPIC -std=c++17 -Bsymbolic -I../corev_apu/tb/dpi -O3 -I$(SPIKE_INSTALL_DIR)/include \
|
ALL_SIMV_UVM_FLAGS += +scoreboard_enabled=0
|
||||||
-I$(VCS_HOME)/include -I$(RISCV)/include -c $(CVA6_REPO_DIR)/corev_apu/tb/dpi/elfloader.cc \
|
endif
|
||||||
-o $(dpi-library)/elfloader.o
|
|
||||||
g++ -shared -m64 -o $(dpi-library)/ariane_dpi.so $(dpi-library)/elfloader.o -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib
|
|
||||||
|
|
||||||
vcs_uvm_comp: dpi_build
|
vcs_uvm_comp:
|
||||||
@echo "[VCS] Building Model"
|
@echo "[VCS] Building Model"
|
||||||
mkdir -p $(VCS_WORK_DIR)
|
mkdir -p $(VCS_WORK_DIR)
|
||||||
cd $(VCS_WORK_DIR) && vcs $(ALL_UVM_FLAGS) \
|
cd $(VCS_WORK_DIR) && vcs $(ALL_UVM_FLAGS) \
|
||||||
|
@ -233,24 +238,19 @@ vcs_uvm_comp: dpi_build
|
||||||
vcs_uvm_run:
|
vcs_uvm_run:
|
||||||
$(if $(TRACE_FAST), unset VERDI_HOME ;) \
|
$(if $(TRACE_FAST), unset VERDI_HOME ;) \
|
||||||
cd $(VCS_WORK_DIR)/ && \
|
cd $(VCS_WORK_DIR)/ && \
|
||||||
$(VCS_WORK_DIR)/simv ${ALL_SIMV_UVM_FLAGS} \
|
$(VCS_WORK_DIR)/simv \
|
||||||
|
-sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv \
|
||||||
|
-sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr \
|
||||||
|
${ALL_SIMV_UVM_FLAGS} \
|
||||||
++$(elf) \
|
++$(elf) \
|
||||||
+PRELOAD=$(elf) \
|
+elf_file=$(elf) \
|
||||||
+tohost_addr=$(shell $$RISCV/bin/riscv-none-elf-nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
|
+tohost_addr=$(shell $$RISCV/bin/$(CV_SW_PREFIX)nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
|
||||||
-sv_lib $(dpi-library)/ariane_dpi \
|
$(cov-run-opt) $(issrun_opts)
|
||||||
$(cov-run-opt) $(issrun_opts) && \
|
|
||||||
mv $(VCS_WORK_DIR)/trace_rvfi_hart_00.dasm $(CVA6_REPO_DIR)/verif/sim/ && \
|
|
||||||
{ [ -z "`ls $(VCS_WORK_DIR)/*.$(SIMV_TRACE_EXTN)`" ] || \
|
|
||||||
for i in `ls $(VCS_WORK_DIR)/*.$(SIMV_TRACE_EXTN)` ; do mv $$i $(CVA6_REPO_DIR)/verif/sim/`basename $$i` ; done || \
|
|
||||||
true ; }
|
|
||||||
|
|
||||||
vcs-uvm:
|
vcs-uvm:
|
||||||
make vcs_uvm_comp
|
make vcs_uvm_comp
|
||||||
make vcs_uvm_run
|
make vcs_uvm_run
|
||||||
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
|
$(tool_path)/spike-dasm --isa=$(variant) < ./vcs_results/default/vcs.d/trace_rvfi_hart_00.dasm > $(log)
|
||||||
grep $(isspostrun_opts) ./trace_rvfi_hart_00.dasm
|
|
||||||
[ -z "`ls *.$(SIMV_TRACE_EXTN)`" ] || \
|
|
||||||
for i in `ls *.$(SIMV_TRACE_EXTN)` ; do mv $$i `dirname $(log)`/`basename $(log) .log`.$(target).$$i ; done || true
|
|
||||||
|
|
||||||
generate_cov_dash:
|
generate_cov_dash:
|
||||||
urg -hvp_proj cva6_embedded -format both -group instcov_for_score -hvp_attributes description -dir vcs_results/default/vcs.d/simv.vdb -plan cva6.hvp -mod modifier_embedded.hvp -tgl portsonly
|
urg -hvp_proj cva6_embedded -format both -group instcov_for_score -hvp_attributes description -dir vcs_results/default/vcs.d/simv.vdb -plan cva6.hvp -mod modifier_embedded.hvp -tgl portsonly
|
||||||
|
|
|
@ -97,7 +97,7 @@ def read_spike_trace(path, full_trace):
|
||||||
If full_trace is true, extract operands from the disassembled instructions.
|
If full_trace is true, extract operands from the disassembled instructions.
|
||||||
|
|
||||||
Since Spike has a strange trampoline that always runs at the start, we skip
|
Since Spike has a strange trampoline that always runs at the start, we skip
|
||||||
instructions up to and including the one at PC 0x1010 (the end of the
|
instructions up to and including the one at PC 0x10010 (the end of the
|
||||||
trampoline). At the end of a DV program, there's an ECALL instruction, which
|
trampoline). At the end of a DV program, there's an ECALL instruction, which
|
||||||
we take as a signal to stop checking, so we ditch everything that follows
|
we take as a signal to stop checking, so we ditch everything that follows
|
||||||
that instruction.
|
that instruction.
|
||||||
|
@ -121,7 +121,7 @@ def read_spike_trace(path, full_trace):
|
||||||
# true. Otherwise, we are in state EFFECT if instr is not None, otherwise we
|
# true. Otherwise, we are in state EFFECT if instr is not None, otherwise we
|
||||||
# are in state INSTR.
|
# are in state INSTR.
|
||||||
|
|
||||||
end_trampoline_re = re.compile(r'core.*: 0x0*1010 ')
|
end_trampoline_re = re.compile(r'core.*: 0x0*10010 ')
|
||||||
|
|
||||||
in_trampoline = True
|
in_trampoline = True
|
||||||
instr = None
|
instr = None
|
||||||
|
|
27
verif/tb/core/rvfi_pkg.sv
Normal file
27
verif/tb/core/rvfi_pkg.sv
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
`ifndef __UVMA_RVFI_PKG_SV__
|
||||||
|
`define __UVMA_RVFI_PKG_SV__
|
||||||
|
|
||||||
|
// Pre-processor macros
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`define uvm_info(TOP,MSG,LVL) \
|
||||||
|
$display(TOP + ":" + MSG);
|
||||||
|
`define uvm_fatal(TOP,MSG) \
|
||||||
|
$display(TOP + ":" + MSG); $finish();
|
||||||
|
`else
|
||||||
|
`include "uvm_macros.svh"
|
||||||
|
`endif
|
||||||
|
|
||||||
|
package rvfi_pkg;
|
||||||
|
|
||||||
|
`ifndef VERILATOR
|
||||||
|
import uvm_pkg ::*;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
`include "uvma_rvfi_constants.sv"
|
||||||
|
`include "uvma_rvfi_tdefs.sv"
|
||||||
|
`include "uvma_rvfi_utils.sv"
|
||||||
|
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
`endif
|
|
@ -32,7 +32,7 @@ import uvm_pkg::*;
|
||||||
|
|
||||||
import "DPI-C" function read_elf(input string filename);
|
import "DPI-C" function read_elf(input string filename);
|
||||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
import "DPI-C" function byte get_section(output longint address, output longint len);
|
||||||
import "DPI-C" context function void read_section(input longint address, inout byte buffer[]);
|
import "DPI-C" context function void read_section_sv(input longint address, inout byte buffer[]);
|
||||||
|
|
||||||
module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||||
|
@ -244,12 +244,11 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
longint address;
|
longint address;
|
||||||
longint len;
|
longint len;
|
||||||
byte buffer[];
|
byte buffer[];
|
||||||
void'(uvcl.get_arg_value("+PRELOAD=", binary));
|
void'(uvcl.get_arg_value("+elf_file=", binary));
|
||||||
|
|
||||||
if (binary != "") begin
|
if (binary != "") begin
|
||||||
|
|
||||||
void'(read_elf(binary));
|
void'(read_elf(binary));
|
||||||
|
|
||||||
wait(clk_i);
|
wait(clk_i);
|
||||||
|
|
||||||
// while there are more sections to process
|
// while there are more sections to process
|
||||||
|
@ -257,7 +256,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
automatic int num_words0 = (len+7)/8;
|
automatic int num_words0 = (len+7)/8;
|
||||||
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_LOW)
|
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_LOW)
|
||||||
buffer = new [num_words0*8];
|
buffer = new [num_words0*8];
|
||||||
void'(read_section(address, buffer));
|
void'(read_section_sv(address, buffer));
|
||||||
// preload memories
|
// preload memories
|
||||||
// 64-bit
|
// 64-bit
|
||||||
for (int i = 0; i < num_words0; i++) begin
|
for (int i = 0; i < num_words0; i++) begin
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
-f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist
|
-f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist
|
||||||
-f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist
|
-f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist
|
||||||
-f ${DV_UVMA_ISACOV_PATH}/uvma_isacov_pkg.flist
|
-f ${DV_UVMA_ISACOV_PATH}/uvma_isacov_pkg.flist
|
||||||
|
-f ${DV_UVMC_RVFI_REFERENCE_MODEL_PATH}/uvmc_rvfi_reference_model_pkg.flist
|
||||||
|
-f ${DV_UVMC_RVFI_SB_PATH}/uvmc_rvfi_scoreboard_pkg.flist
|
||||||
|
|
||||||
// Environments
|
// Environments
|
||||||
-f ${CVA6_UVME_PATH}/uvme_cva6_pkg.flist
|
-f ${CVA6_UVME_PATH}/uvme_cva6_pkg.flist
|
||||||
|
|
|
@ -38,6 +38,7 @@ package uvmt_cva6_pkg;
|
||||||
|
|
||||||
import uvm_pkg::*;
|
import uvm_pkg::*;
|
||||||
import uvme_cva6_pkg::*;
|
import uvme_cva6_pkg::*;
|
||||||
|
import uvmc_rvfi_reference_model_pkg::*;
|
||||||
import uvml_hrtbt_pkg::*;
|
import uvml_hrtbt_pkg::*;
|
||||||
import uvml_logs_pkg::*;
|
import uvml_logs_pkg::*;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ module uvmt_cva6_tb;
|
||||||
import uvmt_cva6_pkg::*;
|
import uvmt_cva6_pkg::*;
|
||||||
import uvme_cva6_pkg::*;
|
import uvme_cva6_pkg::*;
|
||||||
|
|
||||||
|
localparam RVFI_NRET = cva6_config_pkg::CVA6ConfigNrCommitPorts;
|
||||||
|
|
||||||
// CVA6 config
|
// CVA6 config
|
||||||
localparam config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg;
|
localparam config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg;
|
||||||
localparam bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace);
|
localparam bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace);
|
||||||
|
@ -82,9 +84,9 @@ module uvmt_cva6_tb;
|
||||||
uvma_rvfi_instr_if #(
|
uvma_rvfi_instr_if #(
|
||||||
uvme_cva6_pkg::ILEN,
|
uvme_cva6_pkg::ILEN,
|
||||||
uvme_cva6_pkg::XLEN
|
uvme_cva6_pkg::XLEN
|
||||||
) rvfi_instr_if [uvme_cva6_pkg::RVFI_NRET-1:0] ();
|
) rvfi_instr_if [RVFI_NRET-1:0] ();
|
||||||
|
|
||||||
uvma_rvfi_csr_if#(uvme_cva6_pkg::XLEN) rvfi_csr_if [uvme_cva6_pkg::RVFI_NRET-1:0]();
|
uvma_rvfi_csr_if#(uvme_cva6_pkg::XLEN) rvfi_csr_if [RVFI_NRET-1:0]();
|
||||||
|
|
||||||
uvmt_default_inputs_intf default_inputs_vif();
|
uvmt_default_inputs_intf default_inputs_vif();
|
||||||
|
|
||||||
|
@ -132,13 +134,14 @@ module uvmt_cva6_tb;
|
||||||
.rvfi_o(rvfi_if.rvfi_o)
|
.rvfi_o(rvfi_if.rvfi_o)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (genvar i = 0; i < uvme_cva6_pkg::RVFI_NRET; i++) begin
|
for (genvar i = 0; i < RVFI_NRET; i++) begin
|
||||||
assign rvfi_instr_if[i].clk = clknrst_if.clk;
|
assign rvfi_instr_if[i].clk = clknrst_if.clk;
|
||||||
assign rvfi_instr_if[i].reset_n = clknrst_if.reset_n;
|
assign rvfi_instr_if[i].reset_n = clknrst_if.reset_n;
|
||||||
assign rvfi_instr_if[i].rvfi_valid = rvfi_if.rvfi_o[i].valid;
|
assign rvfi_instr_if[i].rvfi_valid = rvfi_if.rvfi_o[i].valid;
|
||||||
assign rvfi_instr_if[i].rvfi_order = rvfi_if.rvfi_o[i].order;
|
assign rvfi_instr_if[i].rvfi_order = rvfi_if.rvfi_o[i].order;
|
||||||
assign rvfi_instr_if[i].rvfi_insn = rvfi_if.rvfi_o[i].insn;
|
assign rvfi_instr_if[i].rvfi_insn = rvfi_if.rvfi_o[i].insn;
|
||||||
assign rvfi_instr_if[i].rvfi_trap = rvfi_if.rvfi_o[i].trap;
|
assign rvfi_instr_if[i].rvfi_trap = rvfi_if.rvfi_o[i].trap;
|
||||||
|
assign rvfi_instr_if[i].rvfi_cause = rvfi_if.rvfi_o[i].cause;
|
||||||
assign rvfi_instr_if[i].rvfi_halt = rvfi_if.rvfi_o[i].halt;
|
assign rvfi_instr_if[i].rvfi_halt = rvfi_if.rvfi_o[i].halt;
|
||||||
assign rvfi_instr_if[i].rvfi_intr = rvfi_if.rvfi_o[i].intr;
|
assign rvfi_instr_if[i].rvfi_intr = rvfi_if.rvfi_o[i].intr;
|
||||||
assign rvfi_instr_if[i].rvfi_mode = rvfi_if.rvfi_o[i].mode;
|
assign rvfi_instr_if[i].rvfi_mode = rvfi_if.rvfi_o[i].mode;
|
||||||
|
@ -165,7 +168,7 @@ module uvmt_cva6_tb;
|
||||||
assign default_inputs_vif.debug_req = 1'b0;
|
assign default_inputs_vif.debug_req = 1'b0;
|
||||||
|
|
||||||
|
|
||||||
for (genvar i = 0; i < uvme_cva6_pkg::RVFI_NRET; i++) begin
|
for (genvar i = 0; i < RVFI_NRET; i++) begin
|
||||||
initial begin
|
initial begin
|
||||||
uvm_config_db#(virtual uvma_rvfi_instr_if )::set(null,"*", $sformatf("instr_vif%0d", i), rvfi_instr_if[i]);
|
uvm_config_db#(virtual uvma_rvfi_instr_if )::set(null,"*", $sformatf("instr_vif%0d", i), rvfi_instr_if[i]);
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,11 @@ class uvmt_cva6_firmware_test_c extends uvmt_cva6_base_test_c;
|
||||||
*/
|
*/
|
||||||
extern virtual task configure_phase(uvm_phase phase);
|
extern virtual task configure_phase(uvm_phase phase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override types with the UVM Factory
|
||||||
|
*/
|
||||||
|
extern virtual function void build_phase(uvm_phase phase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable program execution, wait for completion.
|
* Enable program execution, wait for completion.
|
||||||
*/
|
*/
|
||||||
|
@ -92,6 +97,14 @@ task uvmt_cva6_firmware_test_c::reset_phase(uvm_phase phase);
|
||||||
|
|
||||||
endtask : reset_phase
|
endtask : reset_phase
|
||||||
|
|
||||||
|
function void uvmt_cva6_firmware_test_c::build_phase(uvm_phase phase);
|
||||||
|
super.build_phase(phase);
|
||||||
|
|
||||||
|
`uvm_info("firmware_test", "Overriding Reference Model with Spike", UVM_NONE)
|
||||||
|
set_type_override_by_type(uvmc_rvfi_reference_model::get_type(),uvmc_rvfi_spike::get_type());
|
||||||
|
|
||||||
|
endfunction : build_phase
|
||||||
|
|
||||||
|
|
||||||
task uvmt_cva6_firmware_test_c::configure_phase(uvm_phase phase);
|
task uvmt_cva6_firmware_test_c::configure_phase(uvm_phase phase);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue