Spike Tandem Implementation using VCS simulator (#1561)

This commit is contained in:
MarioOpenHWGroup 2023-11-09 19:29:24 +01:00 committed by GitHub
parent 3c45510934
commit 220f534b6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 354 additions and 638 deletions

View file

@ -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 }}

View file

@ -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

View file

@ -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,,$@)

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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 config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg,
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 longint unsigned DramBase = 'h8000_0000,
parameter int unsigned Size = 64 * 1024 * 1024 // 64 Mega Byte 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);
instr = (commit_log.instr[1:0] != 2'b11) ? {16'b0, commit_log.instr[15:0]} : commit_log.instr;
// $display("\x1B[32m%h %h\x1B[0m", commit_log.pc, instr);
// $display("%p", commit_log);
// $display("\x1B[37m%h %h\x1B[0m", commit_instr_i[i].pc, commit_instr_i[i].ex.tval[31:0]);
assert (commit_log.pc === commit_instr_i[i].pc) else begin
$warning("\x1B[33m[Tandem] PCs Mismatch\x1B[0m");
// $stop;
end
assert (commit_log.was_exception === exception_i.valid) else begin
$warning("\x1B[33m[Tandem] Exception not detected\x1B[0m");
// $stop;
$display("Spike: %p", commit_log);
$display("Ariane: %p", commit_instr_i[i]);
end
if (!exception_i.valid) begin
assert (commit_log.priv === priv_lvl_i) else begin
$warning("\x1B[33m[Tandem] Privilege level mismatches\x1B[0m");
// $stop;
$display("\x1B[37m %2d == %2d @ PC %h\x1B[0m", priv_lvl_i, commit_log.priv, commit_log.pc);
end
assert (instr === commit_instr_i[i].ex.tval) else begin
$warning("\x1B[33m[Tandem] Decoded instructions mismatch\x1B[0m");
// $stop;
$display("\x1B[37m%h === %h @ PC %h\x1B[0m", commit_instr_i[i].ex.tval, instr, commit_log.pc);
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
// we want to schedule the timer increment at the end of this cycle if (rvfi_i[i].valid || rvfi_i[i].trap) begin
assign #1ps fake_clk = clk_i; spike_step(t_reference_model);
t_core.order = rvfi_i[i].order;
t_core.insn = rvfi_i[i].insn;
t_core.trap = rvfi_i[i].trap;
t_core.cause = rvfi_i[i].cause;
t_core.halt = rvfi_i[i].halt;
t_core.intr = rvfi_i[i].intr;
t_core.mode = rvfi_i[i].mode;
t_core.ixl = rvfi_i[i].ixl;
t_core.rs1_addr = rvfi_i[i].rs1_addr;
t_core.rs2_addr = rvfi_i[i].rs2_addr;
t_core.rs1_rdata = rvfi_i[i].rs1_rdata;
t_core.rs2_rdata = rvfi_i[i].rs2_rdata;
t_core.rd1_addr = rvfi_i[i].rd_addr;
t_core.rd1_wdata = rvfi_i[i].rd_wdata;
t_core.pc_rdata = rvfi_i[i].pc_rdata;
t_core.pc_wdata = rvfi_i[i].pc_wdata;
t_core.mem_addr = rvfi_i[i].mem_addr;
t_core.mem_rmask = rvfi_i[i].mem_rmask;
t_core.mem_wmask = rvfi_i[i].mem_wmask;
t_core.mem_rdata = rvfi_i[i].mem_rdata;
t_core.mem_wdata = rvfi_i[i].mem_wdata;
always_ff @(posedge fake_clk) begin rvfi_compare(t_core, t_reference_model);
clint_tick_q <= clint_tick_i; end
clint_tick_qq <= clint_tick_q;
clint_tick_qqq <= clint_tick_qq;
clint_tick_qqqq <= clint_tick_qqq;
end end
always_ff @(posedge clint_tick_qqqq) begin
if (rst_ni) begin
void'(clint_tick());
end end
end end
endmodule endmodule

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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__

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
if [[ ! -f config.log ]]; then
../configure --prefix="$SPIKE_INSTALL_DIR" ../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

View file

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

View file

@ -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

View file

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

View file

@ -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

View file

@ -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

View file

@ -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::*;

View file

@ -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]);

View file

@ -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);