mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
Update google_riscv-dv to google/riscv-dv@faddfa4 (#263)
Update code from upstream repository https://github.com/google/riscv- dv to revision faddfa49f456f3f8ef8c4231865994b7b13aa96d * Obsolete test clean up (Tao Liu) * Remove the old flow (Tao Liu) * minor fix, update README for A extension support (Tao Liu) * Add basic atomic instruction test (Tao Liu) * Add RV32A/RV64A instructions (google/riscv-dv#95) (Tao Liu) * Fix the missing GPR save operations for exception handling (Tao Liu) * Generate handshake sequence to communicate with testbench (Udi) * Fix compare error (Tao Liu) * Fix compare error (Tao Liu) * Initial signature enum for handshake protocol (Udi)
This commit is contained in:
parent
5d1f8e16bc
commit
ce8be4f2fd
22 changed files with 462 additions and 949 deletions
2
vendor/google_riscv-dv.lock.hjson
vendored
2
vendor/google_riscv-dv.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/google/riscv-dv
|
||||
rev: e81acc9ab4f692ff205a207c2dc3d9f2b0284d39
|
||||
rev: faddfa49f456f3f8ef8c4231865994b7b13aa96d
|
||||
}
|
||||
}
|
||||
|
|
69
vendor/google_riscv-dv/README.md
vendored
69
vendor/google_riscv-dv/README.md
vendored
|
@ -3,7 +3,7 @@
|
|||
RISCV-DV is a SV/UVM based open-source instruction generator for RISC-V
|
||||
processor verification. It currently supports the following features:
|
||||
|
||||
- Supported instruction set: RV32IMC, RV64IMC
|
||||
- Supported instruction set: RV32IMAC, RV64IMAC
|
||||
- Supported privileged mode: machine mode, supervisor mode, user mode
|
||||
- Page table randomization and exception
|
||||
- Privileged CSR setup randomization
|
||||
|
@ -370,73 +370,6 @@ We have some work in progress which will be part of future releases:
|
|||
- Coverage model.
|
||||
- Debug mode support
|
||||
|
||||
### DEPRECATED simulation flow
|
||||
|
||||
Note: The flow mentioned below will soon be deprecated. Please switch to new
|
||||
flow.
|
||||
|
||||
A simple script "run" is provided for you to run a single test or a regression.
|
||||
Here is the command to run a single test:
|
||||
|
||||
```
|
||||
./run -test riscv_instr_base_test
|
||||
```
|
||||
You can specify the simulator by "-tool" option
|
||||
|
||||
```
|
||||
./run -test riscv_instr_base_test -tool irun
|
||||
./run -test riscv_instr_base_test -tool vcs
|
||||
./run -test riscv_instr_base_test -tool questa
|
||||
```
|
||||
The complete test list can be found in testlist. To run a full regression, you
|
||||
can just specify the test name to "all".
|
||||
|
||||
```
|
||||
./run -test all
|
||||
```
|
||||
The script will run each test in the test list sequentially with the iteration
|
||||
count specified in the "testlist". All the generated RISC-V assembly will be
|
||||
listed when the regression is done. If it is successful, you should see the
|
||||
following output:
|
||||
|
||||
```
|
||||
===========================================================
|
||||
Generated RISC-V assembly tests
|
||||
----------------------------------------------------------
|
||||
./out_2018-11-20/asm_tests/riscv_arithmetic_basic_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_machine_mode_rand_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_mmu_stress_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_mmu_stress_test.1.S
|
||||
./out_2018-11-20/asm_tests/riscv_no_fence_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_page_table_exception_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_page_table_exception_test.1.S
|
||||
./out_2018-11-20/asm_tests/riscv_privileged_mode_rand_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_privileged_mode_rand_test.1.S
|
||||
./out_2018-11-20/asm_tests/riscv_rand_instr_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_rand_instr_test.1.S
|
||||
./out_2018-11-20/asm_tests/riscv_rand_jump_test.0.S
|
||||
./out_2018-11-20/asm_tests/riscv_sfence_exception_test.0.S
|
||||
```
|
||||
|
||||
Here's a few more examples of the run command:
|
||||
|
||||
```
|
||||
// Run a single test 10 times
|
||||
./run -test riscv_page_table_exception_test -n 10
|
||||
|
||||
// Run a test with a specified seed
|
||||
./run -test riscv_page_table_exception_test -seed 123
|
||||
|
||||
// Run a test with addtional runtime options, separated with comma
|
||||
./run -test riscv_rand_instr_test -runo +instr_cnt=10000,+no_fence=1
|
||||
|
||||
// Two steps compile and simulation (Avoid multiple compilation)
|
||||
./run -co # compile only
|
||||
# Generate multiple tests
|
||||
./run -so -test riscv_rand_instr_test -n 10
|
||||
./run -so -test riscv_mmu_stress_test -n 20
|
||||
....
|
||||
```
|
||||
## Disclaimer
|
||||
|
||||
This is not an officially supported Google product.
|
||||
|
|
1
vendor/google_riscv-dv/files.f
vendored
1
vendor/google_riscv-dv/files.f
vendored
|
@ -17,6 +17,7 @@
|
|||
+incdir+./test
|
||||
|
||||
// SOURCES
|
||||
./src/riscv_signature_pkg.sv
|
||||
./src/riscv_instr_pkg.sv
|
||||
./test/riscv_instr_test_pkg.sv
|
||||
./test/riscv_instr_gen_tb_top.sv
|
||||
|
|
40
vendor/google_riscv-dv/iss_cmp
vendored
40
vendor/google_riscv-dv/iss_cmp
vendored
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2018 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
spike_log="$1"
|
||||
ovpsim_log="$2"
|
||||
report_file="$3"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Convert spike log to standard instruction trace csv
|
||||
# -----------------------------------------------------------------------------
|
||||
# Convert the spike log to riscv_instr_trace.proto format
|
||||
spike_csv=$(echo "$spike_log" | sed 's/\.log/.csv/g')
|
||||
python scripts/spike_log_to_trace_csv.py --log $spike_log \
|
||||
--csv $spike_csv --xlen 64
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Convert ovpsim log to standard instruction trace csv
|
||||
# -----------------------------------------------------------------------------
|
||||
# Convert the spike log to riscv_instr_trace.proto format
|
||||
ovpsim_csv=$(echo "$ovpsim_log" | sed 's/\.log/.csv/g')
|
||||
python scripts/ovpsim_log_to_trace_csv.py --log $ovpsim_log --csv $ovpsim_csv
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Compare the trace log
|
||||
# -----------------------------------------------------------------------------
|
||||
python scripts/instr_trace_compare.py $spike_csv $ovpsim_csv \
|
||||
spike ovpsim >> $report_file
|
||||
echo >> $report_file
|
191
vendor/google_riscv-dv/iss_sim
vendored
191
vendor/google_riscv-dv/iss_sim
vendored
|
@ -1,191 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2018 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Environment variable for the path of RISC-V GCC toolchain
|
||||
# You can install the toolchain from https://github.com/riscv/riscv-gcc
|
||||
# RISCV_TOOLCHAIN="XXX"
|
||||
|
||||
# GCC compile options
|
||||
ABI="lp64"
|
||||
ISA="rv64imc"
|
||||
|
||||
DATE=`date +%Y-%m-%d`
|
||||
|
||||
# Instruction set simulator
|
||||
ISS="spike" # other options: ovpsim, all
|
||||
|
||||
# riscv-ovpsim options
|
||||
OVPSIM_VARIANT="RV64GC"
|
||||
|
||||
# Binary of RISC-V ovpsim ISS
|
||||
# https://github.com/riscv/riscv-ovpsim
|
||||
RISCV_OVPSIM="${OVPSIM_PATH}/riscvOVPsim.exe"
|
||||
|
||||
# Directory of assemble tests
|
||||
SRC_DIR="./out_${DATE}/asm_tests"
|
||||
|
||||
# Assembly test file name
|
||||
TEST=""
|
||||
|
||||
# Regression report file name
|
||||
REPORT="$SRC_DIR/regression_report.log"
|
||||
|
||||
# Clean the result of the previous runs
|
||||
CLEAN=1
|
||||
|
||||
if [[ -z $RISCV_TOOLCHAIN ]]; then
|
||||
echo "ERROR: Please define RISCV_TOOLCHAIN environment variable first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Process command line options
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
case $key in
|
||||
-iss)
|
||||
ISS="$2"
|
||||
shift
|
||||
;;
|
||||
-dir)
|
||||
SRC_DIR="$2"
|
||||
shift
|
||||
;;
|
||||
-toolchain)
|
||||
RISCV_TOOLCHAIN="$2"
|
||||
shift
|
||||
;;
|
||||
-isa)
|
||||
ISA="$2"
|
||||
shift
|
||||
;;
|
||||
-abi)
|
||||
ABI="$2"
|
||||
shift
|
||||
;;
|
||||
-test)
|
||||
TEST="$2"
|
||||
shift
|
||||
;;
|
||||
-report)
|
||||
REPORT="$2"
|
||||
shift
|
||||
;;
|
||||
-noclean)
|
||||
CLEAN=0
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "unknown option $1"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
RISCV_GCC="$RISCV_TOOLCHAIN/bin/riscv64-unknown-elf-gcc"
|
||||
RISCV_OBJCOPY="$RISCV_TOOLCHAIN/bin/riscv64-unknown-elf-objcopy"
|
||||
RISCV_SPIKE="$RISCV_TOOLCHAIN/bin/spike"
|
||||
|
||||
mkdir -p "$SRC_DIR"
|
||||
|
||||
# If the test is specified through "-test" option, run a single test rather
|
||||
# than all tests under SRC_DIR.
|
||||
if [[ $TEST == "" ]]; then
|
||||
find "$SRC_DIR" -name "*.S" > "$SRC_DIR/asm_test_list"
|
||||
else
|
||||
echo "$TEST" > "$SRC_DIR/asm_test_list"
|
||||
fi
|
||||
|
||||
if [[ $ISA =~ 32 ]]; then
|
||||
OVPSIM_VARIANT="RV32GC"
|
||||
fi
|
||||
|
||||
# Clean up previous running result
|
||||
if [[ $CLEAN == 1 ]]; then
|
||||
rm -rf "$REPORT"
|
||||
if [[ "$ISS" == "spike" ]] || [[ "$ISS" == "all" ]]; then
|
||||
rm -rf "$SRC_DIR/spike_sim"
|
||||
fi
|
||||
if [[ "$ISS" == "ovpsim" ]] || [[ "$ISS" == "all" ]]; then
|
||||
rm -rf "$SRC_DIR/riscv_ovpsim"
|
||||
fi
|
||||
fi
|
||||
|
||||
# GCC compile
|
||||
while read asm_test; do
|
||||
# Generate binary for RTL simulation
|
||||
SRC="$asm_test"
|
||||
OBJFILE="$asm_test.o"
|
||||
BINFILE="$asm_test.bin"
|
||||
GCC_CMD="$RISCV_GCC -march=$ISA -mabi=$ABI -static -mcmodel=medany \
|
||||
-fvisibility=hidden -nostdlib \
|
||||
-nostartfiles -I$RISCV_TESTS/env/p \
|
||||
-Tscripts/link.ld $SRC -o $OBJFILE"
|
||||
echo "riscv_gcc compiling : $SRC"
|
||||
$($GCC_CMD)
|
||||
echo "Convert $OBJFILE to $BINFILE"
|
||||
# Convert the ELF to plain binary
|
||||
# You can load this binary to your RTL simulation
|
||||
"$RISCV_OBJCOPY" -O binary "$OBJFILE" "$BINFILE"
|
||||
done <"$SRC_DIR/asm_test_list"
|
||||
|
||||
if [[ "$ISS" == "ovpsim" ]] || [[ "$ISS" == "all" ]]; then
|
||||
mkdir -p "$SRC_DIR/riscv_ovpsim"
|
||||
fi
|
||||
if [[ "$ISS" == "spike" ]] || [[ "$ISS" == "all" ]]; then
|
||||
mkdir -p "$SRC_DIR/spike_sim"
|
||||
fi
|
||||
|
||||
# Run ISS simulation
|
||||
while read asm_test; do
|
||||
ELF="${asm_test}.o"
|
||||
TEST_NAME=$(echo "$ELF" | sed 's/^.*\///g')
|
||||
# Spike sim
|
||||
if [[ "$ISS" == "spike" ]] || [[ "$ISS" == "all" ]]; then
|
||||
echo "Running spike: $TEST_NAME"
|
||||
SPIKE_LOG="$SRC_DIR/spike_sim/$TEST_NAME.log"
|
||||
SPIKE_CMD="timeout 60s $RISCV_SPIKE --isa=$ISA -l $ELF &> $SPIKE_LOG"
|
||||
$($SPIKE_CMD &> $SPIKE_LOG)
|
||||
fi
|
||||
# riscv_ovpsim sim
|
||||
if [[ "$ISS" == "ovpsim" ]] || [[ "$ISS" == "all" ]]; then
|
||||
if [[ -z $OVPSIM_PATH ]]; then
|
||||
echo "ERROR: Please define OVPSIM_PATH environment variable first"
|
||||
exit 1
|
||||
fi
|
||||
OVPSIM_LOG="$SRC_DIR/riscv_ovpsim/$TEST_NAME.log"
|
||||
echo "Running ovpsim: $TEST_NAME"
|
||||
RISCV_OVPSIM_CMD="$RISCV_OVPSIM --variant $OVPSIM_VARIANT \
|
||||
--override riscvOVPsim/cpu/PMP_registers=0 \
|
||||
--override riscvOVPsim/cpu/simulateexceptions=T \
|
||||
--trace --tracechange --traceshowicount --program $ELF \
|
||||
--finishafter 500000"
|
||||
$($RISCV_OVPSIM_CMD &> $OVPSIM_LOG)
|
||||
fi
|
||||
if [[ "$ISS" == "all" ]]; then
|
||||
echo "Rerun command: ./iss_sim -test $asm_test -iss all" >> "$REPORT"
|
||||
echo "spike : $SPIKE_LOG" >> "$REPORT"
|
||||
echo "ovpsim : $OVPSIM_LOG" >> "$REPORT"
|
||||
./iss_cmp "$SPIKE_LOG" "$OVPSIM_LOG" "$REPORT"
|
||||
tail -1 "$REPORT"
|
||||
echo "" >> "$REPORT"
|
||||
fi
|
||||
done <"$SRC_DIR/asm_test_list"
|
||||
|
||||
if [[ "$ISS" == "all" ]]; then
|
||||
echo "Full regression report is saved to $REPORT"
|
||||
cat "$REPORT"
|
||||
fi
|
308
vendor/google_riscv-dv/run
vendored
308
vendor/google_riscv-dv/run
vendored
|
@ -1,308 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2018 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# This is simple run script to run a dedicated test or a regression
|
||||
#
|
||||
# Usage:
|
||||
# Run a single test with irun
|
||||
# ./run -tool irun -test riscv_instr_base_test
|
||||
#
|
||||
# Run regression with vcs
|
||||
# ./run -test all
|
||||
#
|
||||
# Change output directory
|
||||
# ./run -out my_output_dir
|
||||
|
||||
DATE=`date +%Y-%m-%d`
|
||||
|
||||
# RTL simulator, supports vcs, irun, and questa
|
||||
SIMULATOR="vcs"
|
||||
|
||||
# random seed
|
||||
SEED=`date +%s`
|
||||
|
||||
# Test name, "all" means run all tests in the testlist
|
||||
TEST="riscv_instr_base_test"
|
||||
|
||||
# Number of assembly programs to be generated for this test
|
||||
# This option only apply to single test mode. For the regression mode, the number is specified in
|
||||
# the testlist
|
||||
NUM_TESTS=1
|
||||
|
||||
# Simulation output directory
|
||||
OUT="./out_${DATE}"
|
||||
|
||||
# Simulation only
|
||||
SIM_ONLY=0
|
||||
|
||||
# Compile only
|
||||
CMP_ONLY=0
|
||||
|
||||
# Compile/run time options
|
||||
SIM_OPTS=""
|
||||
CMP_OPTS=""
|
||||
|
||||
# Verbose logging, by default disable detail logging
|
||||
VERBOSE=0
|
||||
|
||||
# Submit to LSF
|
||||
LSF_CMD="bsub"
|
||||
LSF_OPTS=""
|
||||
LSF=0
|
||||
LSF_TIMEOUT=100
|
||||
|
||||
# Testlist for regression
|
||||
TEST_LIST=testlist
|
||||
|
||||
# Process command line options
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
case $key in
|
||||
-tool)
|
||||
SIMULATOR="$2"
|
||||
shift
|
||||
;;
|
||||
-test)
|
||||
TEST="$2"
|
||||
shift
|
||||
;;
|
||||
-n)
|
||||
NUM_TESTS="$2"
|
||||
shift
|
||||
;;
|
||||
-seed)
|
||||
SEED="$2"
|
||||
shift
|
||||
;;
|
||||
-sim_opts)
|
||||
SIM_OPTS="$2"
|
||||
shift
|
||||
;;
|
||||
-cmp_opts)
|
||||
CMP_OPTS="$2"
|
||||
shift
|
||||
;;
|
||||
-testlist)
|
||||
TEST_LIST="$2"
|
||||
shift
|
||||
;;
|
||||
-timeout)
|
||||
LSF_TIMEOUT="$2"
|
||||
shift
|
||||
;;
|
||||
-so)
|
||||
SIM_ONLY=1
|
||||
;;
|
||||
-verbose)
|
||||
VERBOSE=1
|
||||
;;
|
||||
-co)
|
||||
CMP_ONLY=1
|
||||
;;
|
||||
-lsf)
|
||||
LSF=1
|
||||
;;
|
||||
-lsf_opts)
|
||||
LSF_OPTS="$2"
|
||||
shift
|
||||
;;
|
||||
-o)
|
||||
OUT="$2"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ $LSF == 0 ]]; then
|
||||
LSF_CMD=""
|
||||
fi
|
||||
|
||||
OUT=`realpath ${OUT}`
|
||||
|
||||
# Generate compile and simulation commands
|
||||
if [[ "$SIMULATOR" == "vcs" ]]; then
|
||||
|
||||
function run_compile {
|
||||
vcs -file ./vcs.compile.option.f \
|
||||
-f ./files.f -full64 \
|
||||
-l $OUT/compile.log \
|
||||
-Mdir=$OUT/vcs_simv.csrc \
|
||||
-o $OUT/vcs_simv ${CMP_OPTS}
|
||||
}
|
||||
|
||||
SIM_CMD="$OUT/vcs_simv +vcs+lic+wait +UVM_TESTNAME="
|
||||
SIM_SEED="+ntb_random_seed="
|
||||
|
||||
elif [[ "$SIMULATOR" == "irun" ]]; then
|
||||
|
||||
function run_compile {
|
||||
irun -64bit \
|
||||
-access +rwc \
|
||||
-f ./files.f \
|
||||
-q -sv -uvm \
|
||||
-vlog_ext +.vh -I. \
|
||||
-uvmhome CDNS-1.2 \
|
||||
-elaborate \
|
||||
-l ${OUT}/compile.log ${CMP_OPTS}
|
||||
}
|
||||
|
||||
SIM_CMD="irun -R +UVM_TESTNAME="
|
||||
SIM_SEED="-svseed "
|
||||
|
||||
elif [[ "$SIMULATOR" == "questa" ]]; then
|
||||
#Questa requires mapping libraries to compile correctly
|
||||
function run_compile {
|
||||
vmap mtiUvm $QUESTA_HOME/questasim/uvm-1.2
|
||||
vlog -64 \
|
||||
-access=rwc \
|
||||
-f ./files.f \
|
||||
-sv \
|
||||
-mfcu -cuname design_cuname \
|
||||
+define+UVM_REGEX_NO_DPI \
|
||||
-writetoplevels ${OUT}/top.list \
|
||||
-l ${OUT}/compile.log ${CMP_OPTS}
|
||||
vopt -64 -debug \
|
||||
+designfile -f ${OUT}/top.list \
|
||||
-l ${OUT}/optimize.log ${CMP_OPTS} \
|
||||
-o design_opt
|
||||
}
|
||||
|
||||
SIM_CMD="vsim -64 -c -do questa_sim.tcl design_opt +UVM_TESTNAME="
|
||||
SIM_SEED="-sv_seed "
|
||||
|
||||
else
|
||||
echo "unsupported simulator $SIMULATOR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up previous runs
|
||||
if [[ $SIM_ONLY == 0 ]]; then
|
||||
rm -rf ${OUT}
|
||||
else
|
||||
rm -rf ${OUT}/asm_tests
|
||||
fi
|
||||
|
||||
mkdir -p ${OUT}
|
||||
mkdir -p ${OUT}/asm_tests
|
||||
|
||||
# Compilation
|
||||
if [[ $SIM_ONLY == 0 ]]; then
|
||||
echo "Building RISC-V instruction generator..."
|
||||
if [[ $VERBOSE == 1 ]]; then
|
||||
run_compile
|
||||
else
|
||||
run_compile > /dev/null
|
||||
fi
|
||||
echo "Building RISC-V instruction generator...done"
|
||||
fi
|
||||
|
||||
# Skip simulation if compilation only flag is set
|
||||
if [[ $CMP_ONLY == 1 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run sim
|
||||
if [[ ${TEST} == "all" ]]; then
|
||||
echo "Running regression with testlist: $TEST_LIST"
|
||||
LOG_LIST="${OUT}/sim_log.list"
|
||||
PROGRAM_CNT=0
|
||||
cat "$TEST_LIST"
|
||||
rm -rf "$LOG_LIST"
|
||||
while read line; do
|
||||
if ! [[ $line =~ ^\/\/ ]]; then
|
||||
if [[ $line =~([a-z0-9_-]*)([[:space:]]*)\:([[:space:]]*)([0-9]*)([[:space:]]*)\:(.*$) ]]; then
|
||||
SEED=`date +%s`
|
||||
TEST=${BASH_REMATCH[1]}
|
||||
ITERATION=${BASH_REMATCH[4]}
|
||||
TEST_OPTS=${BASH_REMATCH[6]}
|
||||
if [[ ${ITERATION} != "0" ]]; then
|
||||
echo "Running ${TEST} to generate ${ITERATION} tests"
|
||||
CMD="${SIM_CMD}${TEST} +asm_file_name=${OUT}/asm_tests/${TEST} \
|
||||
${SIM_SEED}${SEED} ${TEST_OPTS} ${SIM_OPTS} \
|
||||
-l ${OUT}/sim_${TEST}.log +num_of_tests=${ITERATION}"
|
||||
((PROGRAM_CNT+=$ITERATION))
|
||||
echo "${OUT}/sim_${TEST}.log" >> ${LOG_LIST}
|
||||
if [[ $VERBOSE == 1 ]]; then
|
||||
${LSF_CMD} ${LSF_OPTS} ${CMD}
|
||||
else
|
||||
${LSF_CMD} ${LSF_OPTS} ${CMD} > /dev/null
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done < $TEST_LIST
|
||||
# Wait util all tests are generated
|
||||
if [[ $LSF == 1 ]]; then
|
||||
TIMEOUT_CNT=0
|
||||
TOTAL_CNT=`wc -l < ${LOG_LIST}`
|
||||
echo "Waiting for ${TOTAL_CNT} tests to complete, ${PROGRAM_CNT} programs to generate."
|
||||
while [[ 1 ]]; do
|
||||
COMPLETED_CNT=0
|
||||
while read log; do
|
||||
if [[ -f "$log" ]]; then
|
||||
if grep -q "TEST GENERATION DONE" $log; then
|
||||
((COMPLETED_CNT+=1))
|
||||
else
|
||||
if [[ $VERBOSE == 1 ]]; then
|
||||
echo "$log is not completed"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [[ $VERBOSE == 1 ]]; then
|
||||
echo "$log is not completed"
|
||||
fi
|
||||
fi
|
||||
done < ${LOG_LIST}
|
||||
GENERATED_CNT=`find ${OUT}/asm_tests/ -name "*.S" | wc -l`
|
||||
echo "[$TIMEOUT_CNT] Progress > Test:${COMPLETED_CNT}/${TOTAL_CNT} Program:${GENERATED_CNT}/${PROGRAM_CNT}"
|
||||
if [[ "$COMPLETED_CNT" == "$TOTAL_CNT" ]]; then
|
||||
break
|
||||
else
|
||||
if [[ "$TIMEOUT_CNT" == "$LSF_TIMEOUT" ]]; then
|
||||
echo "Generator timeout after $LSF_TIMEOUT * 10 seconds"
|
||||
break
|
||||
else
|
||||
sleep 10
|
||||
fi
|
||||
fi
|
||||
((TIMEOUT_CNT+=1))
|
||||
done
|
||||
fi
|
||||
else
|
||||
echo "Running test ${TEST} to generate ${NUM_TESTS} tests"
|
||||
CMD="${SIM_CMD}${TEST} +asm_file_name=${OUT}/asm_tests/${TEST} \
|
||||
${SIM_SEED}${SEED} \
|
||||
-l ${OUT}/sim_${TEST}.log \
|
||||
+num_of_tests=${NUM_TESTS} ${SIM_OPTS}"
|
||||
if [[ $VERBOSE == 1 ]]; then
|
||||
${CMD}
|
||||
else
|
||||
${CMD} > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# List all generated assembly tests
|
||||
echo "==========================================================="
|
||||
echo " Generated RISC-V assembly tests"
|
||||
echo " ----------------------------------------------------------"
|
||||
find $OUT/asm_tests -name "*.S" | sort -k11
|
2
vendor/google_riscv-dv/run.py
vendored
2
vendor/google_riscv-dv/run.py
vendored
|
@ -334,7 +334,7 @@ def setup_parser():
|
|||
parser.add_argument("--lsf_cmd", type=str, default="",
|
||||
help="LSF command. Run in local sequentially if lsf \
|
||||
command is not specified")
|
||||
parser.add_argument("--isa", type=str, default="rv64imc",
|
||||
parser.add_argument("--isa", type=str, default="rv64gc",
|
||||
help="RISC-V ISA subset")
|
||||
parser.add_argument("-m", "--mabi", type=str, default="lp64",
|
||||
help="mabi used for compilation, lp32 or lp64", dest="mabi")
|
||||
|
|
0
vendor/google_riscv-dv/scripts/__init__.py
vendored
0
vendor/google_riscv-dv/scripts/__init__.py
vendored
13
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
13
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
|
@ -43,8 +43,9 @@ except ImportError as e:
|
|||
Defines the test's success/failure values, one of which will be written to
|
||||
the chosen signature address to indicate the test's result.
|
||||
"""
|
||||
PASS_VAL = 1
|
||||
FAIL_VAL = 0
|
||||
TEST_RESULT = 1
|
||||
TEST_PASS = 0
|
||||
TEST_FAIL = 1
|
||||
|
||||
def get_csr_map(csr_file, xlen):
|
||||
"""
|
||||
|
@ -227,7 +228,9 @@ def gen_csr_test_fail(test_file, end_addr):
|
|||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_fail:\n")
|
||||
test_file.write(f"\tli x1, {FAIL_VAL}\n")
|
||||
test_file.write(f"\tli x1, {TEST_FAIL}\n")
|
||||
test_file.write(f"\tslli x1, x1, 8\n")
|
||||
test_file.write(f"\taddi x1, x1, {TEST_RESULT}\n")
|
||||
test_file.write(f"\tli x2, {end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_fail\n")
|
||||
|
@ -244,7 +247,9 @@ def gen_csr_test_pass(test_file, end_addr):
|
|||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_pass:\n")
|
||||
test_file.write(f"\tli x1, {PASS_VAL}\n")
|
||||
test_file.write(f"\tli x1, {TEST_PASS}\n")
|
||||
test_file.write(f"\tslli x1, x1, 8\n")
|
||||
test_file.write(f"\taddi x1, x1, {TEST_RESULT}\n")
|
||||
test_file.write(f"\tli x2, {end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_pass\n")
|
||||
|
|
2
vendor/google_riscv-dv/scripts/lib.py
vendored
2
vendor/google_riscv-dv/scripts/lib.py
vendored
|
@ -147,7 +147,7 @@ def process_regression_list(testlist, test, iterations, matched_list):
|
|||
yaml_data = read_yaml(testlist)
|
||||
for entry in yaml_data:
|
||||
if (entry['test'] == test) or (test == "all"):
|
||||
if iterations > 0:
|
||||
if (iterations > 0 and entry['iterations'] > 0):
|
||||
entry['iterations'] = iterations
|
||||
if entry['iterations'] > 0:
|
||||
logging.info("Found matched tests: %s, iterations:%0d" %
|
||||
|
|
|
@ -30,7 +30,7 @@ privileged_mode_t supported_privileged_mode[] = {USER_MODE, SUPERVISOR_MODE, MAC
|
|||
riscv_instr_name_t unsupported_instr[];
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C};
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A};
|
||||
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
|
170
vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv
vendored
Normal file
170
vendor/google_riscv-dv/src/riscv_amo_instr_lib.sv
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Base class for AMO instruction stream
|
||||
class riscv_amo_base_instr_stream extends riscv_directed_instr_stream;
|
||||
|
||||
rand int unsigned num_amo;
|
||||
rand int unsigned num_mixed_instr;
|
||||
rand int base;
|
||||
rand riscv_reg_t rs1_reg;
|
||||
riscv_reg_t reserved_rd[$];
|
||||
rand int unsigned data_page_id;
|
||||
|
||||
// User can specify a small group of available registers to generate various hazard condition
|
||||
rand riscv_reg_t avail_regs[];
|
||||
|
||||
`uvm_object_utils(riscv_amo_base_instr_stream)
|
||||
|
||||
constraint rs1_c {
|
||||
!(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
|
||||
}
|
||||
|
||||
constraint addr_range_c {
|
||||
data_page_id < max_data_page_id;
|
||||
base inside {[0 : max_load_store_offset-1]};
|
||||
}
|
||||
|
||||
constraint aligned_amo_c {
|
||||
if (XLEN == 32) {
|
||||
base % 4 == 0;
|
||||
} else {
|
||||
base % 8 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
instr_list.rand_mode(0);
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
gen_amo_instr();
|
||||
// rs1 cannot be modified by other instructions
|
||||
if(!(rs1_reg inside {reserved_rd})) begin
|
||||
reserved_rd.push_back(rs1_reg);
|
||||
end
|
||||
add_mixed_instr();
|
||||
add_rs1_init_la_instr();
|
||||
super.post_randomize();
|
||||
endfunction
|
||||
|
||||
// Use "la" instruction to initialize the base regiseter
|
||||
virtual function void add_rs1_init_la_instr();
|
||||
riscv_pseudo_instr la_instr;
|
||||
la_instr = riscv_pseudo_instr::type_id::create("la_instr");
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(la_instr,
|
||||
pseudo_instr_name == LA;
|
||||
rd == rs1_reg;,
|
||||
"Cannot randomize la_instr")
|
||||
if(access_u_mode_mem) begin
|
||||
la_instr.imm_str = $sformatf("data_page_%0d+%0d", data_page_id, base);
|
||||
end else begin
|
||||
la_instr.imm_str = $sformatf("kernel_data_page_%0d+%0d", data_page_id, base);
|
||||
end
|
||||
instr_list.push_front(la_instr);
|
||||
endfunction
|
||||
|
||||
// AMO instruction generation
|
||||
virtual function void gen_amo_instr();
|
||||
endfunction
|
||||
|
||||
// Insert some other instructions to mix with load/store instruction
|
||||
virtual function void add_mixed_instr();
|
||||
riscv_rand_instr rand_instr;
|
||||
for(int i = 0; i < num_mixed_instr; i ++) begin
|
||||
rand_instr = riscv_rand_instr::type_id::create("rand_instr");
|
||||
rand_instr.cfg = cfg;
|
||||
rand_instr.reserved_rd = reserved_rd;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(rand_instr,
|
||||
if(avail_regs.size() > 0) {
|
||||
rs1 inside {avail_regs};
|
||||
rd inside {avail_regs};
|
||||
}
|
||||
!(category inside {LOAD, STORE, BRANCH, JUMP});,
|
||||
"Cannot randomize instruction")
|
||||
insert_instr(rand_instr);
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
// A pair of LR/SC instruction
|
||||
class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
|
||||
|
||||
riscv_rand_instr lr_instr;
|
||||
riscv_rand_instr sc_instr;
|
||||
|
||||
constraint legal_c {
|
||||
num_amo == 1;
|
||||
num_mixed_instr inside {[0:15]};
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_lr_sc_instr_stream)
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
lr_instr = riscv_rand_instr::type_id::create("lr_instr");
|
||||
sc_instr = riscv_rand_instr::type_id::create("sc_instr");
|
||||
endfunction
|
||||
|
||||
virtual function void gen_amo_instr();
|
||||
lr_instr.cfg = cfg;
|
||||
sc_instr.cfg = cfg;
|
||||
lr_instr.disable_a_extension_c.constraint_mode(0);
|
||||
sc_instr.disable_a_extension_c.constraint_mode(0);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(lr_instr,
|
||||
rs1 == rs1_reg;
|
||||
rd != rs1_reg;
|
||||
instr_name inside {LR_W, LR_D};)
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(sc_instr,
|
||||
rs1 == rs1_reg;
|
||||
rd != rs1_reg;
|
||||
instr_name inside {SC_W, SC_D};)
|
||||
instr_list.push_front(lr_instr);
|
||||
instr_list.push_front(sc_instr);
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_amo_instr_stream extends riscv_amo_base_instr_stream;
|
||||
|
||||
riscv_rand_instr amo_instr[];
|
||||
|
||||
constraint reasonable_c {
|
||||
solve num_amo before num_mixed_instr;
|
||||
num_amo inside {[1:10]};
|
||||
num_mixed_instr inside {[0:2*num_amo]};
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_amo_instr_stream)
|
||||
`uvm_object_new
|
||||
|
||||
virtual function void gen_amo_instr();
|
||||
amo_instr = new[num_amo];
|
||||
foreach (amo_instr[i]) begin
|
||||
amo_instr[i] = riscv_rand_instr::type_id::create($sformatf("amo_instr_%0d", i));
|
||||
amo_instr[i].cfg = cfg;
|
||||
amo_instr[i].disable_a_extension_c.constraint_mode(0);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(amo_instr[i],
|
||||
rs1 == rs1_reg;
|
||||
rd != rs1_reg;
|
||||
category == AMO;)
|
||||
instr_list.push_front(amo_instr[i]);
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass
|
133
vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
vendored
133
vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
vendored
|
@ -70,6 +70,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
gen_program_header();
|
||||
// Initialize general purpose registers
|
||||
init_gpr();
|
||||
setup_misa();
|
||||
// Create all page tables
|
||||
create_page_table();
|
||||
// Setup privileged mode registers and enter target privileged mode
|
||||
|
@ -355,7 +356,6 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
instr_stream.push_back(str);
|
||||
// Init stack pointer to point to the end of the user stack
|
||||
str = {indent, "la sp, _user_stack_end"};
|
||||
setup_misa();
|
||||
instr_stream.push_back(str);
|
||||
core_is_initialized();
|
||||
// Copy the instruction from data section to instruction section
|
||||
|
@ -384,6 +384,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
RV32C, RV64C, RV128C : misa[MISA_EXT_C] = 1'b1;
|
||||
RV32I, RV64I, RV128I : misa[MISA_EXT_I] = 1'b1;
|
||||
RV32M, RV64M : misa[MISA_EXT_M] = 1'b1;
|
||||
RV32A, RV64A : misa[MISA_EXT_A] = 1'b1;
|
||||
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported", supported_isa[i].name()))
|
||||
endcase
|
||||
end
|
||||
|
@ -400,12 +401,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
if (cfg.require_signature_addr) begin
|
||||
if (cfg.signature_addr != 32'hdead_beef) begin
|
||||
string str;
|
||||
str = {indent, $sformatf("li x5, 0x%0h", cfg.signature_addr)};
|
||||
instr_stream.push_back(str);
|
||||
str = {indent, $sformatf("li x6, 0x%0h", riscv_instr_pkg::CORE_INITIALIZATION_DONE)};
|
||||
instr_stream.push_back(str);
|
||||
str = {indent, "sw x6, 0(x5)"};
|
||||
instr_stream.push_back(str);
|
||||
gen_signature_handshake(instr_stream, CORE_STATUS, INITIALIZED);
|
||||
end else begin
|
||||
`uvm_fatal(`gfn, "The signature_addr is not properly configured!")
|
||||
end
|
||||
|
@ -627,10 +623,11 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// Generate page table fault handling routine
|
||||
// Page table fault is always handled in machine mode, as virtual address translation may be
|
||||
// broken when page fault happens.
|
||||
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
|
||||
if(page_table_list != null) begin
|
||||
page_table_list.gen_page_fault_handling_routine(instr);
|
||||
end else begin
|
||||
instr = {"nop"};
|
||||
instr.push_back("nop");
|
||||
end
|
||||
gen_section("pt_fault_handler", instr);
|
||||
endfunction
|
||||
|
@ -670,7 +667,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
tvec_name = tvec.name();
|
||||
gen_section($sformatf("%0s_handler", tvec_name.tolower()), instr);
|
||||
// Exception handler
|
||||
instr = {"",
|
||||
instr = {};
|
||||
if (cfg.mtvec_mode == VECTORED) begin
|
||||
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, instr);
|
||||
end
|
||||
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
|
||||
instr = {instr,
|
||||
// The trap is caused by an exception, read back xCAUSE, xEPC to see if these
|
||||
// CSR values are set properly. The checking is done by comparing against the log
|
||||
// generated by ISA simulator (spike).
|
||||
|
@ -725,12 +727,13 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
$sformatf("j %0smode_exception_handler", mode)};
|
||||
// Redirect the interrupt to the corresponding interrupt handler
|
||||
for (int i = 1; i < 16; i++) begin
|
||||
instr.push_back($sformatf("j intr_vector_%0d", i));
|
||||
instr.push_back($sformatf("j %0smode_intr_vector_%0d", mode, i));
|
||||
end
|
||||
instr = {instr, ".option rvc;"};
|
||||
for (int i = 1; i < 16; i++) begin
|
||||
string intr_handler[$];
|
||||
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, intr_handler);
|
||||
gen_signature_handshake(intr_handler, CORE_STATUS, HANDLING_IRQ);
|
||||
intr_handler = {intr_handler,
|
||||
$sformatf("csrr a1, 0x%0x # %0s", cause, cause.name()),
|
||||
// Terminate the test if xCause[31] != 0 (indicating exception)
|
||||
|
@ -739,7 +742,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// Jump to commmon interrupt handling routine
|
||||
$sformatf("j %0smode_intr_handler", mode),
|
||||
"1: j test_done"};
|
||||
gen_section($sformatf("intr_vector_%0d", i), intr_handler);
|
||||
gen_section($sformatf("%0smode_intr_vector_%0d", mode, i), intr_handler);
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
@ -765,10 +768,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// TODO: Support random operations in debug mode
|
||||
// TODO: Support ebreak exception delegation
|
||||
virtual function void gen_ebreak_handler();
|
||||
string instr[$] = {
|
||||
"csrr x31, mepc",
|
||||
"addi x31, x31, 4",
|
||||
"csrw mepc, x31"
|
||||
string instr[$];
|
||||
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
|
||||
instr = {instr,
|
||||
"csrr x31, mepc",
|
||||
"addi x31, x31, 4",
|
||||
"csrw mepc, x31"
|
||||
};
|
||||
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, instr);
|
||||
instr.push_back("mret");
|
||||
|
@ -782,10 +787,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// 4 and resumes execution. The way that the illegal instruction is injected guarantees that
|
||||
// PC + 4 is a valid instruction boundary.
|
||||
virtual function void gen_illegal_instr_handler();
|
||||
string instr[$] = {
|
||||
"csrr x31, mepc",
|
||||
"addi x31, x31, 4",
|
||||
"csrw mepc, x31"
|
||||
string instr[$];
|
||||
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
|
||||
instr = {instr,
|
||||
"csrr x31, mepc",
|
||||
"addi x31, x31, 4",
|
||||
"csrw mepc, x31"
|
||||
};
|
||||
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, instr);
|
||||
instr.push_back("mret");
|
||||
|
@ -929,6 +936,88 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
`uvm_info(get_full_name(), $sformatf("%0s is generated", test_name), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
// Helper function to generate the proper sequence of handshake instructions
|
||||
// to signal the testbench (see riscv_signature_pkg.sv)
|
||||
function void gen_signature_handshake(ref string instr[$],
|
||||
input signature_type_t signature_type,
|
||||
core_status_t core_status = INITIALIZED,
|
||||
test_result_t test_result = TEST_FAIL,
|
||||
privileged_reg_t csr = MSCRATCH);
|
||||
if (cfg.require_signature_addr) begin
|
||||
string str;
|
||||
str = $sformatf("li x%0d, 0x%0h", cfg.signature_addr_reg, cfg.signature_addr);
|
||||
instr.push_back(str);
|
||||
case (signature_type)
|
||||
// A single data word is written to the signature address.
|
||||
// Bits [7:0] contain the signature_type of CORE_STATUS, and the upper
|
||||
// XLEN-8 bits contain the core_status_t data.
|
||||
CORE_STATUS: begin
|
||||
str = $sformatf("li x%0d, 0x%0h", cfg.signature_data_reg, core_status);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("slli x%0d, x%0d, 8", cfg.signature_data_reg, cfg.signature_data_reg);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("addi x%0d, x%0d, 0x%0h", cfg.signature_data_reg,
|
||||
cfg.signature_data_reg, signature_type);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("sw x%0d, 0(x%0d)", cfg.signature_data_reg, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
end
|
||||
// A single data word is written to the signature address.
|
||||
// Bits [7:0] contain the signature_type of TEST_RESULT, and the upper
|
||||
// XLEN-8 bits contain the test_result_t data.
|
||||
TEST_RESULT: begin
|
||||
str = $sformatf("li x%0d, 0x%0h", cfg.signature_data_reg, test_result);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("slli x%0d, x%0d, 8", cfg.signature_data_reg, cfg.signature_data_reg);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("addi x%0d, x%0d, 0x%0h", cfg.signature_data_reg,
|
||||
cfg.signature_data_reg, signature_type);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("sw x%0d, 0(x%0d)", cfg.signature_data_reg, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
end
|
||||
// The first write to the signature address contains just the
|
||||
// signature_type of WRITE_GPR.
|
||||
// It is followed by 32 consecutive writes to the signature address,
|
||||
// each writing the data contained in one GPR, starting from x0 as the
|
||||
// first write, and ending with x31 as the 32nd write.
|
||||
WRITE_GPR: begin
|
||||
str = $sformatf("li x%0d, 0x%0h", cfg.signature_data_reg, signature_type);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("sw x%0d, 0(x%0d)", cfg.signature_data_reg, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
for(int i = 0; i < 32; i++) begin
|
||||
str = $sformatf("sw x%0x, 0(x%0d)", i, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
end
|
||||
end
|
||||
// The first write to the signature address contains the
|
||||
// signature_type of WRITE_CSR in bits [7:0], and the CSR address in
|
||||
// the upper XLEN-8 bits.
|
||||
// It is followed by a second write to the signature address,
|
||||
// containing the data stored in the specified CSR.
|
||||
WRITE_CSR: begin
|
||||
str = $sformatf("li x%0d, 0x%0h", cfg.signature_data_reg, csr);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("slli x%0d, x%0d, 8", cfg.signature_data_reg, cfg.signature_data_reg);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("addi x%0d, x%0d, 0x%0h", cfg.signature_data_reg,
|
||||
cfg.signature_data_reg, signature_type);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("sw x%0d, 0(x%0d)", cfg.signature_data_reg, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("csrr x%0d, 0x%0h", cfg.signature_data_reg, csr);
|
||||
instr.push_back(str);
|
||||
str = $sformatf("sw x%0d, 0(x%0d)", cfg.signature_data_reg, cfg.signature_addr_reg);
|
||||
instr.push_back(str);
|
||||
end
|
||||
default: begin
|
||||
`uvm_fatal(`gfn, "signature_type is not defined")
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Inject directed instruction stream
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
@ -1028,6 +1117,10 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
string dret;
|
||||
string debug_sub_program_name[$] = {};
|
||||
if (riscv_instr_pkg::support_debug_mode) begin
|
||||
// Signal that the core entered the debug rom regardless of whether the
|
||||
// main debug rom program has been generated
|
||||
gen_signature_handshake(instr, CORE_STATUS, IN_DEBUG_MODE);
|
||||
format_section(instr);
|
||||
// The main debug rom
|
||||
if (cfg.gen_debug_section) begin
|
||||
gen_sub_program(debug_sub_program, debug_sub_program_name,
|
||||
|
@ -1048,7 +1141,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
format_section(push_gpr);
|
||||
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, pop_gpr);
|
||||
format_section(pop_gpr);
|
||||
instr = {push_gpr, debug_program.instr_string_list, pop_gpr};
|
||||
instr = {push_gpr, instr, debug_program.instr_string_list, pop_gpr};
|
||||
insert_sub_program(debug_sub_program, instr_stream);
|
||||
end
|
||||
dret = {format_string(" ", LABEL_STR_LEN), "dret"};
|
||||
|
|
55
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
55
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
|
@ -30,6 +30,8 @@ class riscv_instr_base extends uvm_object;
|
|||
rand imm_t imm_type;
|
||||
rand bit [4:0] imm_len;
|
||||
rand bit is_pseudo_instr;
|
||||
rand bit aq;
|
||||
rand bit rl;
|
||||
bit is_branch_target;
|
||||
bit has_label = 1'b1;
|
||||
bit atomic = 0;
|
||||
|
@ -106,6 +108,10 @@ class riscv_instr_base extends uvm_object;
|
|||
}
|
||||
}
|
||||
|
||||
constraint aq_rl_c {
|
||||
aq && rl == 0;
|
||||
}
|
||||
|
||||
// Avoid generating HINT or illegal instruction by default as it's not supported by the compiler
|
||||
constraint no_hint_illegal_instr_c {
|
||||
if (instr_name inside {C_ADDI, C_ADDIW, C_LI, C_LUI, C_SLLI, C_SLLI64,
|
||||
|
@ -366,6 +372,32 @@ class riscv_instr_base extends uvm_object;
|
|||
`add_instr(C_FLDSP, CI_FORMAT, LOAD, RV32DC, UIMM)
|
||||
`add_instr(C_FSDSP, CSS_FORMAT, STORE, RV32DC, UIMM)
|
||||
|
||||
// RV32A
|
||||
`add_instr(LR_W, R_FORMAT, LOAD, RV32A)
|
||||
`add_instr(SC_W, R_FORMAT, STORE, RV32A)
|
||||
`add_instr(AMOSWAP_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOADD_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOAND_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOOR_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOXOR_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMIN_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMAX_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMINU_W, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMAXU_W, R_FORMAT, AMO, RV32A)
|
||||
|
||||
// RV64A
|
||||
`add_instr(LR_D, R_FORMAT, LOAD, RV32A)
|
||||
`add_instr(SC_D, R_FORMAT, STORE, RV32A)
|
||||
`add_instr(AMOSWAP_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOADD_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOAND_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOOR_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOXOR_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMIN_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMAX_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMINU_D, R_FORMAT, AMO, RV32A)
|
||||
`add_instr(AMOMAXU_D, R_FORMAT, AMO, RV32A)
|
||||
|
||||
// Supervisor Instructions
|
||||
`add_instr(SFENCE_VMA, R_FORMAT,SYNCH,RV32I)
|
||||
|
||||
|
@ -408,7 +440,7 @@ class riscv_instr_base extends uvm_object;
|
|||
virtual function string convert2asm(string prefix = "");
|
||||
string asm_str;
|
||||
asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
|
||||
if(category != SYSTEM) begin
|
||||
if((category != SYSTEM) && !(group inside {RV32A, RV64A})) begin
|
||||
case(format)
|
||||
J_FORMAT, U_FORMAT : // instr rd,imm
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
|
||||
|
@ -431,12 +463,13 @@ class riscv_instr_base extends uvm_object;
|
|||
else
|
||||
asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rs1.name(), rs2.name(), get_imm());
|
||||
R_FORMAT: // instr rd,rs1,rs2
|
||||
if(category == CSR)
|
||||
if(category == CSR) begin
|
||||
asm_str = $sformatf("%0s%0s, 0x%0x, %0s", asm_str, rd.name(), csr, rs1.name());
|
||||
else if(instr_name == SFENCE_VMA)
|
||||
end else if(instr_name == SFENCE_VMA) begin
|
||||
asm_str = "sfence.vma x0, x0"; // TODO: Support all possible sfence
|
||||
else
|
||||
end else begin
|
||||
asm_str = $sformatf("%0s%0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
end
|
||||
CI_FORMAT, CIW_FORMAT:
|
||||
if(instr_name == C_NOP)
|
||||
asm_str = "c.nop";
|
||||
|
@ -458,6 +491,12 @@ class riscv_instr_base extends uvm_object;
|
|||
CJ_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s", asm_str, get_imm());
|
||||
endcase
|
||||
end else if (group inside {RV32A, RV64A}) begin
|
||||
if (instr_name inside {LR_W, LR_D}) begin
|
||||
asm_str = $sformatf("%0s %0s, (%0s)", asm_str, rd.name(), rs1.name());
|
||||
end else begin
|
||||
asm_str = $sformatf("%0s %0s, %0s, (%0s)", asm_str, rd.name(), rs2.name(), rs1.name());
|
||||
end
|
||||
end else begin
|
||||
// For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary
|
||||
// This is needed to resume execution from epc+4 after ebreak handling
|
||||
|
@ -835,6 +874,14 @@ class riscv_instr_base extends uvm_object;
|
|||
get_instr_name = instr_name.name();
|
||||
if(get_instr_name.substr(0, 1) == "C_") begin
|
||||
get_instr_name = {"c.", get_instr_name.substr(2, get_instr_name.len() - 1)};
|
||||
end else if (group == RV32A) begin
|
||||
get_instr_name = {get_instr_name.substr(0, get_instr_name.len() - 3), ".w"};
|
||||
get_instr_name = aq ? {get_instr_name, ".aq"} :
|
||||
rl ? {get_instr_name, ".rl"} : get_instr_name;
|
||||
end else if (group == RV64A) begin
|
||||
get_instr_name = {get_instr_name.substr(0, get_instr_name.len() - 3), ".d"};
|
||||
get_instr_name = aq ? {get_instr_name, ".aq"} :
|
||||
rl ? {get_instr_name, ".rl"} : get_instr_name;
|
||||
end
|
||||
return get_instr_name;
|
||||
endfunction
|
||||
|
|
|
@ -113,6 +113,8 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
// the testbench - testbench will take action based on the value written
|
||||
int signature_addr = 32'hdead_beef;
|
||||
bit require_signature_addr = 1'b0;
|
||||
rand riscv_reg_t signature_addr_reg;
|
||||
rand riscv_reg_t signature_data_reg;
|
||||
bit gen_debug_section = 1'b0;
|
||||
// Enable a full or empty debug_rom section.
|
||||
// Full debug_rom will contain random instruction streams.
|
||||
|
@ -245,6 +247,9 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
foreach(loop_regs[i]) {
|
||||
!(loop_regs[i] inside {default_reserved_regs});
|
||||
}
|
||||
!(signature_addr_reg inside {default_reserved_regs, loop_regs});
|
||||
!(signature_data_reg inside {default_reserved_regs, loop_regs});
|
||||
signature_addr_reg != signature_data_reg;
|
||||
}
|
||||
|
||||
constraint legal_loop_regs_c {
|
||||
|
|
32
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
32
vendor/google_riscv-dv/src/riscv_instr_pkg.sv
vendored
|
@ -17,6 +17,7 @@
|
|||
package riscv_instr_pkg;
|
||||
|
||||
import uvm_pkg::*;
|
||||
import riscv_signature_pkg::*;
|
||||
|
||||
`include "uvm_macros.svh"
|
||||
`include "dv_defines.svh"
|
||||
|
@ -24,8 +25,6 @@ package riscv_instr_pkg;
|
|||
|
||||
`define include_file(f) `include `"f`"
|
||||
|
||||
parameter CORE_INITIALIZATION_DONE = 2;
|
||||
|
||||
typedef enum bit [3:0] {
|
||||
BARE = 4'b0000,
|
||||
SV32 = 4'b0001,
|
||||
|
@ -237,6 +236,30 @@ package riscv_instr_pkg;
|
|||
C_FSD,
|
||||
C_FLDSP,
|
||||
C_FSDSP,
|
||||
// RV32A
|
||||
LR_W,
|
||||
SC_W,
|
||||
AMOSWAP_W,
|
||||
AMOADD_W,
|
||||
AMOAND_W,
|
||||
AMOOR_W,
|
||||
AMOXOR_W,
|
||||
AMOMIN_W,
|
||||
AMOMAX_W,
|
||||
AMOMINU_W,
|
||||
AMOMAXU_W,
|
||||
// RV64A
|
||||
LR_D,
|
||||
SC_D,
|
||||
AMOSWAP_D,
|
||||
AMOADD_D,
|
||||
AMOAND_D,
|
||||
AMOOR_D,
|
||||
AMOXOR_D,
|
||||
AMOMIN_D,
|
||||
AMOMAX_D,
|
||||
AMOMINU_D,
|
||||
AMOMAXU_D,
|
||||
// Supervisor instruction
|
||||
MRET,
|
||||
URET,
|
||||
|
@ -317,7 +340,8 @@ package riscv_instr_pkg;
|
|||
CSR,
|
||||
CHANGELEVEL,
|
||||
TRAP,
|
||||
INTERRUPT
|
||||
INTERRUPT,
|
||||
AMO
|
||||
} riscv_instr_cateogry_t;
|
||||
|
||||
typedef bit [11:0] riscv_csr_t;
|
||||
|
@ -776,6 +800,7 @@ package riscv_instr_pkg;
|
|||
end
|
||||
endfunction
|
||||
|
||||
|
||||
`include "riscv_instr_gen_config.sv"
|
||||
`include "riscv_illegal_instr.sv"
|
||||
`include "riscv_reg.sv"
|
||||
|
@ -793,6 +818,7 @@ package riscv_instr_pkg;
|
|||
`include "riscv_loop_instr.sv"
|
||||
`include "riscv_directed_instr_lib.sv"
|
||||
`include "riscv_load_store_instr_lib.sv"
|
||||
`include "riscv_amo_instr_lib.sv"
|
||||
`include "riscv_instr_sequence.sv"
|
||||
`include "riscv_asm_program_gen.sv"
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
|
|||
// 2. For normal test, a page table fault typically means the program is accessing a large
|
||||
// virtual address which currently not mapped a valid physical address. Need to do a
|
||||
// memcpy to move data from lower physical address to the place the virtual address map to.
|
||||
virtual function void gen_page_fault_handling_routine(output string instr[$]);
|
||||
virtual function void gen_page_fault_handling_routine(ref string instr[$]);
|
||||
int unsigned level;
|
||||
string load_store_unit;
|
||||
bit[XLEN-1:0] bit_mask = '1;
|
||||
|
|
13
vendor/google_riscv-dv/src/riscv_rand_instr.sv
vendored
13
vendor/google_riscv-dv/src/riscv_rand_instr.sv
vendored
|
@ -23,12 +23,23 @@ class riscv_rand_instr extends riscv_instr_base;
|
|||
|
||||
`uvm_object_utils(riscv_rand_instr)
|
||||
|
||||
constraint category_c {
|
||||
soft category inside {LOAD, STORE, SHIFT, ARITHMETIC, LOGICAL,
|
||||
BRANCH, COMPARE, CSR, SYSTEM, SYNCH};
|
||||
}
|
||||
|
||||
// Atomic extension instructions are default disabled
|
||||
// AMO instruction generation is handled by riscv_amo_instr_lib.sv
|
||||
constraint disable_a_extension_c {
|
||||
group != RV32A;
|
||||
group != RV64A;
|
||||
}
|
||||
|
||||
constraint instr_c {
|
||||
solve instr_name before imm;
|
||||
solve instr_name before rs1;
|
||||
solve instr_name before rs2;
|
||||
!(instr_name inside {riscv_instr_pkg::unsupported_instr});
|
||||
category inside {LOAD, STORE, SHIFT, ARITHMETIC, LOGICAL, BRANCH, COMPARE, CSR, SYSTEM, SYNCH};
|
||||
group inside {riscv_instr_pkg::supported_isa};
|
||||
// Avoid using any special purpose register as rd, those registers are reserved for
|
||||
// special instructions
|
||||
|
|
54
vendor/google_riscv-dv/src/riscv_signature_pkg.sv
vendored
Normal file
54
vendor/google_riscv-dv/src/riscv_signature_pkg.sv
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package riscv_signature_pkg;
|
||||
|
||||
// Will be the lowest 8 bits of the data word
|
||||
typedef enum bit[7:0] {
|
||||
// Information sent to the core relating its current status.
|
||||
// Bits [12:8] of the data word will be the core_status_t value
|
||||
// corresponding to the current core status.
|
||||
CORE_STATUS,
|
||||
// Information sent to the core conveying the uvm simulation result.
|
||||
// Bit [8] of the data word will be the test_result_t value.
|
||||
TEST_RESULT,
|
||||
// Sent to the core to indicate a dump of GPRs to testbench.
|
||||
// Will be followed by 32 writes of registers x0-x32.
|
||||
WRITE_GPR,
|
||||
// Sent to the core to indicate a write of a CSR's data.
|
||||
// Bits [19:8] of the data word will be the CSR address.
|
||||
// Will be followed by a second write of the actual data from the CSR.
|
||||
WRITE_CSR
|
||||
} signature_type_t;
|
||||
|
||||
typedef enum bit[4:0] {
|
||||
INITIALIZED,
|
||||
IN_DEBUG_MODE,
|
||||
IN_MACHINE_MODE,
|
||||
IN_HYPERVISOR_MODE,
|
||||
IN_SUPERVISOR_MODE,
|
||||
IN_USER_MODE,
|
||||
HANDLING_IRQ,
|
||||
HANDLING_EXCEPTION
|
||||
} core_status_t;
|
||||
|
||||
typedef enum bit {
|
||||
TEST_PASS,
|
||||
TEST_FAIL
|
||||
} test_result_t;
|
||||
|
||||
|
||||
endpackage
|
253
vendor/google_riscv-dv/test/riscv_instr_test_lib.sv
vendored
253
vendor/google_riscv-dv/test/riscv_instr_test_lib.sv
vendored
|
@ -14,120 +14,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//================================================================================================
|
||||
// RISC-V Test Library
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// riscv_arithmetic_basic_test :
|
||||
// - Simple arithmetic instruction test, [machine mode]
|
||||
//
|
||||
// riscv_machine_mode_rand_test :
|
||||
// - Random instruction test, include sub-programs, branch, load/store [machine mode]
|
||||
//
|
||||
// riscv_privileged_mode_rand_test :
|
||||
// - Similar to riscv_machine_mode_rand_test, run in supervisor mode or user mode if supported
|
||||
//
|
||||
// riscv_rand_instr_test :
|
||||
// - A full random test, with a mix of directed instruction stream
|
||||
//
|
||||
// riscv_rand_jump_test :
|
||||
// - Random jump among a large number of sub programs
|
||||
//
|
||||
// riscv_mmu_stress_test:
|
||||
// - A mixed of intense load/store instructions
|
||||
//
|
||||
// riscv_page_table_exception_test:
|
||||
// - Running test in privileged mode with page table exceptions
|
||||
//
|
||||
// riscv_no_fence_test
|
||||
// - Random instruction with fence disabled, allow more intense instruction execution
|
||||
//
|
||||
// riscv_sfence_exception_test
|
||||
// - Random instruction with sfence exception. sfence.vma could be excuted in non-supervisor mode
|
||||
// or mstatus.tvm is set.
|
||||
//
|
||||
// riscv_illegal_instr_test:
|
||||
// - Random instruction mixed with illegal instructions
|
||||
//
|
||||
// riscv_hint_instr_test:
|
||||
// - Random instruction mixed with HINT instructions
|
||||
//
|
||||
// riscv_ebreak_test:
|
||||
// - Randomly inject ebreak instruction, verify core can be halted and resumed properly
|
||||
//
|
||||
// riscv_wfi_test:
|
||||
// - Randomly inject wfi instruction, verify core can be halted and resumed properly(by interrupt)
|
||||
//
|
||||
// riscv_csr_test:
|
||||
// - Random instructions with CSR intruction enabled
|
||||
//
|
||||
// riscv_illegal_csr_test:
|
||||
// - Accessing non-existence CSR or CSR with the wrong privileged mode
|
||||
//
|
||||
//================================================================================================
|
||||
|
||||
class riscv_arithmetic_basic_test extends riscv_instr_base_test;
|
||||
|
||||
`uvm_component_utils(riscv_arithmetic_basic_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.instr_cnt = 10000;
|
||||
cfg.num_of_sub_program = 0;
|
||||
cfg.no_fence = 1;
|
||||
cfg.no_data_page = 1'b1;
|
||||
cfg.no_branch_jump = 1'b1;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(cfg,
|
||||
init_privileged_mode == MACHINE_MODE;
|
||||
max_nested_loop == 0;)
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
|
||||
cfg.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_machine_mode_rand_test extends riscv_instr_base_test;
|
||||
|
||||
`uvm_component_utils(riscv_machine_mode_rand_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.instr_cnt = 10000;
|
||||
cfg.num_of_sub_program = 5;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(cfg,
|
||||
init_privileged_mode == MACHINE_MODE;
|
||||
max_nested_loop == 0;)
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
|
||||
cfg.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
virtual function void apply_directed_instr();
|
||||
// Add load/store instruction stream
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_rand_instr_stream", 10);
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_privileged_mode_rand_test extends riscv_instr_base_test;
|
||||
|
||||
`uvm_component_utils(riscv_privileged_mode_rand_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.instr_cnt = 10000;
|
||||
cfg.num_of_sub_program = 5;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(cfg,
|
||||
init_privileged_mode != MACHINE_MODE;
|
||||
max_nested_loop == 0;)
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
|
||||
cfg.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
virtual function void apply_directed_instr();
|
||||
// Add load/store instruction stream
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_rand_instr_stream", 10);
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_rand_instr_test extends riscv_instr_base_test;
|
||||
|
||||
|
@ -154,142 +40,3 @@ class riscv_rand_instr_test extends riscv_instr_base_test;
|
|||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_rand_jump_test extends riscv_instr_base_test;
|
||||
|
||||
`uvm_component_utils(riscv_rand_jump_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.instr_cnt = 20000;
|
||||
cfg.num_of_sub_program = 20;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(cfg,
|
||||
max_nested_loop == 1;)
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
|
||||
cfg.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
virtual function void apply_directed_instr();
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_rand_instr_stream", 10);
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_mmu_stress_test extends riscv_instr_base_test;
|
||||
|
||||
`uvm_component_utils(riscv_mmu_stress_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.instr_cnt = 500;
|
||||
cfg.num_of_sub_program = 0;
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(cfg,
|
||||
max_nested_loop == 0;)
|
||||
`uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s",
|
||||
cfg.sprint()), UVM_LOW)
|
||||
endfunction
|
||||
|
||||
virtual function void apply_directed_instr();
|
||||
// Mix below directed instructino streams with the random instructions
|
||||
asm_gen.add_directed_instr_stream("riscv_cache_line_stress_instr_stream", 80);
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_hazard_instr_stream", 80);
|
||||
asm_gen.add_directed_instr_stream("riscv_multi_page_load_store_instr_stream", 80);
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_page_table_exception_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_page_table_exception_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.enable_page_table_exception = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_no_fence_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_no_fence_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.no_fence = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_sfence_exception_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_sfence_exception_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.allow_sfence_exception = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_illegal_instr_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_illegal_instr_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.enable_illegal_instruction = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_hint_instr_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_hint_instr_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.enable_hint_instruction = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_ebreak_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_ebreak_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.no_ebreak = 1'b0;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_wfi_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_wfi_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.no_wfi = 1'b0;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
class riscv_illegal_csr_test extends riscv_rand_instr_test;
|
||||
|
||||
`uvm_component_utils(riscv_illegal_csr_test)
|
||||
`uvm_component_new
|
||||
|
||||
virtual function void randomize_cfg();
|
||||
cfg.enable_illegal_csr_instruction = 1'b1;
|
||||
super.randomize_cfg();
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
31
vendor/google_riscv-dv/testlist
vendored
31
vendor/google_riscv-dv/testlist
vendored
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//====================================================================
|
||||
// Test name : iterations : options
|
||||
//--------------------------------------------------------------------
|
||||
riscv_arithmetic_basic_test : 2 :
|
||||
riscv_machine_mode_rand_test : 2 :
|
||||
riscv_privileged_mode_rand_test : 2 :
|
||||
riscv_rand_instr_test : 2 :
|
||||
riscv_rand_jump_test : 2 :
|
||||
riscv_mmu_stress_test : 2 :
|
||||
riscv_page_table_exception_test : 2 :
|
||||
riscv_no_fence_test : 2 :
|
||||
riscv_sfence_exception_test : 2 :
|
||||
riscv_illegal_instr_test : 2 :
|
||||
riscv_hint_instr_test : 2 :
|
||||
riscv_ebreak_test : 2 :
|
||||
riscv_wfi_test : 2 :
|
||||
//--------------------------------------------------------------------
|
33
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
33
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
|
@ -185,7 +185,6 @@
|
|||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+require_signature_addr=1
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
|
@ -195,34 +194,14 @@
|
|||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
- test: riscv_fast_interrupt_test
|
||||
description: >
|
||||
WFI(wait for interrupt) instruction test. If WFI is supported, processor
|
||||
should halt execution upon decoding WFI instruction and resume execution
|
||||
by interrupt. Otherwise WFI should be executed as NOP instruction.
|
||||
Interrupt handling routine is skipped to allow instruction strace comparison
|
||||
with ISS which is not interrupted during execution.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+require_signature_addr=1
|
||||
+skip_trap_handling=1
|
||||
+no_wfi=0
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+require_signature_addr=1
|
||||
+enable_irq_seq=1
|
||||
|
||||
- test: riscv_full_interrupt_test
|
||||
description: >
|
||||
Random instruction test with complete interrupt handling
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+require_signature_addr=1
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+require_signature_addr=1
|
||||
+enable_irq_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
@ -252,3 +231,15 @@
|
|||
+directed_instr_3=riscv_multi_page_load_store_instr_stream,20
|
||||
+enable_unaligned_load_store=1
|
||||
rtl_test: core_ibex_base_test
|
||||
|
||||
- test: riscv_amo_test
|
||||
description: >
|
||||
RISC-V atomic instruction extension test
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_lr_sc_instr_stream,10
|
||||
+directed_instr_1=riscv_amo_instr_stream,10
|
||||
rtl_test: core_base_test
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue