mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 22:07:43 -04:00
Update google_riscv-dv to google/riscv-dv@46ec4bc (#417)
Update code from upstream repository https://github.com/google/riscv- dv to revision 46ec4bc48bc1eebc5a2bcd48fe4ce4c77105fead * Incorrect deletion (google/riscv-dv#249) (eroom) * Updated OVPsim log processing for coverage (google/riscv-dv#248) (eroom) * Improve illegal/hint test coverage (google/riscv-dv#247) (taoliug) * Coverage model fixes (google/riscv-dv#246) (taoliug) * Add back-to-back jump instruction test (google/riscv-dv#244) (taoliug) * Functional coverage improvement (google/riscv-dv#243) (taoliug) * Functional coverage improvement (google/riscv-dv#242) (taoliug) * Support c.jr,c.jalr, fix coverage sampling issues (google/riscv- dv#241) (taoliug) * allow select a random GPR for JALR op (google/riscv-dv#240) (taoliug) * Fix coverage definition/sampling issue (google/riscv-dv#239) (taoliug) * Testlist clean up, add RV32I target (google/riscv-dv#238) (taoliug) * Consolidate the coverage collection script (google/riscv-dv#234) (taoliug) * Fixed default values, and trailing blank lines (google/riscv-dv#233) (eroom) * Refine README structure (google/riscv-dv#231) (taoliug) * Add pre-defined target: RV32IMC, RV64IMC (google/riscv-dv#230) (taoliug)
This commit is contained in:
parent
023b7b6856
commit
c89e431937
34 changed files with 2113 additions and 666 deletions
4
vendor/google_riscv-dv/.gitignore
vendored
4
vendor/google_riscv-dv/.gitignore
vendored
|
@ -3,3 +3,7 @@
|
|||
out_*/
|
||||
work/
|
||||
*.pyc
|
||||
/.cproject
|
||||
/.project
|
||||
/outdir/
|
||||
ucli.key
|
||||
|
|
274
vendor/google_riscv-dv/README.md
vendored
274
vendor/google_riscv-dv/README.md
vendored
|
@ -41,8 +41,40 @@ setup script, or run only one of the below commands:
|
|||
2) pip install bitstring
|
||||
```
|
||||
|
||||
### Running the generator
|
||||
|
||||
### Setup RISCV-GCC compiler toolchain
|
||||
|
||||
- Install [riscv-gcc](https://github.com/riscv/riscv-gcc) toolchain
|
||||
- Set environment variable RISCV_GCC to the RISC-V gcc executable
|
||||
executable. (example: <install_dir>/bin/riscv32-unknown-elf-gcc)
|
||||
- Set environment variable RISCV_OBJCOPY to RISC-v objcopy executable
|
||||
executable. (example: <install_dir>/bin/riscv32-unknown-elf-objcopy)
|
||||
|
||||
```
|
||||
// Sample .bashrc setup
|
||||
export RISCV_TOOLCHAIN=<riscv_gcc_install_path>
|
||||
export RISCV_GCC="$RISCV_TOOLCHAIN/bin/riscv32-unknown-elf-gcc"
|
||||
export RISCV_OBJCOPY="$RISCV_TOOLCHAIN/bin/riscv32-unknown-elf-objcopy"
|
||||
export SPIKE_PATH=$RISCV_TOOLCHAIN/bin
|
||||
```
|
||||
|
||||
### Setup ISS (instruction set simulator)
|
||||
|
||||
Currently three ISS are supported, the default ISS is spike. You can install any
|
||||
one of below to run ISS simulation.
|
||||
|
||||
- [spike](https://github.com/riscv/riscv-isa-sim#) setup
|
||||
- Follow the [steps](https://github.com/riscv/riscv-isa-sim#build-steps) to build spike
|
||||
- Install spike with "--enable-commitlog"
|
||||
- Set environment variable SPIKE_PATH to the directory of the spike binary
|
||||
- [riscv-ovpsim](https://github.com/riscv/riscv-ovpsim) setup
|
||||
- Download the riscv-ovpsim binary
|
||||
- Set environment variable OVPSIM_PATH to the directory of the ovpsim binary
|
||||
- [sail-riscv](https://github.com/rems-project/sail-riscv) setup
|
||||
- Follow the [steps](https://github.com/rems-project/sail-riscv/blob/master/README.md) to install sail-riscv
|
||||
- Set environment variable SAIL_RISCV to the sail-riscv binary
|
||||
|
||||
## Running the generator
|
||||
|
||||
A simple script "run.py" is provided for you to run a single test or a regression.
|
||||
|
||||
|
@ -102,25 +134,109 @@ python3 run.py --test riscv_arithmetic_basic_test --co
|
|||
....
|
||||
```
|
||||
|
||||
### Privileged CSR Test Generation
|
||||
### Run ISS simulation
|
||||
|
||||
The CSR generation script is located at
|
||||
[scripts/gen_csr_test.py](https://github.com/google/riscv-dv/blob/master/scripts/gen_csr_test.py).
|
||||
The CSR test code that this script generates will execute every CSR instruction
|
||||
on every processor implemented CSR, writing values to the CSR and then using a
|
||||
prediction function to calculate a reference value that will be written into
|
||||
another GPR. The reference value will then be compared to the value actually
|
||||
stored in the CSR to determine whether to jump to the failure condition or
|
||||
continue executing, allowing it to be completely self checking. This script has
|
||||
been integrated with run.py. If you want to run it separately, you can get the
|
||||
command reference with --help:
|
||||
You can use -iss to run with different ISS.
|
||||
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --help
|
||||
// Run ISS with spike
|
||||
python3 run.py --test riscv_arithmetic_basic_test --iss spike
|
||||
|
||||
// Run ISS with riscv-ovpsim
|
||||
python3 run.py --test riscv_rand_instr_test --iss ovpsim
|
||||
|
||||
// Run ISS with sail-riscv
|
||||
python3 run.py --test riscv_rand_instr_test --iss sail
|
||||
```
|
||||
|
||||
To run with ISS simulation for RV32IMC, you can specify ISA and ABI from command
|
||||
line like this:
|
||||
|
||||
```
|
||||
// Run a full regression with RV32IMC
|
||||
python3 run.py --isa rv32imc --mabi ilp32
|
||||
```
|
||||
|
||||
We have added a flow to run ISS simulation with both spike and riscv-ovpsim,
|
||||
the instruction trace from these runs will be cross compared. This could greatly
|
||||
speed up your development of new test without the need to simulate against a
|
||||
real RISC-V processor.
|
||||
|
||||
```
|
||||
python3 run.py --test=riscv_rand_instr_test --iss=spike,ovpsim
|
||||
python3 run.py --test=riscv_rand_instr_test --iss=spike,sail
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Configure the generator to match your processor features
|
||||
|
||||
The default configuration of the instruction generator is for **RV64GC** RISC-V
|
||||
processors with address translation capability. You might want to configure the
|
||||
generator according the feature of your processor.
|
||||
|
||||
The static setting of the processor src/riscv_core_setting.sv
|
||||
|
||||
```
|
||||
// Bit width of RISC-V GPR
|
||||
parameter int XLEN = 64;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = SV39;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {USER_MODE,
|
||||
SUPERVISOR_MODE,
|
||||
MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[] = {};
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[] = {RV32I, RV32M, RV64I, RV64M};
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
A few pre-defined configurations can be found under "target" directory, you can
|
||||
run with these targets if it matches your processor specification.
|
||||
|
||||
```
|
||||
// Run regression with RV32IMC configuration
|
||||
python3 run.py --target rv32imc
|
||||
```
|
||||
|
||||
|
||||
### Setup the memory map
|
||||
|
||||
Here's a few cases that you might want to allocate the instruction and data
|
||||
sections to match the actual memory map
|
||||
- The processor has internal memories, and you want to test load/store from
|
||||
various internal/externel memory regions
|
||||
- The processor implments the PMP feature, and you want to configure the memory
|
||||
map to match PMP setting.
|
||||
- Virtual address translation is implmented and you want to test load/store from
|
||||
sparse memory locations to verify data TLB replacement logic.
|
||||
|
||||
You can configure the memory map in [riscv_instr_gen_config.sv](https://github.com/google/riscv-dv/blob/master/src/riscv_instr_gen_config.sv)
|
||||
|
||||
```
|
||||
mem_region_t mem_region[$] = '{
|
||||
'{name:"region_0", size_in_bytes: 4096, xwr: 3'b111},
|
||||
'{name:"region_1", size_in_bytes: 4096 * 4, xwr: 3'b111},
|
||||
'{name:"region_2", size_in_bytes: 4096 * 2, xwr: 3'b111},
|
||||
'{name:"region_3", size_in_bytes: 512, xwr: 3'b111},
|
||||
'{name:"region_4", size_in_bytes: 4096, xwr: 3'b111}
|
||||
};
|
||||
```
|
||||
|
||||
Each memory region belongs to a separate section in the generated assembly
|
||||
program. You can modify the link script to link each section to the target
|
||||
memory location. Please avoid setting a large memory range as it could takes a
|
||||
long time to randomly initializing the memory. You can break down a large memory
|
||||
region to a few representative small regions which covers all the boundary
|
||||
conditions for the load/store testing.
|
||||
|
||||
### Setup regression test list
|
||||
|
||||
[Test list in YAML format](https://github.com/google/riscv-dv/blob/master/yaml/testlist.yaml)
|
||||
|
@ -159,65 +275,6 @@ script, include `riscv_csr_test` in the testlist as shown in the example YAML
|
|||
file above.
|
||||
|
||||
|
||||
### Configure the generator to match your processor features
|
||||
|
||||
The default configuration of the instruction generator is for RV64IMC RISC-V
|
||||
processors with address translation capability. You might want to configure the
|
||||
generator according the feature of your processor.
|
||||
|
||||
The static setting of the processor src/riscv_core_setting.sv
|
||||
|
||||
```
|
||||
// Bit width of RISC-V GPR
|
||||
parameter int XLEN = 64;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = SV39;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {USER_MODE,
|
||||
SUPERVISOR_MODE,
|
||||
MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[] = {};
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[] = {RV32I, RV32M, RV64I, RV64M};
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### Setup the memory map
|
||||
|
||||
Here's a few cases that you might want to allocate the instruction and data
|
||||
sections to match the actual memory map
|
||||
- The processor has internal memories, and you want to test load/store from
|
||||
various internal/externel memory regions
|
||||
- The processor implments the PMP feature, and you want to configure the memory
|
||||
map to match PMP setting.
|
||||
- Virtual address translation is implmented and you want to test load/store from
|
||||
sparse memory locations to verify data TLB replacement logic.
|
||||
|
||||
You can configure the memory map in [riscv_instr_gen_config.sv](https://github.com/google/riscv-dv/blob/master/src/riscv_instr_gen_config.sv)
|
||||
|
||||
```
|
||||
mem_region_t mem_region[$] = '{
|
||||
'{name:"region_0", size_in_bytes: 4096, xwr: 3'b111},
|
||||
'{name:"region_1", size_in_bytes: 4096 * 4, xwr: 3'b111},
|
||||
'{name:"region_2", size_in_bytes: 4096 * 2, xwr: 3'b111},
|
||||
'{name:"region_3", size_in_bytes: 512, xwr: 3'b111},
|
||||
'{name:"region_4", size_in_bytes: 4096, xwr: 3'b111}
|
||||
};
|
||||
```
|
||||
|
||||
Each memory region belongs to a separate section in the generated assembly
|
||||
program. You can modify the link script to link each section to the target
|
||||
memory location. Please avoid setting a large memory range as it could takes a
|
||||
long time to randomly initializing the memory. You can break down a large memory
|
||||
region to a few representative small regions which covers all the boundary
|
||||
conditions for the load/store testing.
|
||||
|
||||
|
||||
### Runtime options of the generator
|
||||
|
||||
|
@ -296,6 +353,22 @@ format](https://github.com/google/riscv-dv/blob/master/yaml/csr_template.yaml)
|
|||
To specify what ISA width should be generated in the test, simply include the
|
||||
matching rv32/rv64/rv128 entry and fill in the appropriate CSR field entries.
|
||||
|
||||
### Privileged CSR Test Generation
|
||||
|
||||
The CSR generation script is located at
|
||||
[scripts/gen_csr_test.py](https://github.com/google/riscv-dv/blob/master/scripts/gen_csr_test.py).
|
||||
The CSR test code that this script generates will execute every CSR instruction
|
||||
on every processor implemented CSR, writing values to the CSR and then using a
|
||||
prediction function to calculate a reference value that will be written into
|
||||
another GPR. The reference value will then be compared to the value actually
|
||||
stored in the CSR to determine whether to jump to the failure condition or
|
||||
continue executing, allowing it to be completely self checking. This script has
|
||||
been integrated with run.py. If you want to run it separately, you can get the
|
||||
command reference with --help:
|
||||
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --help
|
||||
```
|
||||
|
||||
### Adding new instruction stream and test
|
||||
|
||||
|
@ -309,62 +382,7 @@ it with random instructions
|
|||
+directed_instr_5=riscv_multi_page_load_store_instr_stream,4
|
||||
```
|
||||
|
||||
## Compile generated programs with GCC
|
||||
|
||||
- Install [riscv-gcc](https://github.com/riscv/riscv-gcc) toolchain
|
||||
- Set environment variable RISCV_GCC to the RISC-V gcc executable
|
||||
executable. (example: <install_dir>/bin/riscv32-unknown-elf-gcc)
|
||||
- Set environment variable RISCV_OBJCOPY to RISC-v objcopy executable
|
||||
executable. (example: <install_dir>/bin/riscv32-unknown-elf-objcopy)
|
||||
|
||||
## Run ISS (Instruction Set Simulator) simulation
|
||||
|
||||
Currently three ISS are supported, the default ISS is spike. You can install any
|
||||
one of below to run ISS simulation.
|
||||
|
||||
- [spike](https://github.com/riscv/riscv-isa-sim#) setup
|
||||
- Follow the [steps](https://github.com/riscv/riscv-isa-sim#build-steps) to build spike
|
||||
- Install spike with "--enable-commitlog"
|
||||
- Set environment variable SPIKE_PATH to the directory of the spike binary
|
||||
- [riscv-ovpsim](https://github.com/riscv/riscv-ovpsim) setup
|
||||
- Download the riscv-ovpsim binary
|
||||
- Set environment variable OVPSIM_PATH to the directory of the ovpsim binary
|
||||
- [sail-riscv](https://github.com/rems-project/sail-riscv) setup
|
||||
- Follow the [steps](https://github.com/rems-project/sail-riscv/blob/master/README.md) to install sail-riscv
|
||||
- Set environment variable SAIL_RISCV to the sail-riscv binary
|
||||
|
||||
You can use -iss to run with different ISS.
|
||||
|
||||
```
|
||||
// Run ISS with spike
|
||||
python3 run.py --test riscv_arithmetic_basic_test --iss spike
|
||||
|
||||
// Run ISS with riscv-ovpsim
|
||||
python3 run.py --test riscv_rand_instr_test --iss ovpsim
|
||||
|
||||
// Run ISS with sail-riscv
|
||||
python3 run.py --test riscv_rand_instr_test --iss sail
|
||||
```
|
||||
|
||||
To run with ISS simulation for RV32IMC, you can specify ISA and ABI from command
|
||||
line like this:
|
||||
|
||||
```
|
||||
// Run a full regression with RV32IMC
|
||||
python3 run.py --isa rv32imc --mabi ilp32
|
||||
```
|
||||
|
||||
We have added a flow to run ISS simulation with both spike and riscv-ovpsim,
|
||||
the instruction trace from these runs will be cross compared. This could greatly
|
||||
speed up your development of new test without the need to simulate against a
|
||||
real RISC-V processor.
|
||||
|
||||
```
|
||||
python3 run.py --test=riscv_rand_instr_test --iss=spike,ovpsim
|
||||
python3 run.py --test=riscv_rand_instr_test --iss=spike,sail
|
||||
```
|
||||
|
||||
### Integrate a new ISS
|
||||
## Integrate a new ISS
|
||||
|
||||
You can add a new entry in [iss.yaml](https://github.com/google/riscv-dv/blob/master/yaml/iss.yaml)
|
||||
|
||||
|
|
89
vendor/google_riscv-dv/cov.py
vendored
89
vendor/google_riscv-dv/cov.py
vendored
|
@ -31,20 +31,23 @@ from scripts.sail_log_to_trace_csv import *
|
|||
|
||||
LOGGER = logging.getLogger()
|
||||
|
||||
def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, timeout, si):
|
||||
def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, \
|
||||
opts, timeout, simulator, simulator_yaml, core_setting_dir):
|
||||
"""Collect functional coverage from the instruction trace
|
||||
|
||||
Args:
|
||||
log_dir : ISS log directory
|
||||
out : Output directory
|
||||
iss : Instruction set simulator
|
||||
test_list : Testlist of the coverage test
|
||||
batch_size : Number of trace CSV to process per test
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
steps : csv:log to CSV, cov:sample coverage
|
||||
opts : Additional options to the instruction generator
|
||||
timeout : Timeout limit in seconds
|
||||
si : Simulator used to run
|
||||
log_dir : ISS log directory
|
||||
out : Output directory
|
||||
iss : Instruction set simulator
|
||||
test_list : Testlist of the coverage test
|
||||
batch_size : Number of trace CSV to process per test
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
steps : csv:log to CSV, cov:sample coverage
|
||||
opts : Additional options to the instruction generator
|
||||
timeout : Timeout limit in seconds
|
||||
simulator : RTL simulator used to run
|
||||
simulator_yaml : RTL simulator configuration file in YAML format
|
||||
core_setting_dir : Path for riscv_core_setting.sv
|
||||
"""
|
||||
log_list = []
|
||||
csv_list = []
|
||||
|
@ -64,15 +67,19 @@ def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, t
|
|||
logging.info("Process %0s log[%0d/%0d] : %s" % (iss, i+1, len(log_list), log))
|
||||
if iss == "spike":
|
||||
process_spike_sim_log(log, csv, 1)
|
||||
elif iss == "ovpsim":
|
||||
process_ovpsim_sim_log(log, csv, 1)
|
||||
else:
|
||||
logging.error("Full trace for %s is not supported yet" % iss)
|
||||
sys.exit(1)
|
||||
if steps == "all" or re.match("cov", steps):
|
||||
build_cmd = ("python3 run.py -si %s --co -o %s --cov -tl %s %s" %
|
||||
(si, out, testlist, opts))
|
||||
base_sim_cmd = ("python3 run.py -si %s --so -o %s --cov -tl %s %s "
|
||||
build_cmd = ("python3 run.py --simulator %s --simulator_yaml %s "
|
||||
"--core_setting_dir %s --co -o %s --cov -tl %s %s " %
|
||||
(simulator, simulator_yaml, core_setting_dir, out, testlist, opts))
|
||||
base_sim_cmd = ("python3 run.py --simulator %s --simulator_yaml %s "
|
||||
"--core_setting_dir %s --so -o %s --cov -tl %s %s "
|
||||
"-tn riscv_instr_cov_test --steps gen --sim_opts \"<trace_csv_opts>\"" %
|
||||
(si, out, testlist, opts))
|
||||
(simulator, simulator_yaml, core_setting_dir, out, testlist, opts))
|
||||
logging.info("Building the coverage collection framework")
|
||||
run_cmd(build_cmd)
|
||||
file_idx = 0
|
||||
|
@ -107,28 +114,33 @@ def collect_cov(log_dir, out, iss, testlist, batch_size, lsf_cmd, steps, opts, t
|
|||
logging.info("Collecting functional coverage from %0d trace CSV...done" % len(csv_list))
|
||||
|
||||
|
||||
def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd, timeout, si):
|
||||
def run_cov_debug_test(out, instr_cnt, testlist, batch_size, opts, lsf_cmd,\
|
||||
timeout, simulator, simulator_yaml, core_setting_dir):
|
||||
"""Collect functional coverage from the instruction trace
|
||||
|
||||
Args:
|
||||
out : Output directory
|
||||
instr_cnt : Number of instruction to randomize
|
||||
test_list : Testlist of the coverage test
|
||||
batch_size : Number of trace CSV to process per test
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
opts : Additional options to the instruction generator
|
||||
timeout : Timeout limit in seconds
|
||||
si : Simulator used to run
|
||||
out : Output directory
|
||||
instr_cnt : Number of instruction to randomize
|
||||
test_list : Testlist of the coverage test
|
||||
batch_size : Number of trace CSV to process per test
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
opts : Additional options to the instruction generator
|
||||
timeout : Timeout limit in seconds
|
||||
simulator : RTL simulator used to run
|
||||
simulator_yaml : RTL simulator configuration file in YAML format
|
||||
core_setting_dir : Path for riscv_core_setting.sv
|
||||
"""
|
||||
sim_cmd_list = []
|
||||
logging.info("Building the coverage collection framework")
|
||||
build_cmd = ("python3 run.py -si %s --co -o %s --cov -tl %s %s" %
|
||||
(si, out, testlist, opts))
|
||||
build_cmd = ("python3 run.py --simulator %s --simulator_yaml %s "
|
||||
"--core_setting_dir %s --co -o %s --cov -tl %s %s" %
|
||||
(simulator, simulator_yaml, core_setting_dir, out, testlist, opts))
|
||||
run_cmd(build_cmd)
|
||||
base_sim_cmd = ("python3 run.py -si %s --so -o %s --cov -tl %s %s "
|
||||
base_sim_cmd = ("python3 run.py --simulator %s --simulator_yaml %s "
|
||||
"--core_setting_dir %s --so -o %s --cov -tl %s %s "
|
||||
"-tn riscv_instr_cov_debug_test --steps gen "
|
||||
"--sim_opts \"+num_of_iterations=<instr_cnt>\"" %
|
||||
(si, out, testlist, opts))
|
||||
(simulator, simulator_yaml, core_setting_dir, out, testlist, opts))
|
||||
if batch_size > 0:
|
||||
batch_cnt = int((instr_cnt+batch_size-1)/batch_size)
|
||||
logging.info("Batch size: %0d, Batch cnt:%0d" % (batch_size, batch_cnt))
|
||||
|
@ -188,8 +200,15 @@ 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("--target", type=str, default="",
|
||||
help="Run the generator with pre-defined targets: \
|
||||
rv32imc, rv32i, rv64imc")
|
||||
parser.add_argument("-si", "--simulator", type=str, default="vcs",
|
||||
help="Simulator used to run the generator, default VCS", dest="simulator")
|
||||
parser.add_argument("--simulator_yaml", type=str, default="",
|
||||
help="RTL simulator setting YAML")
|
||||
parser.add_argument("-cs", "--core_setting_dir", type=str, default="",
|
||||
help="Path for the riscv_core_setting.sv")
|
||||
parser.set_defaults(verbose=False)
|
||||
parser.set_defaults(debug_mode=False)
|
||||
return parser
|
||||
|
@ -207,6 +226,14 @@ def main():
|
|||
if not args.testlist:
|
||||
args.testlist = cwd + "/yaml/cov_testlist.yaml"
|
||||
|
||||
if not args.simulator_yaml:
|
||||
args.simulator_yaml = cwd + "/yaml/simulator.yaml"
|
||||
|
||||
if args.target:
|
||||
args.core_setting_dir = cwd + "/target/"+ args.target
|
||||
elif not args.core_setting_dir:
|
||||
args.core_setting_dir = cwd + "/setting/"
|
||||
|
||||
# Create output directory
|
||||
if args.o is None:
|
||||
output_dir = "out_" + str(date.today())
|
||||
|
@ -217,10 +244,12 @@ def main():
|
|||
|
||||
if args.debug_mode:
|
||||
run_cov_debug_test(output_dir, args.instr_cnt, args.testlist,
|
||||
args.batch_size, args.opts, args.lsf_cmd, args.timeout, args.simulator)
|
||||
args.batch_size, args.opts, args.lsf_cmd, args.timeout,
|
||||
args.simulator, args.simulator_yaml, args.core_setting_dir)
|
||||
else:
|
||||
collect_cov(args.dir, output_dir, args.iss, args.testlist, args.batch_size,
|
||||
args.lsf_cmd, args.steps, args.opts, args.timeout, args.simulator)
|
||||
args.lsf_cmd, args.steps, args.opts, args.timeout,
|
||||
args.simulator, args.simulator_yaml, args.core_setting_dir)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
1
vendor/google_riscv-dv/questa_sim.tcl
vendored
1
vendor/google_riscv-dv/questa_sim.tcl
vendored
|
@ -1 +1,2 @@
|
|||
coverage save -onexit riscv.ucdb
|
||||
run -all ; quit
|
||||
|
|
21
vendor/google_riscv-dv/run.py
vendored
21
vendor/google_riscv-dv/run.py
vendored
|
@ -92,7 +92,7 @@ def parse_iss_yaml(iss, iss_yaml, isa):
|
|||
cmd = entry['cmd'].rstrip()
|
||||
cmd = re.sub("\<path_var\>", get_env_var(entry['path_var']), cmd)
|
||||
if iss == "ovpsim":
|
||||
cmd = re.sub("\<variant\>", isa.upper(), cmd)
|
||||
cmd = re.sub("\<variant\>", isa, cmd)
|
||||
else:
|
||||
cmd = re.sub("\<variant\>", isa, cmd)
|
||||
return cmd
|
||||
|
@ -466,6 +466,9 @@ def setup_parser():
|
|||
help="Path for the user extension directory")
|
||||
parser.add_argument("--asm_test", type=str, default="",
|
||||
help="Directed assembly test")
|
||||
parser.add_argument("--target", type=str, default="",
|
||||
help="Run the generator with pre-defined targets: \
|
||||
rv32imc, rv32i, rv64imc")
|
||||
parser.add_argument("--log_suffix", type=str, default="",
|
||||
help="Simulation log name suffix")
|
||||
parser.add_argument("-bz", "--batch_size", type=int, default=0,
|
||||
|
@ -495,7 +498,21 @@ def main():
|
|||
if not args.simulator_yaml:
|
||||
args.simulator_yaml = cwd + "/yaml/simulator.yaml"
|
||||
|
||||
if not args.testlist:
|
||||
if args.target:
|
||||
args.testlist = cwd + "/target/"+ args.target +"/testlist.yaml"
|
||||
args.core_setting_dir = cwd + "/target/"+ args.target
|
||||
if args.target == "rv32imc":
|
||||
args.mabi = "ilp32"
|
||||
args.isa = "rv32imc"
|
||||
elif args.target == "rv32i":
|
||||
args.mabi = "ilp32"
|
||||
args.isa = "rv32i"
|
||||
elif args.target == "rv64imc":
|
||||
args.mabi = "lp64"
|
||||
args.isa = "rv64imc"
|
||||
else:
|
||||
print ("Unsupported target: %0s" % args.target)
|
||||
elif not args.testlist:
|
||||
args.testlist = cwd + "/yaml/testlist.yaml"
|
||||
|
||||
if args.asm_test != "":
|
||||
|
|
|
@ -20,15 +20,63 @@ import os
|
|||
import argparse
|
||||
import logging
|
||||
|
||||
import sys
|
||||
import pprint as pp
|
||||
|
||||
from riscv_trace_csv import *
|
||||
|
||||
def process_ovpsim_sim_log(ovpsim_log, csv):
|
||||
"""Process SPIKE simulation log.
|
||||
def convert_mode(pri, line):
|
||||
if "Machine" in pri: return str(3)
|
||||
logging.info("convert_mode = UNKNOWN PRIV MODE [%s]: %s" % (pri, line))
|
||||
sys.exit(-1)
|
||||
|
||||
REGS = ["zero","ra","sp","gp","tp","t0","t1","t2","s0","s1",
|
||||
"a0","a1","a2","a3","a4","a5","a6","a7",
|
||||
"s2","s3","s4","s5","s6","s7","s8","s9","s10","s11",
|
||||
"t3","t4","t5","t6"]
|
||||
|
||||
def process_jalr(trace, operands, gpr):
|
||||
## jalr x3
|
||||
## jalr 9(x3)
|
||||
## jalr x2,x3
|
||||
## jalr x2,4(x3)
|
||||
if len(operands) == 1:
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
m = ADDR_RE.search(operands[0])
|
||||
if m: # jalr 9(x3)
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
else: # jalr x3
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif len(operands) == 2:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
m = ADDR_RE.search(operands[1])
|
||||
if m: # jalr x2,4(x3)
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
else: # jalr x2,x3
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
|
||||
def process_if_compressed(prev_trace):
|
||||
if len(prev_trace.binary) == 4: # compressed are always 4 hex digits
|
||||
prev_trace.instr = "c."+prev_trace.instr
|
||||
# logging.debug("process_if_compressed(%s, %s)" % (prev_trace.instr, prev_trace.binary))
|
||||
|
||||
def process_ovpsim_sim_log(ovpsim_log, csv, full_trace = 0):
|
||||
"""Process OVPsim simulation log.
|
||||
|
||||
Extract instruction and affected register information from ovpsim simulation
|
||||
log and save to a list.
|
||||
"""
|
||||
logging.info("Processing ovpsim log : %s" % ovpsim_log)
|
||||
logging.info("Processing ovpsim log [%d]: %s" % (full_trace, ovpsim_log))
|
||||
instr_cnt = 0
|
||||
trace_instr = ""
|
||||
trace_bin = ""
|
||||
|
@ -41,33 +89,113 @@ def process_ovpsim_sim_log(ovpsim_log, csv):
|
|||
cmd = ("sed -i '/ecall/q' %s" % ovpsim_log)
|
||||
os.system(cmd)
|
||||
|
||||
gpr = {}
|
||||
|
||||
for g in REGS:
|
||||
gpr[g] = 0
|
||||
|
||||
with open(ovpsim_log, "r") as f, open(csv, "w") as csv_fd:
|
||||
trace_csv = RiscvInstructiontTraceCsv(csv_fd)
|
||||
trace_csv.start_new_trace()
|
||||
prev_trace = 0
|
||||
for line in f:
|
||||
# Extract instruction infromation
|
||||
m = re.search(r"riscvOVPsim.*, 0x(?P<addr>.*?)(?P<section>\(.*\): ?)" \
|
||||
"(?P<bin>[a-f0-9]*?)\s+(?P<instr>.*?)$", line)
|
||||
"(?P<mode>[A-Za-z]*?)\s+(?P<bin>[a-f0-9]*?)\s+(?P<instr>.*?)$", line)
|
||||
if m:
|
||||
if prev_trace: # if not yet written as it had no data following it
|
||||
trace_csv.write_trace_entry(prev_trace)
|
||||
prev_trace = 0
|
||||
trace_bin = m.group("bin")
|
||||
trace_instr = m.group("instr")
|
||||
trace_instr_str = m.group("instr")
|
||||
trace_addr = m.group("addr")
|
||||
trace_section = m.group("section") # not yet used
|
||||
#trace_mode = convert_mode(m.group("mode"), line)
|
||||
instr_cnt += 1
|
||||
prev_trace = RiscvInstructiontTraceEntry()
|
||||
prev_trace.instr_str = trace_instr_str
|
||||
prev_trace.binary = trace_bin
|
||||
prev_trace.addr = trace_addr
|
||||
#prev_trace.privileged_mode = trace_mode
|
||||
prev_trace.instr = trace_instr # wrong
|
||||
|
||||
if 0:
|
||||
print ("line ::"+line)
|
||||
print ("bin ::"+trace_bin)
|
||||
print ("instr::"+trace_instr_str)
|
||||
print ("ins ::"+trace_instr)
|
||||
print ("addr ::"+trace_addr)
|
||||
print ("sect ::"+trace_section)
|
||||
#print ("mode ::"+prev_trace.privileged_mode)
|
||||
sys.exit(-1)
|
||||
|
||||
if full_trace:
|
||||
i = re.search (r"(?P<instr>[a-z]*?)\s", trace_instr_str)
|
||||
if i:
|
||||
trace_instr = i.group("instr")
|
||||
if trace_instr_str == "nop" or \
|
||||
trace_instr_str == "mret" or \
|
||||
trace_instr_str == "ecall" :
|
||||
# this will probably need also doing for things like wfi too
|
||||
trace_instr = trace_instr_str
|
||||
prev_trace.instr = trace_instr
|
||||
process_if_compressed(prev_trace)
|
||||
o = re.search (r"(?P<instr>[a-z]*?)\s(?P<operand>.*)", trace_instr_str)
|
||||
if o:
|
||||
operand_str = o.group("operand").replace(" ", "")
|
||||
operands = operand_str.split(",")
|
||||
if (prev_trace.instr in ['jalr']):
|
||||
process_jalr(prev_trace, operands, gpr)
|
||||
else:
|
||||
assign_operand(prev_trace, operands, gpr)
|
||||
# sys.exit(-1)
|
||||
else:
|
||||
# print("no operand for [%s] in [%s]" % (trace_instr, trace_instr_str))
|
||||
pass
|
||||
else:
|
||||
trace_instr = ""
|
||||
else:
|
||||
if 0:
|
||||
print ("not ins line... [%s]" % (line))
|
||||
# Extract register value information
|
||||
n = re.search(r" (?P<rd>[a-z]{1,3}[0-9]{0,2}?) (?P<pre>[a-f0-9]+?)" \
|
||||
" -> (?P<val>[a-f0-9]+?)$", line)
|
||||
if n:
|
||||
# Write the extracted instruction to a csvcol buffer file
|
||||
# print("%0s %0s = %0s" % (trace_instr_str, m.group("rd"), m.group("val")))
|
||||
if n.group("rd") != "frm":
|
||||
rv_instr_trace = RiscvInstructiontTraceEntry()
|
||||
rv_instr_trace.rd = n.group("rd")
|
||||
rv_instr_trace.rd_val = n.group("val")
|
||||
rv_instr_trace.instr_str = trace_instr
|
||||
rv_instr_trace.rs1 = prev_trace.rs1
|
||||
rv_instr_trace.rs1_val = prev_trace.rs1_val
|
||||
rv_instr_trace.rs2 = prev_trace.rs2
|
||||
rv_instr_trace.rs2_val = prev_trace.rs2_val
|
||||
rv_instr_trace.instr_str = trace_instr_str
|
||||
rv_instr_trace.instr = prev_trace.instr
|
||||
rv_instr_trace.binary = trace_bin
|
||||
rv_instr_trace.addr = trace_addr
|
||||
#rv_instr_trace.privileged_mode = trace_mode
|
||||
gpr[rv_instr_trace.rd] = rv_instr_trace.rd_val
|
||||
if full_trace:
|
||||
rv_instr_trace.instr = prev_trace.instr
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
prev_trace = 0 # we wrote out as it had data, so no need to write it next time round
|
||||
if 0:
|
||||
print ("write entry [[%d]]: rd[%s] val[%s] instr(%s) bin(%s) addr(%s)"
|
||||
% (instr_cnt, rv_instr_trace.rd, rv_instr_trace.rd_val,
|
||||
trace_instr_str, trace_bin, trace_addr))
|
||||
print (rv_instr_trace.__dict__)
|
||||
sys.exit(-1)
|
||||
else:
|
||||
if 0:
|
||||
print ("write previous entry: [%s] %s " % (str(instr_cnt), line))
|
||||
sys.exit(-1)
|
||||
logging.info("Processed instruction count : %d" % instr_cnt)
|
||||
if instr_cnt == 0:
|
||||
logging.error ("No Instructions in logfile: %s" % ovpsim_log)
|
||||
sys.exit(-1)
|
||||
logging.info("CSV saved to : %s" % csv)
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -76,9 +204,16 @@ def main():
|
|||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--log", type=str, help="Input ovpsim simulation log")
|
||||
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
|
||||
parser.add_argument("-f", "--full_trace", dest="full_trace", action="store_true",
|
||||
help="Generate the full trace")
|
||||
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
|
||||
help="Verbose logging")
|
||||
parser.set_defaults(full_trace=False)
|
||||
parser.set_defaults(verbose=False)
|
||||
args = parser.parse_args()
|
||||
setup_logging(args.verbose)
|
||||
# Process ovpsim log
|
||||
process_ovpsim_sim_log(args.log, args.csv)
|
||||
process_ovpsim_sim_log(args.log, args.csv, args.full_trace)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
292
vendor/google_riscv-dv/scripts/riscv_trace_csv.py
vendored
292
vendor/google_riscv-dv/scripts/riscv_trace_csv.py
vendored
|
@ -17,6 +17,8 @@ Class for RISC-V instruction trace CSV
|
|||
"""
|
||||
|
||||
import csv
|
||||
import re
|
||||
import logging
|
||||
|
||||
class RiscvInstructiontTraceEntry(object):
|
||||
"""RISC-V instruction trace entry"""
|
||||
|
@ -159,3 +161,293 @@ def gpr_to_abi(gpr):
|
|||
"f31" : "ft11",
|
||||
}
|
||||
return switcher.get(gpr, "na")
|
||||
|
||||
|
||||
def sint_to_hex(val):
|
||||
"""Signed integer to hex conversion"""
|
||||
return str(hex((val + (1 << 32)) % (1 << 32)))
|
||||
|
||||
|
||||
def get_imm_hex_val(imm):
|
||||
"""Get the hex representation of the imm value"""
|
||||
if imm[0] == '-':
|
||||
is_negative = 1
|
||||
imm = imm[1:]
|
||||
else:
|
||||
is_negative = 0
|
||||
if len(imm) > 1 and imm[1] != 'x':
|
||||
imm = "0x"+imm
|
||||
imm_val = int(imm, 0)
|
||||
if is_negative:
|
||||
imm_val = -imm_val
|
||||
hexstr = sint_to_hex(imm_val)
|
||||
return hexstr[2:]
|
||||
|
||||
ADDR_RE = re.compile(r"(?P<imm>[\-0-9]+?)\((?P<rs1>.*)\)")
|
||||
|
||||
def assign_operand(trace, operands, gpr):
|
||||
"""Assign the operand value of the instruction trace"""
|
||||
if trace.instr in ['lb', 'lh', 'lw', 'lbu', 'lhu', 'ld', 'lq', 'lwu', 'ldu',
|
||||
'c.lw', 'c.ld', 'c.lq', 'c.lwsp', 'c.ldsp', 'c.lqsp']:
|
||||
# TODO: Support regular load/store format
|
||||
m = ADDR_RE.search(operands[1])
|
||||
# Load instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
if m:
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
else:
|
||||
logging.info("Unexpected load address %0s", operands[1])
|
||||
elif trace.instr in ['sb', 'sh', 'sw', 'sd', 'sq', 'c.sw', 'c.sd', 'c.sq',
|
||||
'c.swsp', 'c.sdsp', 'c.sqsp']:
|
||||
# Store instruction
|
||||
m = ADDR_RE.search(operands[1])
|
||||
# Load instruction
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
if m:
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
else:
|
||||
logging.info("Unexpected store address %0s", operands[1])
|
||||
elif trace.instr in ['mul', 'mulh', 'mulhsu', 'mulhu', 'div', 'divu', 'rem', 'remu',
|
||||
'mulw', 'muld', 'divw', 'divuw', 'divd', 'remw', 'remd', 'remuw',
|
||||
'remud', 'sll', 'srl', 'sra', 'add', 'sub', 'xor', 'or', 'and',
|
||||
'slt', 'sltu', 'sllw', 'slld', 'srlw', 'srld', 'sraw', 'srad',
|
||||
'addw', 'addd', 'subw', 'subd']:
|
||||
# R type instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[2]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['c.add', 'c.addw', 'c.mv', 'c.sub', 'c.and', 'c.or', 'c.xor', 'c.subw']:
|
||||
# CR type
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['c.jr']:
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
elif trace.instr in ['c.jr', 'c.jalr']:
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
elif trace.instr in ['slli', 'srli', 'srai', 'addi', 'xori', 'ori', 'andi', 'slti',
|
||||
'sltiu', 'slliw', 'sllid', 'srliw', 'srlid', 'sraiw', 'sraid',
|
||||
'addiw', 'addid']:
|
||||
# I type instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.addi16sp', 'c.addi4spn']:
|
||||
trace.rs1 = 'sp'
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.imm = get_imm_hex_val(operands[-1])
|
||||
elif trace.instr in ['c.addi', 'c.addiw', 'c.li', 'c.lui',
|
||||
'c.slli', 'c.srai', 'c.srli', 'c.andi']:
|
||||
# CI/CIW type
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[-1])
|
||||
elif trace.instr in ['beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu']:
|
||||
# SB type instruction
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.beqz', 'c.bnez']:
|
||||
# CB type instruction
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['csrrw', 'csrrs', 'csrrc']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.rs1 = operands[2]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
elif trace.instr in ['csrrwi', 'csrrsi', 'csrrci']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['scall', 'sbreak', 'fence', 'fence.i', 'ecall', 'ebreak', 'wfi',
|
||||
'sfence.vma', 'c.ebreak', 'nop', 'c.nop']:
|
||||
trace.rd = 'zero'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs2 = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2_val = '0'
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['lui', 'auipc']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['jal']:
|
||||
if len(operands) == 1:
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
else:
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['jalr']:
|
||||
if len(operands) == 1:
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
else:
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.j', 'c.jal']:
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
# Pseudo instruction convertion below
|
||||
elif trace.instr in ['mv']:
|
||||
trace.instr = 'addi'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['not']:
|
||||
trace.instr = 'xori'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('-1')
|
||||
elif trace.instr in ['neg']:
|
||||
trace.instr = 'sub'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['negw']:
|
||||
trace.instr = 'subw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['sext.w']:
|
||||
trace.instr = 'addiw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['seqz']:
|
||||
trace.instr = 'sltiu'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('1')
|
||||
elif trace.instr in ['snez']:
|
||||
trace.instr = 'sltu'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['sltz']:
|
||||
trace.instr = 'slt'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
elif trace.instr in ['sgtz']:
|
||||
trace.instr = 'slt'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['beqz', 'bnez', 'bgez', 'bltz']:
|
||||
trace.instr = trace.instr[0:3]
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['blez']:
|
||||
trace.instr = 'bge'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['bgtz']:
|
||||
trace.instr = 'blt'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['csrr']:
|
||||
trace.instr = 'csrrw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
elif trace.instr in ['csrw', 'csrs', 'csrc']:
|
||||
trace.instr = 'csrr' + trace.instr[-1]
|
||||
trace.csr = operands[0]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
elif trace.instr in ['csrwi', 'csrsi', 'csrci']:
|
||||
trace.instr = 'csrr' + trace.instr[-2:]
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.csr = operands[0]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['j']:
|
||||
trace.instr = 'jal'
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
elif trace.instr in ['jr']:
|
||||
trace.instr = 'jal'
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.rs1 = operands[0]
|
||||
if trace.rs1 in gpr:
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
elif trace.instr in ['li']:
|
||||
trace.instr = 'li'
|
||||
elif trace.instr[0:2] in ['lr', 'am', 'sc']:
|
||||
# TODO: Support A-extension
|
||||
pass
|
||||
else:
|
||||
# TODO: Support other instructions
|
||||
logging.info("Unsupported instr : %s" % trace.instr)
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ CORE_RE = re.compile(r"core.*0x(?P<addr>[a-f0-9]+?) \(0x(?P<bin>.*?)\) (?P<inst
|
|||
INSTR_RE = re.compile(r"(?P<instr>[a-z\.0-9]+?)(\s+?)(?P<operand>.*)")
|
||||
GPR_RE = re.compile(r"^[a-z][0-9a-z]$")
|
||||
ILLE_RE = re.compile(r"trap_illegal_instruction")
|
||||
ADDR_RE = re.compile(r"(?P<imm>[\-0-9]+?)\((?P<rs1>.*)\)")
|
||||
PC_RE = re.compile(r"pc+")
|
||||
HEX_RE = re.compile(r"^0x")
|
||||
|
||||
|
@ -79,6 +78,8 @@ def process_spike_sim_log(spike_log, csv, full_trace = 0):
|
|||
if nextline != "":
|
||||
if ILLE_RE.search(nextline):
|
||||
if full_trace:
|
||||
logging.debug("Illegal instruction: %s, opcode:%s" %
|
||||
(rv_instr_trace.instr_str, rv_instr_trace.binary))
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
continue
|
||||
m = RD_RE.search(nextline)
|
||||
|
@ -110,272 +111,6 @@ def process_spike_sim_log(spike_log, csv, full_trace = 0):
|
|||
logging.info("CSV saved to : %s" % csv)
|
||||
|
||||
|
||||
def sint_to_hex(val):
|
||||
"""Signed integer to hex conversion"""
|
||||
return str(hex((val + (1 << 32)) % (1 << 32)))
|
||||
|
||||
|
||||
def get_imm_hex_val(imm):
|
||||
"""Get the hex representation of the imm value"""
|
||||
if imm[0] == '-':
|
||||
is_negative = 1
|
||||
imm = imm[1:]
|
||||
else:
|
||||
is_negative = 0
|
||||
imm_val = int(imm, 0)
|
||||
if is_negative:
|
||||
imm_val = -imm_val
|
||||
hexstr = sint_to_hex(imm_val)
|
||||
return hexstr[2:]
|
||||
|
||||
|
||||
def assign_operand(trace, operands, gpr):
|
||||
#logging.debug("-> [%0s] %0s" % (trace.instr, trace.instr_str))
|
||||
if trace.instr in ['lb', 'lh', 'lw', 'lbu', 'lhu', 'ld', 'lq', 'lwu', 'ldu',
|
||||
'c.lw', 'c.ld', 'c.lq', 'c.lwsp', 'c.ldsp', 'c.lqsp']:
|
||||
# TODO: Support regular load/store format
|
||||
m = ADDR_RE.search(operands[1])
|
||||
# Load instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
if m:
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
else:
|
||||
logging.info("Unexpected load address %0s", operands[1])
|
||||
elif trace.instr in ['sb', 'sh', 'sw', 'sd', 'sq', 'c.sw', 'c.sd', 'c.sq',
|
||||
'c.swsp', 'c.sdsp', 'c.sqsp']:
|
||||
# Store instruction
|
||||
m = ADDR_RE.search(operands[1])
|
||||
# Load instruction
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
if m:
|
||||
trace.imm = get_imm_hex_val(m.group('imm'))
|
||||
trace.rs1 = m.group('rs1')
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
else:
|
||||
logging.info("Unexpected store address %0s", operands[1])
|
||||
elif trace.instr in ['mul', 'mulh', 'mulhsu', 'mulhu', 'div', 'divu', 'rem', 'remu',
|
||||
'mulw', 'muld', 'divw', 'divuw', 'divd', 'remw', 'remd', 'remuw',
|
||||
'remud', 'sll', 'srl', 'sra', 'add', 'sub', 'xor', 'or', 'and',
|
||||
'slt', 'sltu', 'sllw', 'slld', 'srlw', 'srld', 'sraw', 'srad',
|
||||
'addw', 'addd', 'subw', 'subd']:
|
||||
# R type instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[2]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['c.add', 'c.addw', 'c.mv', 'c.sub', 'c.jr', 'c.and', 'c.or',
|
||||
'c.xor', 'c.subw']:
|
||||
# CR type
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['slli', 'srli', 'srai', 'addi', 'xori', 'ori', 'andi', 'slti',
|
||||
'sltiu', 'slliw', 'sllid', 'srliw', 'srlid', 'sraiw', 'sraid',
|
||||
'addiw', 'addid']:
|
||||
# I type instruction
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.addi', 'c.addiw', 'c.addi16sp', 'c.addi4spn', 'c.li', 'c.lui',
|
||||
'c.slli', 'c.srai', 'c.srli', 'c.andi']:
|
||||
# CI/CIW type
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.imm = get_imm_hex_val(operands[-1])
|
||||
elif trace.instr in ['beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu']:
|
||||
# SB type instruction
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.beqz', 'c.bnez']:
|
||||
# CB type instruction
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['csrrw', 'csrrs', 'csrrc']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.rs1 = operands[2]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
elif trace.instr in ['csrrwi', 'csrrsi', 'csrrci']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['scall', 'sbreak', 'fence', 'fence.i', 'ecall', 'ebreak', 'wfi',
|
||||
'sfence.vma', 'c.ebreak', 'nop', 'c.nop']:
|
||||
trace.rd = 'zero'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs2 = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2_val = '0'
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['lui', 'auipc']:
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['jal']:
|
||||
if len(operands) == 1:
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
else:
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['jalr']:
|
||||
if len(operands) == 1:
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
else:
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val(operands[2])
|
||||
elif trace.instr in ['c.j', 'c.jal']:
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
# Pseudo instruction convertion below
|
||||
elif trace.instr in ['mv']:
|
||||
trace.instr = 'addi'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['not']:
|
||||
trace.instr = 'xori'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('-1')
|
||||
elif trace.instr in ['neg']:
|
||||
trace.instr = 'sub'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
elif trace.instr in ['negw']:
|
||||
trace.instr = 'subw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['sext.w']:
|
||||
trace.instr = 'addiw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('0')
|
||||
elif trace.instr in ['seqz']:
|
||||
trace.instr = 'sltiu'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.imm = get_imm_hex_val('1')
|
||||
elif trace.instr in ['snez']:
|
||||
trace.instr = 'sltu'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['sltz']:
|
||||
trace.instr = 'slt'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
elif trace.instr in ['sgtz']:
|
||||
trace.instr = 'slt'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[1]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
elif trace.instr in ['beqz', 'bnez', 'bgez', 'bltz']:
|
||||
trace.instr = trace.instr[0:3]
|
||||
trace.rs1 = operands[0]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rs2 = 'zero'
|
||||
trace.rs2_val = '0'
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['blez']:
|
||||
trace.instr = 'bge'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['bgtz']:
|
||||
trace.instr = 'blt'
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
trace.rs2 = operands[0]
|
||||
trace.rs2_val = gpr[trace.rs2]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['csrr']:
|
||||
trace.instr = 'csrrw'
|
||||
trace.rd = operands[0]
|
||||
trace.rd_val = gpr[trace.rd]
|
||||
trace.csr = operands[1]
|
||||
trace.rs1 = 'zero'
|
||||
trace.rs1_val = '0'
|
||||
elif trace.instr in ['csrw', 'csrs', 'csrc']:
|
||||
trace.instr = 'csrr' + trace.instr[-1]
|
||||
trace.csr = operands[0]
|
||||
trace.rs1 = operands[1]
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
elif trace.instr in ['csrwi', 'csrsi', 'csrci']:
|
||||
trace.instr = 'csrr' + trace.instr[-2:]
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.csr = operands[0]
|
||||
trace.imm = get_imm_hex_val(operands[1])
|
||||
elif trace.instr in ['j']:
|
||||
trace.instr = 'jal'
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.imm = get_imm_hex_val(operands[0])
|
||||
elif trace.instr in ['jr']:
|
||||
trace.instr = 'jal'
|
||||
trace.rd = 'zero'
|
||||
trace.rd_val = '0'
|
||||
trace.rs1 = operands[0]
|
||||
if trace.rs1 in gpr:
|
||||
trace.rs1_val = gpr[trace.rs1]
|
||||
elif trace.instr in ['li']:
|
||||
trace.instr = 'li'
|
||||
elif trace.instr[0:2] in ['lr', 'am', 'sc']:
|
||||
# TODO: Support A-extension
|
||||
pass
|
||||
else:
|
||||
# TODO: Support other instructions
|
||||
logging.info("Unsupported instr : %s" % trace.instr)
|
||||
|
||||
def main():
|
||||
instr_trace = []
|
||||
# Parse input arguments
|
||||
|
|
|
@ -35,12 +35,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
// These programs are called in the interrupt/exception handling routine based on the privileged
|
||||
// mode settings. For example, when the interrupt/exception is delegated to S-mode, if both SUM
|
||||
// and MPRV equal 1, kernel program can fetch/load/store from U-mode pages,
|
||||
// smode_accessible_umode_program is designed for this purpose. There can be other cases that
|
||||
// umode_program is designed for this purpose. There can be other cases that
|
||||
// instruction can only be fetched from S-mode pages but load/store can access U-mode pages, or
|
||||
// everything needs to be in S-mode pages.
|
||||
riscv_instr_sequence smode_accessible_umode_program;
|
||||
riscv_instr_sequence umode_program;
|
||||
riscv_instr_sequence smode_program;
|
||||
riscv_instr_sequence smode_ls_umem_program;
|
||||
riscv_instr_sequence smode_lsu_program;
|
||||
riscv_instr_stream directed_instr[];
|
||||
string instr_stream[$];
|
||||
riscv_callstack_gen callstack_gen;
|
||||
|
@ -141,13 +141,12 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
instr_stream.push_back(".text");
|
||||
// Kernel programs
|
||||
if (cfg.virtual_addr_translation_on) begin
|
||||
smode_accessible_umode_program = riscv_instr_sequence::type_id::
|
||||
create("smode_accessible_umode_program");
|
||||
gen_kernel_program(smode_accessible_umode_program);
|
||||
umode_program = riscv_instr_sequence::type_id::create("umode_program");
|
||||
gen_kernel_program(umode_program);
|
||||
smode_program = riscv_instr_sequence::type_id::create("smode_program");
|
||||
gen_kernel_program(smode_program);
|
||||
smode_ls_umem_program = riscv_instr_sequence::type_id::create("smode_ls_umem_program");
|
||||
gen_kernel_program(smode_ls_umem_program);
|
||||
smode_lsu_program = riscv_instr_sequence::type_id::create("smode_lsu_program");
|
||||
gen_kernel_program(smode_lsu_program);
|
||||
end
|
||||
// All trap/interrupt handling is in the kernel region
|
||||
// Trap/interrupt delegation to user mode is not supported now
|
||||
|
@ -1155,7 +1154,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
end
|
||||
if($cast(new_instr_stream, object_h)) begin
|
||||
new_instr_stream.cfg = cfg;
|
||||
new_instr_stream.label = $sformatf("%0s_instr_%0d", label, idx);
|
||||
new_instr_stream.label = $sformatf("%0s_%0d", label, idx);
|
||||
new_instr_stream.kernel_mode = kernel_mode;
|
||||
`DV_CHECK_RANDOMIZE_FATAL(new_instr_stream)
|
||||
instr_stream = {instr_stream, new_instr_stream};
|
||||
|
|
|
@ -85,55 +85,12 @@ class riscv_mem_access_stream extends riscv_directed_instr_stream;
|
|||
|
||||
endclass
|
||||
|
||||
// Create a infinte zero instruction loop, test if we can interrupt or
|
||||
// enter debug mode while core is executing this loop
|
||||
class riscv_infinte_loop_instr extends riscv_directed_instr_stream;
|
||||
|
||||
string label_prefix = "";
|
||||
string label_name;
|
||||
|
||||
`uvm_object_utils(riscv_infinte_loop_instr)
|
||||
|
||||
constraint instr_c {
|
||||
foreach(instr_list[i]) {
|
||||
instr_list[i].imm == 0;
|
||||
instr_list[i].category inside {JUMP, BRANCH};
|
||||
instr_list[i].instr_name != JALR;
|
||||
}
|
||||
}
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
function void pre_randomize();
|
||||
riscv_rand_instr instr;
|
||||
initialize_instr_list(5);
|
||||
foreach(instr_list[i]) begin
|
||||
$cast(instr, instr_list[i]);
|
||||
instr.constraint_cfg_knob_c.constraint_mode(0);
|
||||
end
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
foreach(instr_list[i]) begin
|
||||
label_name = $sformatf("%0s_inf_loop_%0d", label_prefix, i);
|
||||
instr_list[i].atomic = 1'b1;
|
||||
instr_list[i].label = label_name;
|
||||
instr_list[i].imm_str = label_name;
|
||||
instr_list[i].has_label = 1'b1;
|
||||
instr_list[i].branch_assigned = 1'b1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
// Jump instruction (JAL, JALR)
|
||||
// la rd0, jump_tagert_label
|
||||
// addi rd1, offset, rd0
|
||||
// jalr rd, offset, rd1
|
||||
// For JAL, restore the stack before doing the jump
|
||||
class riscv_jump_instr extends riscv_rand_instr_stream;
|
||||
class riscv_jump_instr extends riscv_directed_instr_stream;
|
||||
|
||||
riscv_instr_base jump;
|
||||
riscv_instr_base addi;
|
||||
|
@ -168,8 +125,11 @@ class riscv_jump_instr extends riscv_rand_instr_stream;
|
|||
riscv_instr_base instr[];
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(jump,
|
||||
(use_jalr) -> (instr_name == JALR);
|
||||
instr_name dist {JAL := 1, JALR := 9};
|
||||
rd == RA;
|
||||
instr_name dist {JAL := 2, JALR := 6, C_JALR := 2};
|
||||
if (cfg.disable_compressed_instr || (cfg.ra != RA)) {
|
||||
instr_name != C_JALR;
|
||||
}
|
||||
rd == cfg.ra;
|
||||
rs1 == gpr;
|
||||
)
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(addi,
|
||||
|
@ -198,6 +158,8 @@ class riscv_jump_instr extends riscv_rand_instr_stream;
|
|||
end
|
||||
if(jump.instr_name == JAL) begin
|
||||
jump.imm_str = target_program_label;
|
||||
end else if (jump.instr_name == C_JALR) begin
|
||||
instr = {la, instr};
|
||||
end else begin
|
||||
instr = {la, addi, instr};
|
||||
end
|
||||
|
@ -215,6 +177,78 @@ class riscv_jump_instr extends riscv_rand_instr_stream;
|
|||
endfunction
|
||||
endclass
|
||||
|
||||
// Stress back to back jump instruction
|
||||
class riscv_jal_instr extends riscv_rand_instr_stream;
|
||||
|
||||
riscv_instr_base jump[];
|
||||
riscv_instr_base jump_start;
|
||||
riscv_instr_base jump_end;
|
||||
rand int unsigned num_of_jump_instr;
|
||||
riscv_instr_name_t jal[];
|
||||
|
||||
constraint instr_c {
|
||||
num_of_jump_instr inside {[10:30]};
|
||||
}
|
||||
|
||||
`uvm_object_utils(riscv_jal_instr)
|
||||
|
||||
function new(string name = "");
|
||||
super.new(name);
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
int order[];
|
||||
order = new[num_of_jump_instr];
|
||||
jump = new[num_of_jump_instr];
|
||||
foreach (order[i]) begin
|
||||
order[i] = i;
|
||||
end
|
||||
order.shuffle();
|
||||
setup_allowed_instr(1, 1);
|
||||
jal = {JAL};
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
jal = (XLEN == 32) ? {jal, C_J, C_JAL} : {jal, C_J};
|
||||
end
|
||||
// First instruction
|
||||
jump_start = riscv_instr_base::type_id::create("jump_start");
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(jump_start,
|
||||
instr_name == JAL;
|
||||
rd == cfg.ra;
|
||||
)
|
||||
jump_start.imm_str = $sformatf("%0df", order[0]);
|
||||
jump_start.label = label;
|
||||
// Last instruction
|
||||
jump_end = riscv_instr_base::type_id::create("jump_end");
|
||||
randomize_instr(jump_end);
|
||||
jump_end.label = $sformatf("%0d", num_of_jump_instr);
|
||||
foreach (jump[i]) begin
|
||||
jump[i] = riscv_instr_base::type_id::create($sformatf("jump_%0d", i));
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(jump[i],
|
||||
instr_name inside {jal};
|
||||
rd dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
|
||||
!(rd inside {cfg.reserved_regs});
|
||||
)
|
||||
jump[i].label = $sformatf("%0d", i);
|
||||
end
|
||||
foreach (order[i]) begin
|
||||
if (i == num_of_jump_instr - 1) begin
|
||||
jump[order[i]].imm_str = $sformatf("%0df", num_of_jump_instr);
|
||||
end else begin
|
||||
if (order[i+1] > order[i]) begin
|
||||
jump[order[i]].imm_str = $sformatf("%0df", order[i+1]);
|
||||
end else begin
|
||||
jump[order[i]].imm_str = $sformatf("%0db", order[i+1]);
|
||||
end
|
||||
end
|
||||
end
|
||||
instr_list = {jump_start, jump, jump_end};
|
||||
foreach (instr_list[i]) begin
|
||||
instr_list[i].has_label = 1'b1;
|
||||
instr_list[i].atomic = 1'b1;
|
||||
end
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
// Push stack instruction stream
|
||||
class riscv_push_stack_instr extends riscv_rand_instr_stream;
|
||||
|
||||
|
@ -235,8 +269,8 @@ class riscv_push_stack_instr extends riscv_rand_instr_stream;
|
|||
|
||||
function void init();
|
||||
// Save RA, T0
|
||||
reserved_rd = {RA, T0};
|
||||
saved_regs = {RA, T0};
|
||||
reserved_rd = {cfg.ra};
|
||||
saved_regs = {cfg.ra};
|
||||
num_of_reg_to_save = saved_regs.size();
|
||||
if(num_of_reg_to_save * (XLEN/8) > stack_len) begin
|
||||
`uvm_fatal(get_full_name(), $sformatf("stack len [%0d] is not enough to store %d regs",
|
||||
|
@ -317,7 +351,7 @@ class riscv_pop_stack_instr extends riscv_rand_instr_stream;
|
|||
endfunction
|
||||
|
||||
function void init();
|
||||
reserved_rd = {RA, T0};
|
||||
reserved_rd = {cfg.ra};
|
||||
num_of_reg_to_save = saved_regs.size();
|
||||
if(num_of_reg_to_save * 4 > stack_len) begin
|
||||
`uvm_fatal(get_full_name(), $sformatf("stack len [%0d] is not enough to store %d regs",
|
||||
|
|
|
@ -25,6 +25,7 @@ class riscv_illegal_instr extends uvm_object;
|
|||
|
||||
typedef enum bit [2:0] {
|
||||
kIllegalOpcode,
|
||||
kIllegalCompressedOpcode,
|
||||
kIllegalFunc3,
|
||||
kIllegalFunc7,
|
||||
kReservedCompressedInstr,
|
||||
|
@ -44,6 +45,15 @@ class riscv_illegal_instr extends uvm_object;
|
|||
7'b1110011,
|
||||
7'b1101111};
|
||||
|
||||
// Default legal opcode for RV32C instructions
|
||||
bit [2:0] legal_c00_opcode[$] = '{3'b000,
|
||||
3'b010,
|
||||
3'b110};
|
||||
bit [2:0] legal_c10_opcode[$] = '{3'b000,
|
||||
3'b010,
|
||||
3'b100,
|
||||
3'b110};
|
||||
|
||||
rand illegal_instr_type_e exception;
|
||||
rand bit [31:0] instr_bin;
|
||||
rand bit [6:0] opcode;
|
||||
|
@ -56,6 +66,17 @@ class riscv_illegal_instr extends uvm_object;
|
|||
rand bit [2:0] c_msb;
|
||||
riscv_instr_gen_config cfg;
|
||||
|
||||
constraint exception_dist_c {
|
||||
exception dist {
|
||||
kIllegalOpcode := 4,
|
||||
kIllegalCompressedOpcode := 1,
|
||||
kIllegalFunc3 := 1,
|
||||
kIllegalFunc7 := 1,
|
||||
kReservedCompressedInstr := 1,
|
||||
kHintInstr := 3
|
||||
};
|
||||
}
|
||||
|
||||
constraint instr_bit_assignment_c {
|
||||
solve opcode before instr_bin;
|
||||
solve func3 before instr_bin;
|
||||
|
@ -76,9 +97,19 @@ class riscv_illegal_instr extends uvm_object;
|
|||
}
|
||||
}
|
||||
|
||||
constraint legal_rv32_c_slli {
|
||||
if ((c_msb == 3'b000) && (c_op == 2'b10) && (XLEN == 32)) {
|
||||
if (exception == kReservedCompressedInstr) {
|
||||
instr_bin[12] == 1;
|
||||
} else {
|
||||
instr_bin[12] == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constraint exception_type_c {
|
||||
if (compressed) {
|
||||
exception inside {kReservedCompressedInstr, kHintInstr};
|
||||
exception inside {kReservedCompressedInstr, kIllegalCompressedOpcode, kHintInstr};
|
||||
} else {
|
||||
exception inside {kIllegalOpcode, kIllegalFunc3, kIllegalFunc7};
|
||||
}
|
||||
|
@ -94,14 +125,31 @@ class riscv_illegal_instr extends uvm_object;
|
|||
c_op != 2'b11;
|
||||
}
|
||||
|
||||
|
||||
constraint illegal_compressed_op_c {
|
||||
if (exception == kIllegalCompressedOpcode) {
|
||||
c_op != 2'b01;
|
||||
if (legal_c00_opcode.size() == 8) {
|
||||
c_op != 2'b00;
|
||||
} else {
|
||||
!(c_msb inside {legal_c00_opcode});
|
||||
}
|
||||
if (legal_c10_opcode.size() == 8) {
|
||||
c_op != 2'b10;
|
||||
} else {
|
||||
!(c_msb inside {legal_c10_opcode});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constraint reserved_compressed_instr_c {
|
||||
if (exception == kReservedCompressedInstr) {
|
||||
((instr_bin[15:5] == '0) && (c_op == 2'b00)) ||
|
||||
((c_msb == 3'b100) && (c_op == 2'b00)) ||
|
||||
((instr_bin[15:10] == 6'b100111) && (instr_bin[6:5] == 2'b10) && (c_op == 2'b01)) ||
|
||||
((instr_bin[15:10] == 6'b100111) && (instr_bin[6:5] == 2'b11) && (c_op == 2'b01)) ||
|
||||
((c_msb == 3'b001) && (c_op == 2'b01) && (instr_bin[11:7] == 5'b0) && (XLEN == 64)) ||
|
||||
((c_msb == 3'b011) && (c_op == 2'b01) && (instr_bin[12:2] == 11'h40)) ||
|
||||
// C_LUI, imm = 0
|
||||
((c_msb == 3'b011) && (c_op == 2'b01) && !instr_bin[12] && (instr_bin[6:2] == 0)) ||
|
||||
((c_msb == 3'b001) && (c_op == 2'b10) && (instr_bin[11:7] == 5'b0)) ||
|
||||
((c_msb == 3'b010) && (c_op == 2'b10) && (instr_bin[11:7] == 5'b0)) ||
|
||||
((c_msb == 3'b011) && (c_op == 2'b10) && (instr_bin[11:7] == 5'b0)) ||
|
||||
|
@ -118,6 +166,9 @@ class riscv_illegal_instr extends uvm_object;
|
|||
// C.SRAI64, C.SRLI64
|
||||
((c_msb == 3'b100) && (c_op == 2'b01) && (instr_bin[12:11] == 2'b00) &&
|
||||
(instr_bin[6:2] == 5'b0)) ||
|
||||
// C.MV
|
||||
((c_msb == 3'b100) && (c_op == 2'b10) && (instr_bin[11:7] == 0) &&
|
||||
(instr_bin[6:2] != 0)) ||
|
||||
// C.LUI
|
||||
((c_msb == 3'b011) && (c_op == 2'b01) && (instr_bin[11:7] == 5'b0) &&
|
||||
({instr_bin[12], instr_bin[6:2]} != 6'b0)) ||
|
||||
|
@ -133,6 +184,7 @@ class riscv_illegal_instr extends uvm_object;
|
|||
}
|
||||
|
||||
constraint illegal_opcode_c {
|
||||
solve opcode before instr_bin;
|
||||
if (exception == kIllegalOpcode) {
|
||||
!(opcode inside {legal_opcode});
|
||||
opcode[1:0] == 2'b11;
|
||||
|
@ -233,6 +285,10 @@ class riscv_illegal_instr extends uvm_object;
|
|||
riscv_instr_pkg::RV64M inside {riscv_instr_pkg::supported_isa}) begin
|
||||
legal_opcode = {legal_opcode, 7'b0111011};
|
||||
end
|
||||
if (riscv_instr_pkg::RV64I inside {riscv_instr_pkg::supported_isa}) begin
|
||||
legal_c00_opcode = {legal_c00_opcode, 3'b011, 3'b111};
|
||||
legal_c10_opcode = {legal_c10_opcode, 3'b011, 3'b111};
|
||||
end
|
||||
endfunction
|
||||
|
||||
function string get_bin_str();
|
||||
|
|
77
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
77
vendor/google_riscv-dv/src/riscv_instr_base.sv
vendored
|
@ -132,16 +132,6 @@ class riscv_instr_base extends uvm_object;
|
|||
}
|
||||
}
|
||||
|
||||
// Registers specified by the three-bit rs1’, rs2’, and rd’ fields of the CIW, CL, CS,
|
||||
// and CB formats
|
||||
constraint compressed_three_bits_csr_c {
|
||||
if(format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT}) {
|
||||
rs1 inside {[S0:A5]};
|
||||
rs2 inside {[S0:A5]};
|
||||
rd inside {[S0:A5]};
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot shift more than the width of the bus
|
||||
constraint shift_imm_val_c {
|
||||
solve category before imm;
|
||||
|
@ -177,16 +167,21 @@ class riscv_instr_base extends uvm_object;
|
|||
}
|
||||
|
||||
constraint rvc_csr_c {
|
||||
// Registers specified by the three-bit rs1’, rs2’, and rd’ fields of the CIW, CL, CS,
|
||||
// and CB formats
|
||||
if(format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT}) {
|
||||
// Registers specified by the three-bit rs1’, rs2’, and rd’
|
||||
if(format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT, CA_FORMAT}) {
|
||||
rs1 inside {[S0:A5]};
|
||||
rs2 inside {[S0:A5]};
|
||||
rd inside {[S0:A5]};
|
||||
}
|
||||
// C_ADDI16SP is only valid when rd == SP
|
||||
if(instr_name == C_ADDI16SP) {
|
||||
rd == SP;
|
||||
rd == SP;
|
||||
rs1 == SP;
|
||||
}
|
||||
|
||||
if(instr_name inside {C_JR, C_JALR}) {
|
||||
rs2 == ZERO;
|
||||
rs1 != ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,21 +358,21 @@ class riscv_instr_base extends uvm_object;
|
|||
// RV32IC
|
||||
`add_instr(C_LW, CL_FORMAT, LOAD, RV32C, UIMM)
|
||||
`add_instr(C_SW, CS_FORMAT, STORE, RV32C, UIMM)
|
||||
`add_instr(C_LWSP, CI_FORMAT, LOAD, RV64C, UIMM)
|
||||
`add_instr(C_SWSP, CSS_FORMAT, STORE, RV64C, UIMM)
|
||||
`add_instr(C_LWSP, CI_FORMAT, LOAD, RV32C, UIMM)
|
||||
`add_instr(C_SWSP, CSS_FORMAT, STORE, RV32C, UIMM)
|
||||
`add_instr(C_ADDI4SPN, CIW_FORMAT, ARITHMETIC, RV32C, NZUIMM)
|
||||
`add_instr(C_ADDI, CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
|
||||
`add_instr(C_ADDI16SP, CI_FORMAT, ARITHMETIC, RV32C, NZIMM)
|
||||
`add_instr(C_LI, CI_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_LUI, CI_FORMAT, ARITHMETIC, RV32C, NZUIMM)
|
||||
`add_instr(C_SUB, CS_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_SUB, CA_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_ADD, CR_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_NOP, CI_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_MV, CR_FORMAT, ARITHMETIC, RV32C)
|
||||
`add_instr(C_ANDI, CB_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_XOR, CS_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_OR, CS_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_AND, CS_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_XOR, CA_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_OR, CA_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_AND, CA_FORMAT, LOGICAL, RV32C)
|
||||
`add_instr(C_BEQZ, CB_FORMAT, BRANCH, RV32C)
|
||||
`add_instr(C_BNEZ, CB_FORMAT, BRANCH, RV32C)
|
||||
`add_instr(C_SRLI, CB_FORMAT, SHIFT, RV32C, NZUIMM)
|
||||
|
@ -391,8 +386,8 @@ class riscv_instr_base extends uvm_object;
|
|||
|
||||
// RV64C
|
||||
`add_instr(C_ADDIW, CI_FORMAT, ARITHMETIC, RV64C)
|
||||
`add_instr(C_SUBW, CS_FORMAT, ARITHMETIC, RV64C)
|
||||
`add_instr(C_ADDW, CS_FORMAT, ARITHMETIC, RV64C)
|
||||
`add_instr(C_SUBW, CA_FORMAT, ARITHMETIC, RV64C)
|
||||
`add_instr(C_ADDW, CA_FORMAT, ARITHMETIC, RV64C)
|
||||
`add_instr(C_LD, CL_FORMAT, LOAD, RV64C, UIMM)
|
||||
`add_instr(C_SD, CS_FORMAT, STORE, RV64C, UIMM)
|
||||
`add_instr(C_LDSP, CI_FORMAT, LOAD, RV64C, UIMM)
|
||||
|
@ -461,10 +456,14 @@ class riscv_instr_base extends uvm_object;
|
|||
update_imm_str();
|
||||
end
|
||||
end
|
||||
if (format inside {R_FORMAT, S_FORMAT, B_FORMAT, CSS_FORMAT, CS_FORMAT, CR_FORMAT}) begin
|
||||
if (format inside {R_FORMAT, S_FORMAT, B_FORMAT, CSS_FORMAT,
|
||||
CS_FORMAT, CR_FORMAT, CA_FORMAT}) begin
|
||||
has_rs2 = 1'b1;
|
||||
end
|
||||
if (!(format inside {J_FORMAT, U_FORMAT, CJ_FORMAT, CSS_FORMAT, CR_FORMAT, CI_FORMAT})) begin
|
||||
if (!(format inside {J_FORMAT, U_FORMAT, CJ_FORMAT, CSS_FORMAT,
|
||||
CA_FORMAT, CR_FORMAT, CI_FORMAT})) begin
|
||||
has_rs1 = 1'b1;
|
||||
end else if (instr_name inside {C_JR, C_JALR}) begin
|
||||
has_rs1 = 1'b1;
|
||||
end
|
||||
if (!(format inside {CJ_FORMAT, CB_FORMAT, CS_FORMAT, CSS_FORMAT, B_FORMAT, S_FORMAT})) begin
|
||||
|
@ -557,18 +556,24 @@ class riscv_instr_base extends uvm_object;
|
|||
riscv_reg_t legal_gpr[$];
|
||||
if (included_reg.size() > 0) begin
|
||||
legal_gpr = included_reg;
|
||||
while (is_compressed && (i < legal_gpr.size())) begin
|
||||
if (legal_gpr[i] < S0 || legal_gpr[i] > A5) begin
|
||||
legal_gpr.delete(i);
|
||||
end else begin
|
||||
i++;
|
||||
if (is_compressed && !(format inside {CR_FORMAT, CI_FORMAT, CSS_FORMAT})) begin
|
||||
while (i < legal_gpr.size()) begin
|
||||
if (legal_gpr[i] < S0 || legal_gpr[i] > A5) begin
|
||||
legal_gpr.delete(i);
|
||||
end else begin
|
||||
i++;
|
||||
end
|
||||
end
|
||||
end
|
||||
end else if (is_compressed) begin
|
||||
end else if (is_compressed &&
|
||||
!(format inside {CR_FORMAT, CI_FORMAT, CSS_FORMAT})) begin
|
||||
legal_gpr = riscv_instr_pkg::compressed_gpr;
|
||||
end else begin
|
||||
legal_gpr = riscv_instr_pkg::all_gpr;
|
||||
end
|
||||
if (format inside {CR_FORMAT, CI_FORMAT}) begin
|
||||
excluded_reg = {excluded_reg, ZERO};
|
||||
end
|
||||
if (excluded_reg.size() > 0) begin
|
||||
i = 0;
|
||||
while (i < legal_gpr.size()) begin
|
||||
|
@ -710,6 +715,8 @@ class riscv_instr_base extends uvm_object;
|
|||
CI_FORMAT, CIW_FORMAT:
|
||||
if(instr_name == C_NOP)
|
||||
asm_str = "c.nop";
|
||||
else if(instr_name == C_ADDI16SP)
|
||||
asm_str = $sformatf("%0ssp, %0s", asm_str, get_imm());
|
||||
else
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm());
|
||||
CL_FORMAT:
|
||||
|
@ -719,12 +726,18 @@ class riscv_instr_base extends uvm_object;
|
|||
asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rs2.name(), get_imm(), rs1.name());
|
||||
else
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), rs2.name());
|
||||
CA_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name());
|
||||
CB_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), get_imm());
|
||||
CSS_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rs2.name(), get_imm());
|
||||
CR_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name());
|
||||
if (instr_name inside {C_JR, C_JALR}) begin
|
||||
asm_str = $sformatf("%0s%0s", asm_str, rs1.name());
|
||||
end else begin
|
||||
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name());
|
||||
end
|
||||
CJ_FORMAT:
|
||||
asm_str = $sformatf("%0s%0s", asm_str, get_imm());
|
||||
endcase
|
||||
|
@ -738,7 +751,7 @@ class riscv_instr_base extends uvm_object;
|
|||
// 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
|
||||
if(instr_name == EBREAK) begin
|
||||
asm_str = ".option norvc;ebreak;.option rvc;";
|
||||
asm_str = ".4byte 0x00100073 # ebreak";
|
||||
end else if(instr_name == C_EBREAK) begin
|
||||
asm_str = "c.ebreak;c.nop;";
|
||||
end
|
||||
|
|
|
@ -67,7 +67,7 @@ class riscv_instr_cov_item extends riscv_instr_base;
|
|||
if (category inside {LOAD, STORE}) begin
|
||||
unaligned_mem_access = is_unaligned_mem_access();
|
||||
if (unaligned_mem_access) begin
|
||||
`uvm_info(`gfn, $sformatf("Unaligned: %0s, mem_addr:%0x", instr_name.name(), mem_addr), UVM_LOW)
|
||||
`uvm_info(`gfn, $sformatf("Unaligned: %0s, mem_addr:%0x", instr_name.name(), mem_addr), UVM_HIGH)
|
||||
end
|
||||
end
|
||||
if (category == LOGICAL) begin
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
cp_rs1_sign : coverpoint instr.rs1_sign; \
|
||||
cp_rs2_sign : coverpoint instr.rs2_sign; \
|
||||
cp_rd_sign : coverpoint instr.rd_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard; \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard; \
|
||||
|
||||
`define CMP_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
|
@ -34,7 +34,7 @@
|
|||
cp_rd : coverpoint instr.rd; \
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign; \
|
||||
cp_result : coverpoint instr.rd_value[0]; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard; \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard; \
|
||||
|
||||
`define SB_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
|
@ -44,30 +44,34 @@
|
|||
cp_rs2_sign : coverpoint instr.rs2_sign; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_branch_hit : coverpoint instr.branch_hit; \
|
||||
cp_sign_cross : cross cp_rs1_sign, cp_rs2_sign, cp_imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_sign_cross : cross cp_rs1_sign, cp_rs2_sign; \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}
|
||||
|
||||
`define STORE_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rs1 : coverpoint instr.rs1; \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
ignore_bins zero = {ZERO}; \
|
||||
} \
|
||||
cp_rs2 : coverpoint instr.rs2; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
} \
|
||||
cp_lsu_harzard : coverpoint instr.lsu_hazard { \
|
||||
cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
|
||||
}
|
||||
|
||||
`define LOAD_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rs1 : coverpoint instr.rs1; \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
ignore_bins zero = {ZERO}; \
|
||||
} \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard; \
|
||||
cp_lsu_harzard : coverpoint instr.lsu_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard; \
|
||||
cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}
|
||||
|
||||
|
@ -78,41 +82,39 @@
|
|||
cp_rs1_sign : coverpoint instr.rs1_sign; \
|
||||
cp_rd_sign : coverpoint instr.rd_sign; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
|
||||
`define U_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_rd_sign : coverpoint instr.rd_sign; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
|
||||
|
||||
`define J_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_imm_lsb : coverpoint instr.imm[1:0]; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_rd_align : coverpoint instr.rd_value[1];
|
||||
|
||||
|
||||
`define CSR_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rs1 : coverpoint instr.rs1; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
|
||||
`define CR_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rs2 : coverpoint instr.rs2; \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_rs2_sign : coverpoint instr.rs2_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
|
||||
`define CI_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rd : coverpoint instr.rd; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
|
||||
}
|
||||
|
||||
|
@ -121,7 +123,7 @@
|
|||
cp_rs2 : coverpoint instr.rs2; \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_rs2_sign : coverpoint instr.rs2_sign; \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}
|
||||
|
||||
|
@ -129,50 +131,69 @@
|
|||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_rd : coverpoint instr.rd { \
|
||||
bins gpr[] = cp_rd with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
|
||||
}
|
||||
|
||||
`define CL_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_rd : coverpoint instr.rd { \
|
||||
bins gpr[] = cp_rd with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard; \
|
||||
cp_lsu_harzard : coverpoint instr.lsu_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard; \
|
||||
cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}
|
||||
|
||||
`define CL_SP_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rd : coverpoint instr.rd { \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
}
|
||||
|
||||
`define CS_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_rs2 : coverpoint instr.rs2 { \
|
||||
bins gpr[] = cp_rs2 with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
} \
|
||||
cp_lsu_harzard : coverpoint instr.lsu_hazard { \
|
||||
cp_lsu_hazard : coverpoint instr.lsu_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
|
||||
}
|
||||
|
||||
`define CS_SP_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rs2 : coverpoint instr.rs2 { \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
}
|
||||
|
||||
`define CA_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_rd : coverpoint instr.rd { \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_rs2 : coverpoint instr.rs2 { \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
|
||||
|
||||
`define CB_INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
`INSTR_CG_BEGIN(INSTR_NAME) \
|
||||
cp_imm_sign : coverpoint instr.imm_sign; \
|
||||
cp_rs1 : coverpoint instr.rs1 { \
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item))); \
|
||||
bins gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5}; \
|
||||
} \
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard { \
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard { \
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
|
||||
}
|
||||
|
||||
|
@ -208,11 +229,9 @@ class riscv_instr_cover_group;
|
|||
`CG_END
|
||||
|
||||
`U_INSTR_CG_BEGIN(lui)
|
||||
cp_sign_cross: cross cp_imm_sign, cp_rd_sign;
|
||||
`CG_END
|
||||
|
||||
`U_INSTR_CG_BEGIN(auipc)
|
||||
cp_sign_cross: cross cp_imm_sign, cp_rd_sign;
|
||||
`CG_END
|
||||
|
||||
// Shift instructions
|
||||
|
@ -233,7 +252,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(slli)
|
||||
|
@ -241,7 +260,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(srli)
|
||||
|
@ -249,7 +268,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
// Logical instructions
|
||||
|
@ -361,33 +380,39 @@ class riscv_instr_cover_group;
|
|||
`CG_END
|
||||
|
||||
`J_INSTR_CG_BEGIN(jalr)
|
||||
cp_rs1_eq_rd : coverpoint instr.rs1 iff (instr.rs1 == instr.rd);
|
||||
cp_rs1_ne_rd : coverpoint instr.rs1 iff (instr.rs1 != instr.rd);
|
||||
cp_rs1_link : coverpoint instr.rs1 {
|
||||
bins ra = {RA};
|
||||
bins t1 = {T1};
|
||||
bins non_link = default;
|
||||
}
|
||||
cp_rd_link : coverpoint instr.rd {
|
||||
bins ra = {RA};
|
||||
bins t1 = {T1};
|
||||
bins non_link = default;
|
||||
}
|
||||
cp_ras : cross cp_rs1_link, cp_rd_link;
|
||||
`CG_END
|
||||
|
||||
// CSR instructions
|
||||
`CSR_INSTR_CG_BEGIN(csrrw)
|
||||
cp_rs2 : coverpoint instr.rs1;
|
||||
cp_rs1 : coverpoint instr.rs1;
|
||||
`CG_END
|
||||
|
||||
`CSR_INSTR_CG_BEGIN(csrrs)
|
||||
cp_rs2 : coverpoint instr.rs1;
|
||||
cp_rs1 : coverpoint instr.rs1;
|
||||
`CG_END
|
||||
|
||||
`CSR_INSTR_CG_BEGIN(csrrc)
|
||||
cp_rs2 : coverpoint instr.rs1;
|
||||
cp_rs1 : coverpoint instr.rs1;
|
||||
`CG_END
|
||||
|
||||
`CSR_INSTR_CG_BEGIN(csrrwi)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
`CSR_INSTR_CG_BEGIN(csrrsi)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
`CSR_INSTR_CG_BEGIN(csrrci)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
covergroup rv32i_misc_cg with function sample(riscv_instr_cov_item instr);
|
||||
|
@ -521,7 +546,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(slliw)
|
||||
|
@ -529,7 +554,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(srliw)
|
||||
|
@ -537,7 +562,7 @@ class riscv_instr_cover_group;
|
|||
cp_rd : coverpoint instr.rd;
|
||||
cp_rs1_sign : coverpoint instr.rs1_sign;
|
||||
cp_rd_sign : coverpoint instr.rd_sign;
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard;
|
||||
`CG_END
|
||||
|
||||
`R_INSTR_CG_BEGIN(addw)
|
||||
|
@ -557,13 +582,13 @@ class riscv_instr_cover_group;
|
|||
`CL_INSTR_CG_BEGIN(c_lw)
|
||||
`CG_END
|
||||
|
||||
`CL_INSTR_CG_BEGIN(c_lwsp)
|
||||
`CL_SP_INSTR_CG_BEGIN(c_lwsp)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_sw)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_swsp)
|
||||
`CS_SP_INSTR_CG_BEGIN(c_swsp)
|
||||
`CG_END
|
||||
|
||||
`CIW_INSTR_CG_BEGIN(c_addi4spn)
|
||||
|
@ -572,16 +597,23 @@ class riscv_instr_cover_group;
|
|||
`CI_INSTR_CG_BEGIN(c_addi)
|
||||
`CG_END
|
||||
|
||||
`CI_INSTR_CG_BEGIN(c_addi16sp)
|
||||
`INSTR_CG_BEGIN(c_addi16sp)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD};
|
||||
}
|
||||
`CG_END
|
||||
|
||||
`CI_INSTR_CG_BEGIN(c_li)
|
||||
`CG_END
|
||||
|
||||
`CI_INSTR_CG_BEGIN(c_lui)
|
||||
`INSTR_CG_BEGIN(c_lui)
|
||||
cp_rd : coverpoint instr.rd {
|
||||
ignore_bins bin = {ZERO, SP};
|
||||
}
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_sub)
|
||||
`CA_INSTR_CG_BEGIN(c_sub)
|
||||
`CG_END
|
||||
|
||||
`CR_INSTR_CG_BEGIN(c_add)
|
||||
|
@ -591,46 +623,35 @@ class riscv_instr_cover_group;
|
|||
`CG_END
|
||||
|
||||
`CB_INSTR_CG_BEGIN(c_andi)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_xor)
|
||||
`CA_INSTR_CG_BEGIN(c_xor)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_or)
|
||||
`CA_INSTR_CG_BEGIN(c_or)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_and)
|
||||
`CA_INSTR_CG_BEGIN(c_and)
|
||||
`CG_END
|
||||
|
||||
`CB_INSTR_CG_BEGIN(c_beqz)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
`CB_INSTR_CG_BEGIN(c_bnez)
|
||||
cp_imm_sign : coverpoint instr.imm_sign;
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(c_srli)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item)));
|
||||
}
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
|
||||
}
|
||||
`CB_INSTR_CG_BEGIN(c_srli)
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(c_srai)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item)));
|
||||
}
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
|
||||
}
|
||||
`CB_INSTR_CG_BEGIN(c_srai)
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(c_slli)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item)));
|
||||
}
|
||||
cp_gpr_harzard : coverpoint instr.gpr_hazard {
|
||||
cp_rd : coverpoint instr.rd;
|
||||
cp_gpr_hazard : coverpoint instr.gpr_hazard {
|
||||
bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
|
||||
}
|
||||
`CG_END
|
||||
|
@ -641,10 +662,17 @@ class riscv_instr_cover_group;
|
|||
`CJ_INSTR_CG_BEGIN(c_jal)
|
||||
`CG_END
|
||||
|
||||
`CR_INSTR_CG_BEGIN(c_jr)
|
||||
`INSTR_CG_BEGIN(c_jr)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
ignore_bins zero = {ZERO};
|
||||
}
|
||||
`CG_END
|
||||
|
||||
`CR_INSTR_CG_BEGIN(c_jalr)
|
||||
`INSTR_CG_BEGIN(c_jalr)
|
||||
cp_rs1 : coverpoint instr.rs1 {
|
||||
ignore_bins zero = {ZERO};
|
||||
}
|
||||
cp_rd_align : coverpoint instr.rd_value[1];
|
||||
`CG_END
|
||||
|
||||
// RV64C
|
||||
|
@ -652,22 +680,22 @@ class riscv_instr_cover_group;
|
|||
`CL_INSTR_CG_BEGIN(c_ld)
|
||||
`CG_END
|
||||
|
||||
`CL_INSTR_CG_BEGIN(c_ldsp)
|
||||
`CL_SP_INSTR_CG_BEGIN(c_ldsp)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_sd)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_sdsp)
|
||||
`CS_SP_INSTR_CG_BEGIN(c_sdsp)
|
||||
`CG_END
|
||||
|
||||
`CI_INSTR_CG_BEGIN(c_addiw)
|
||||
`CG_END
|
||||
|
||||
`CS_INSTR_CG_BEGIN(c_subw)
|
||||
`CA_INSTR_CG_BEGIN(c_subw)
|
||||
`CG_END
|
||||
|
||||
`CR_INSTR_CG_BEGIN(c_addw)
|
||||
`CA_INSTR_CG_BEGIN(c_addw)
|
||||
`CG_END
|
||||
|
||||
`INSTR_CG_BEGIN(hint)
|
||||
|
@ -697,10 +725,9 @@ class riscv_instr_cover_group;
|
|||
`CG_END
|
||||
|
||||
// Cover all illegal instruction
|
||||
covergroup illegal_cg with function sample(bit [31:0] binary);
|
||||
covergroup illegal_compressed_instr_cg with function sample(bit [31:0] binary);
|
||||
cp_point : coverpoint binary {
|
||||
wildcard bins c_addi4spn = {32'bxxxx_xxxxx_0000_0000_000x_xx00};
|
||||
wildcard bins c_addiw = {32'bxxxx_xxxxx_001x_0000_0xxx_xx01};
|
||||
wildcard bins c_addi16sp = {32'bxxxx_xxxxx_0110_0001_0000_0001};
|
||||
wildcard bins c_lui = {32'bxxxx_xxxxx_0110_xxxx_1000_0001,
|
||||
32'bxxxx_xxxxx_0110_xx1x_x000_0001,
|
||||
|
@ -766,7 +793,7 @@ class riscv_instr_cover_group;
|
|||
}
|
||||
endgroup
|
||||
|
||||
covergroup mepc_cg with function sample(bit [XLEN-1:0] val);
|
||||
covergroup mepc_alignment_cg with function sample(bit [XLEN-1:0] val);
|
||||
cp_align: coverpoint val[1:0] {
|
||||
bins alignment[] = {2'b00, 2'b10};
|
||||
}
|
||||
|
@ -783,7 +810,6 @@ class riscv_instr_cover_group;
|
|||
cur_instr = riscv_instr_cov_item::type_id::create("cur_instr");
|
||||
pre_instr = riscv_instr_cov_item::type_id::create("pre_instr");
|
||||
build_instr_list();
|
||||
hint_cg = new();
|
||||
// RV32I instruction functional coverage instantiation
|
||||
add_cg = new();
|
||||
sub_cg = new();
|
||||
|
@ -831,9 +857,14 @@ class riscv_instr_cover_group;
|
|||
// instr_trans_cg = new();
|
||||
branch_hit_history_cg = new();
|
||||
rv32i_misc_cg = new();
|
||||
illegal_cg = new();
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
illegal_compressed_instr_cg = new();
|
||||
end
|
||||
opcode_cg = new();
|
||||
compressed_opcode_cg = new();
|
||||
if (RV32C inside {supported_isa}) begin
|
||||
compressed_opcode_cg = new();
|
||||
hint_cg = new();
|
||||
end
|
||||
if (RV32M inside {supported_isa}) begin
|
||||
mul_cg = new();
|
||||
mulh_cg = new();
|
||||
|
@ -842,6 +873,7 @@ class riscv_instr_cover_group;
|
|||
div_cg = new();
|
||||
divu_cg = new();
|
||||
rem_cg = new();
|
||||
remu_cg = new();
|
||||
end
|
||||
if (RV64M inside {supported_isa}) begin
|
||||
mulw_cg = new();
|
||||
|
@ -890,7 +922,9 @@ class riscv_instr_cover_group;
|
|||
c_srai_cg = new();
|
||||
c_slli_cg = new();
|
||||
c_j_cg = new();
|
||||
c_jal_cg = new();
|
||||
if (XLEN == 32) begin
|
||||
c_jal_cg = new();
|
||||
end
|
||||
c_jr_cg = new();
|
||||
c_jalr_cg = new();
|
||||
end
|
||||
|
@ -906,7 +940,9 @@ class riscv_instr_cover_group;
|
|||
privileged_csr_cg = new();
|
||||
mcause_exception_cg = new();
|
||||
mcause_interrupt_cg = new();
|
||||
mepc_cg = new();
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
mepc_alignment_cg = new();
|
||||
end
|
||||
mstatus_m_cg = new();
|
||||
endfunction
|
||||
|
||||
|
@ -915,10 +951,11 @@ class riscv_instr_cover_group;
|
|||
if (instr_cnt > 1) begin
|
||||
instr.check_hazard_condition(pre_instr);
|
||||
end
|
||||
if (instr.binary[1:0] != 2'b11) begin
|
||||
if ((instr.binary[1:0] != 2'b11) && (RV32C inside {supported_isa})) begin
|
||||
hint_cg.sample(instr);
|
||||
compressed_opcode_cg.sample(instr.binary[15:0]);
|
||||
end else begin
|
||||
end
|
||||
if (instr.binary[1:0] == 2'b11) begin
|
||||
opcode_cg.sample(instr.binary[6:2]);
|
||||
end
|
||||
case (instr.instr_name)
|
||||
|
@ -943,13 +980,11 @@ class riscv_instr_cover_group;
|
|||
end
|
||||
end
|
||||
SRAI : begin
|
||||
slli_cg.sample(instr);
|
||||
srai_cg.sample(instr);
|
||||
if (RV64I inside {supported_isa}) begin
|
||||
slli64_cg.sample(instr);
|
||||
srai64_cg.sample(instr);
|
||||
end
|
||||
end
|
||||
SRLI : srli_cg.sample(instr);
|
||||
SRAI : srai_cg.sample(instr);
|
||||
AND : and_cg.sample(instr);
|
||||
OR : or_cg.sample(instr);
|
||||
XOR : xor_cg.sample(instr);
|
||||
|
@ -989,6 +1024,7 @@ class riscv_instr_cover_group;
|
|||
DIV : div_cg.sample(instr);
|
||||
DIVU : divu_cg.sample(instr);
|
||||
REM : rem_cg.sample(instr);
|
||||
REMU : remu_cg.sample(instr);
|
||||
MULW : mulw_cg.sample(instr);
|
||||
DIVW : divw_cg.sample(instr);
|
||||
DIVUW : divuw_cg.sample(instr);
|
||||
|
@ -1039,7 +1075,9 @@ class riscv_instr_cover_group;
|
|||
C_ADDW : c_addw_cg.sample(instr);
|
||||
C_ADDIW : c_addiw_cg.sample(instr);
|
||||
default: begin
|
||||
illegal_cg.sample(instr.binary);
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
illegal_compressed_instr_cg.sample(instr.binary);
|
||||
end
|
||||
if (instr.group == RV32I) begin
|
||||
rv32i_misc_cg.sample(instr);
|
||||
end
|
||||
|
@ -1068,7 +1106,11 @@ class riscv_instr_cover_group;
|
|||
end
|
||||
end
|
||||
end
|
||||
MEPC: mepc_cg.sample(instr.rd_value);
|
||||
MEPC: begin
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
mepc_alignment_cg.sample(instr.rd_value);
|
||||
end
|
||||
end
|
||||
MSTATUS: begin
|
||||
mstatus_m_cg.sample(instr.rd_value);
|
||||
end
|
||||
|
|
|
@ -76,6 +76,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
// Use a random register for stack pointer/thread pointer
|
||||
rand riscv_reg_t sp;
|
||||
rand riscv_reg_t tp;
|
||||
rand riscv_reg_t ra;
|
||||
|
||||
// Options for privileged mode CSR checking
|
||||
// Below checking can be made optional as the ISS implementation could be different with the
|
||||
|
@ -324,8 +325,16 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
}
|
||||
}
|
||||
|
||||
constraint ra_c {
|
||||
ra dist {RA := 5, T1 := 2, [SP:T0] :/ 1, [T2:T6] :/ 2};
|
||||
ra != sp;
|
||||
ra != tp;
|
||||
ra != ZERO;
|
||||
}
|
||||
|
||||
constraint sp_tp_c {
|
||||
sp != tp;
|
||||
sp dist {SP := 6, RA := 1, [GP:T6] :/ 3};
|
||||
!(sp inside {GP, RA, ZERO});
|
||||
!(tp inside {GP, RA, ZERO});
|
||||
}
|
||||
|
@ -437,6 +446,9 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
end
|
||||
end
|
||||
end
|
||||
if (!(RV32C inside {supported_isa})) begin
|
||||
disable_compressed_instr = 1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Initialize the exception/interrupt delegation associate array, set all delegation default to 0
|
||||
|
|
|
@ -348,6 +348,7 @@ package riscv_instr_pkg;
|
|||
CB_FORMAT,
|
||||
CJ_FORMAT,
|
||||
CR_FORMAT,
|
||||
CA_FORMAT,
|
||||
CL_FORMAT,
|
||||
CS_FORMAT,
|
||||
CSS_FORMAT,
|
||||
|
|
|
@ -278,7 +278,11 @@ class riscv_instr_sequence extends uvm_sequence;
|
|||
insert_illegal_hint_instr();
|
||||
prefix = format_string($sformatf("%0d:", i), LABEL_STR_LEN);
|
||||
if(!is_main_program) begin
|
||||
str = {prefix, "ret"};
|
||||
if (!cfg.disable_compressed_instr) begin
|
||||
str = {prefix, $sformatf("c.jr x%0d", cfg.ra)};
|
||||
end else begin
|
||||
str = {prefix, $sformatf("jalr x0, x%0d, 0", cfg.ra)};
|
||||
end
|
||||
instr_string_list.push_back(str);
|
||||
end
|
||||
endfunction
|
||||
|
|
|
@ -116,10 +116,10 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
|
|||
// Assign the allowed load/store instructions based on address alignment
|
||||
// This is done separately rather than a constraint to improve the randomization performance
|
||||
allowed_instr = {LB, LBU, SB};
|
||||
if (addr[i][0] == 1'b0) begin
|
||||
allowed_instr = {LH, LHU, SH, allowed_instr};
|
||||
end
|
||||
if (!cfg.enable_unaligned_load_store) begin
|
||||
if (addr[i][0] == 1'b0) begin
|
||||
allowed_instr = {LH, LHU, SH, allowed_instr};
|
||||
end
|
||||
if (addr[i] % 4 == 0) begin
|
||||
allowed_instr = {LW, SW, allowed_instr};
|
||||
if (cfg.enable_floating_point) begin
|
||||
|
@ -149,7 +149,7 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream;
|
|||
end
|
||||
end
|
||||
end else begin
|
||||
allowed_instr = {LW, SW, allowed_instr};
|
||||
allowed_instr = {LW, SW, LH, LHU, SH, allowed_instr};
|
||||
if ((offset[i] inside {[0:127]}) && (offset[i] % 4 == 0) &&
|
||||
(RV32C inside {riscv_instr_pkg::supported_isa}) &&
|
||||
enable_compressed_load_store) begin
|
||||
|
|
61
vendor/google_riscv-dv/src/riscv_loop_instr.sv
vendored
61
vendor/google_riscv-dv/src/riscv_loop_instr.sv
vendored
|
@ -44,7 +44,6 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
|
|||
}
|
||||
}
|
||||
foreach (loop_limit_reg[i]) {
|
||||
loop_limit_reg[i] != ZERO;
|
||||
foreach (cfg.reserved_regs[j]) {
|
||||
loop_limit_reg[i] != cfg.reserved_regs[j];
|
||||
}
|
||||
|
@ -58,34 +57,54 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
|
|||
solve num_of_nested_loop before loop_init_val;
|
||||
solve num_of_nested_loop before loop_step_val;
|
||||
solve num_of_nested_loop before loop_limit_val;
|
||||
num_of_instr_in_loop inside {[1:200]};
|
||||
solve loop_limit_val before loop_limit_reg;
|
||||
solve branch_type before loop_init_val;
|
||||
solve branch_type before loop_step_val;
|
||||
solve branch_type before loop_limit_val;
|
||||
num_of_instr_in_loop inside {[1:25]};
|
||||
num_of_nested_loop inside {[1:2]};
|
||||
loop_init_val.size() == num_of_nested_loop;
|
||||
loop_step_val.size() == num_of_nested_loop;
|
||||
loop_limit_val.size() == num_of_nested_loop;
|
||||
branch_type.size() == num_of_nested_loop;
|
||||
foreach (branch_type[i]) {
|
||||
if (!cfg.disable_compressed_instr) {
|
||||
branch_type[i] inside {C_BNEZ, C_BEQZ, BEQ, BNE, BLTU, BLT, BGEU, BGE};
|
||||
} else {
|
||||
branch_type[i] inside {BEQ, BNE, BLTU, BLT, BGEU, BGE};
|
||||
}
|
||||
}
|
||||
foreach(loop_init_val[i]) {
|
||||
if (branch_type[i] inside {C_BNEZ, C_BEQZ}) {
|
||||
loop_limit_val[i] == 0;
|
||||
loop_limit_reg[i] == ZERO;
|
||||
loop_cnt_reg[i] inside {riscv_instr_pkg::compressed_gpr};
|
||||
} else {
|
||||
loop_limit_val[i] inside {[-20:20]};
|
||||
loop_limit_reg[i] != ZERO;
|
||||
}
|
||||
if (branch_type[i] inside {C_BNEZ, C_BEQZ, BEQ, BNE}) {
|
||||
((loop_limit_val[i] - loop_init_val[i]) % loop_step_val[i] == 0) &&
|
||||
(loop_limit_val[i] != loop_init_val[i]);
|
||||
} else if (branch_type[i] == BGE) {
|
||||
loop_step_val[i] < 0;
|
||||
} else if (branch_type[i] == BGEU) {
|
||||
loop_step_val[i] < 0;
|
||||
loop_init_val[i] > 0;
|
||||
// Avoid count to negative
|
||||
loop_step_val[i] + loop_limit_val[i] > 0;
|
||||
} else if (branch_type[i] == BLT) {
|
||||
loop_step_val[i] > 0;
|
||||
} else if (branch_type[i] == BLTU) {
|
||||
loop_step_val[i] > 0;
|
||||
loop_limit_val[i] > 0;
|
||||
}
|
||||
loop_init_val[i] inside {[-10:10]};
|
||||
loop_limit_val[i] inside {[-20:20]};
|
||||
loop_step_val[i] inside {[-10:10]};
|
||||
loop_step_val[i] != 0;
|
||||
if(loop_init_val[i] < loop_limit_val[i]) {
|
||||
loop_step_val[i] > 0;
|
||||
loop_step_val[i] > 0;
|
||||
} else {
|
||||
loop_step_val[i] < 0;
|
||||
}
|
||||
// Select a reasonable branch instruction to avoid inifint loop
|
||||
if(loop_init_val[i] < 0 || (loop_limit_val[i] + loop_step_val[i]) < 0) {
|
||||
!(branch_type[i] inside {BLTU, BGEU});
|
||||
}
|
||||
if(((loop_limit_val[i] - loop_init_val[i]) % loop_step_val[i] != 0) ||
|
||||
(loop_limit_val[i] == loop_init_val[i])) {
|
||||
!(branch_type[i] inside {BEQ, BNE});
|
||||
}
|
||||
if(loop_step_val[i] > 0) {
|
||||
branch_type[i] inside {BLTU, BNE, BLT, BEQ};
|
||||
} else {
|
||||
branch_type[i] inside {BGEU, BNE, BGE, BEQ};
|
||||
loop_step_val[i] < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +167,9 @@ class riscv_loop_instr extends riscv_rand_instr_stream;
|
|||
`DV_CHECK_RANDOMIZE_WITH_FATAL(loop_branch_instr[i],
|
||||
instr_name == branch_type[i];
|
||||
rs1 == loop_cnt_reg[i];
|
||||
rs2 == loop_limit_reg[i];,
|
||||
if (!(branch_type[i] inside {C_BEQZ, C_BNEZ})) {
|
||||
rs2 == loop_limit_reg[i];
|
||||
},
|
||||
"Cannot randomize backward branch instruction")
|
||||
loop_branch_instr[i].comment = $sformatf("branch for loop %0d", i);
|
||||
loop_branch_instr[i].imm_str = loop_branch_target_instr[i].label;
|
||||
|
|
|
@ -390,7 +390,7 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
|
|||
instr.push_back($sformatf("csrr x%0d, 0x%0x", tmp_reg, MSTATUS));
|
||||
instr.push_back($sformatf("and x%0d, x%0d, x%0d", tmp_reg, tmp_reg, mask_reg));
|
||||
instr.push_back($sformatf("beqz x%0d, j_smode", tmp_reg));
|
||||
instr.push_back("jal ra, smode_ls_umem_program");
|
||||
instr.push_back("jal ra, smode_lsu_program");
|
||||
instr.push_back("j fix_pte_ret");
|
||||
instr.push_back("j_smode: jal ra, smode_program");
|
||||
instr.push_back("fix_pte_ret:");
|
||||
|
|
21
vendor/google_riscv-dv/target/rv32i/riscvOVPsim.ic
vendored
Normal file
21
vendor/google_riscv-dv/target/rv32i/riscvOVPsim.ic
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# riscOVPsim configuration file converted from YAML
|
||||
--variant RVB32I
|
||||
--override riscvOVPsim/cpu/misa_MXL=1
|
||||
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/unaligned=T
|
||||
--override riscvOVPsim/cpu/mtvec_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/mtvec_is_ro=T
|
||||
--override riscvOVPsim/cpu/mtvec=0x80000081 # 2147483777
|
||||
--override riscvOVPsim/cpu/user_version=2.3
|
||||
--override riscvOVPsim/cpu/priv_version=1.11
|
||||
--override riscvOVPsim/cpu/mvendorid=0
|
||||
--override riscvOVPsim/cpu/marchid=0
|
||||
--override riscvOVPsim/cpu/mimpid=0
|
||||
--override riscvOVPsim/cpu/mhartid=0
|
||||
--override riscvOVPsim/cpu/cycle_undefined=F
|
||||
--override riscvOVPsim/cpu/instret_undefined=F
|
||||
--override riscvOVPsim/cpu/time_undefined=T
|
||||
--override riscvOVPsim/cpu/nmi_address=0x800000fc # 2147483900
|
||||
--override riscvOVPsim/cpu/reset_address=0x80000000
|
||||
--override riscvOVPsim/cpu/simulateexceptions=T
|
104
vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
vendored
Normal file
104
vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor feature configuration
|
||||
//-----------------------------------------------------------------------------
|
||||
// XLEN
|
||||
parameter int XLEN = 32;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = BARE;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[];
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I};
|
||||
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
||||
// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is
|
||||
// supported
|
||||
int max_interrupt_vector_num = 16;
|
||||
|
||||
// Debug mode support
|
||||
bit support_debug_mode = 0;
|
||||
|
||||
// Support delegate trap to user mode
|
||||
bit support_umode_trap = 0;
|
||||
|
||||
// Support sfence.vma instruction
|
||||
bit support_sfence = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Implemented previlieged CSR list
|
||||
`ifdef DSIM
|
||||
privileged_reg_t implemented_csr[] = {
|
||||
`else
|
||||
parameter privileged_reg_t implemented_csr[] = {
|
||||
`endif
|
||||
// Machine mode mode CSR
|
||||
MVENDORID, // Vendor ID
|
||||
MARCHID, // Architecture ID
|
||||
MIMPID, // Implementation ID
|
||||
MHARTID, // Hardware thread ID
|
||||
MSTATUS, // Machine status
|
||||
MISA, // ISA and extensions
|
||||
MIE, // Machine interrupt-enable register
|
||||
MTVEC, // Machine trap-handler base address
|
||||
MCOUNTEREN, // Machine counter enable
|
||||
MSCRATCH, // Scratch register for machine trap handlers
|
||||
MEPC, // Machine exception program counter
|
||||
MCAUSE, // Machine trap cause
|
||||
MTVAL, // Machine bad address or instruction
|
||||
MIP // Machine interrupt pending
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supported interrupt/exception setting, used for functional coverage
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
`ifdef DSIM
|
||||
interrupt_cause_t implemented_interrupt[] = {
|
||||
`else
|
||||
parameter interrupt_cause_t implemented_interrupt[] = {
|
||||
`endif
|
||||
M_SOFTWARE_INTR,
|
||||
M_TIMER_INTR,
|
||||
M_EXTERNAL_INTR
|
||||
};
|
||||
|
||||
`ifdef DSIM
|
||||
exception_cause_t implemented_exception[] = {
|
||||
`else
|
||||
parameter exception_cause_t implemented_exception[] = {
|
||||
`endif
|
||||
INSTRUCTION_ADDRESS_MISALIGNED,
|
||||
INSTRUCTION_ACCESS_FAULT,
|
||||
ILLEGAL_INSTRUCTION,
|
||||
BREAKPOINT,
|
||||
LOAD_ADDRESS_MISALIGNED,
|
||||
LOAD_ACCESS_FAULT,
|
||||
ECALL_MMODE
|
||||
};
|
197
vendor/google_riscv-dv/target/rv32i/testlist.yaml
vendored
Normal file
197
vendor/google_riscv-dv/target/rv32i/testlist.yaml
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
# Copyright 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.
|
||||
|
||||
# ================================================================================
|
||||
# Regression test list format
|
||||
# --------------------------------------------------------------------------------
|
||||
# test : Assembly test name
|
||||
# description : Description of this test
|
||||
# gen_opts : Instruction generator options
|
||||
# iterations : Number of iterations of this test
|
||||
# no_iss : Enable/disable ISS simulator (Optional)
|
||||
# gen_test : Test name used by the instruction generator
|
||||
# rtl_test : RTL simulation test name
|
||||
# cmp_opts : Compile options passed to the instruction generator
|
||||
# sim_opts : Simulation options passed to the instruction generator
|
||||
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# gcc_opts : gcc compile options
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
- test: riscv_arithmetic_basic_test
|
||||
description: >
|
||||
Arithmetic instruction test, no load/store/branch instructions
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=0
|
||||
+no_fence=1
|
||||
+no_data_page=1
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_rand_instr_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,4
|
||||
+directed_instr_1=riscv_loop_instr,4
|
||||
+directed_instr_2=riscv_hazard_instr_stream,4
|
||||
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
|
||||
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
|
||||
+directed_instr_5=riscv_mem_region_stress_test,4
|
||||
+directed_instr_6=riscv_jal_instr,4
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_jump_stress_test
|
||||
description: >
|
||||
Stress back-to-back jump instruction test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_jal_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_loop_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_loop_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_rand_jump_test
|
||||
description: >
|
||||
Jump among large number of sub-programs, stress testing iTLB operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=20
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,8
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_mmu_stress_test
|
||||
description: >
|
||||
Test with different patterns of load/store instructions, stress test MMU
|
||||
operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,40
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
|
||||
+directed_instr_3=riscv_mem_region_stress_test,10
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_no_fence_test
|
||||
description: >
|
||||
Random instruction with FENCE disabled, used to test processor pipeline with
|
||||
less stall/flush operations caused by FENCE instruction.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+no_fence=1
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_illegal_instr_test
|
||||
description: >
|
||||
Illegal instruction test, verify the processor can detect illegal
|
||||
instruction and handle corresponding exception properly. An exception
|
||||
handling routine is designed to resume execution after illegal
|
||||
instruction exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+illegal_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_test
|
||||
description: >
|
||||
Random instruction test with ebreak instruction enabled. Debug mode is not
|
||||
enabled for this test, processor should raise ebreak exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_debug_mode_test
|
||||
description: >
|
||||
Ebreak instruction test with debug mode enabled.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+require_signature_addr=1
|
||||
+enable_debug_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
- test: riscv_full_interrupt_test
|
||||
description: >
|
||||
Random instruction test with complete interrupt handling
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+enable_interrupt=1
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+enable_irq_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
# Please enable this test for your RTL simulation
|
||||
- test: riscv_csr_test
|
||||
description: >
|
||||
Test all CSR instructions on all implemented CSR registers
|
||||
iterations: 0
|
||||
no_iss: 1
|
||||
rtl_test: core_csr_test
|
||||
no_post_compare: 1
|
||||
|
||||
- test: riscv_unaligned_load_store_test
|
||||
description: >
|
||||
Unaligned load/store test
|
||||
iterations: 1
|
||||
gen_test: riscv_instr_base_test
|
||||
gcc_opts: >
|
||||
-mno-strict-align
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,20
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
|
||||
+directed_instr_3=riscv_mem_region_stress_test,5
|
||||
+enable_unaligned_load_store=1
|
||||
rtl_test: core_base_test
|
22
vendor/google_riscv-dv/target/rv32imc/riscvOVPsim.ic
vendored
Normal file
22
vendor/google_riscv-dv/target/rv32imc/riscvOVPsim.ic
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
# riscOVPsim configuration file converted from YAML
|
||||
--variant RVB32I
|
||||
--override riscvOVPsim/cpu/add_Extensions=MC
|
||||
--override riscvOVPsim/cpu/misa_MXL=1
|
||||
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/unaligned=T
|
||||
--override riscvOVPsim/cpu/mtvec_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/mtvec_is_ro=T
|
||||
--override riscvOVPsim/cpu/mtvec=0x80000081 # 2147483777
|
||||
--override riscvOVPsim/cpu/user_version=2.3
|
||||
--override riscvOVPsim/cpu/priv_version=1.11
|
||||
--override riscvOVPsim/cpu/mvendorid=0
|
||||
--override riscvOVPsim/cpu/marchid=0
|
||||
--override riscvOVPsim/cpu/mimpid=0
|
||||
--override riscvOVPsim/cpu/mhartid=0
|
||||
--override riscvOVPsim/cpu/cycle_undefined=F
|
||||
--override riscvOVPsim/cpu/instret_undefined=F
|
||||
--override riscvOVPsim/cpu/time_undefined=T
|
||||
--override riscvOVPsim/cpu/nmi_address=0x800000fc # 2147483900
|
||||
--override riscvOVPsim/cpu/reset_address=0x80000000
|
||||
--override riscvOVPsim/cpu/simulateexceptions=T
|
104
vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
vendored
Normal file
104
vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor feature configuration
|
||||
//-----------------------------------------------------------------------------
|
||||
// XLEN
|
||||
parameter int XLEN = 32;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = BARE;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[];
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C};
|
||||
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
||||
// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is
|
||||
// supported
|
||||
int max_interrupt_vector_num = 16;
|
||||
|
||||
// Debug mode support
|
||||
bit support_debug_mode = 0;
|
||||
|
||||
// Support delegate trap to user mode
|
||||
bit support_umode_trap = 0;
|
||||
|
||||
// Support sfence.vma instruction
|
||||
bit support_sfence = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Implemented previlieged CSR list
|
||||
`ifdef DSIM
|
||||
privileged_reg_t implemented_csr[] = {
|
||||
`else
|
||||
parameter privileged_reg_t implemented_csr[] = {
|
||||
`endif
|
||||
// Machine mode mode CSR
|
||||
MVENDORID, // Vendor ID
|
||||
MARCHID, // Architecture ID
|
||||
MIMPID, // Implementation ID
|
||||
MHARTID, // Hardware thread ID
|
||||
MSTATUS, // Machine status
|
||||
MISA, // ISA and extensions
|
||||
MIE, // Machine interrupt-enable register
|
||||
MTVEC, // Machine trap-handler base address
|
||||
MCOUNTEREN, // Machine counter enable
|
||||
MSCRATCH, // Scratch register for machine trap handlers
|
||||
MEPC, // Machine exception program counter
|
||||
MCAUSE, // Machine trap cause
|
||||
MTVAL, // Machine bad address or instruction
|
||||
MIP // Machine interrupt pending
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supported interrupt/exception setting, used for functional coverage
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
`ifdef DSIM
|
||||
interrupt_cause_t implemented_interrupt[] = {
|
||||
`else
|
||||
parameter interrupt_cause_t implemented_interrupt[] = {
|
||||
`endif
|
||||
M_SOFTWARE_INTR,
|
||||
M_TIMER_INTR,
|
||||
M_EXTERNAL_INTR
|
||||
};
|
||||
|
||||
`ifdef DSIM
|
||||
exception_cause_t implemented_exception[] = {
|
||||
`else
|
||||
parameter exception_cause_t implemented_exception[] = {
|
||||
`endif
|
||||
INSTRUCTION_ADDRESS_MISALIGNED,
|
||||
INSTRUCTION_ACCESS_FAULT,
|
||||
ILLEGAL_INSTRUCTION,
|
||||
BREAKPOINT,
|
||||
LOAD_ADDRESS_MISALIGNED,
|
||||
LOAD_ACCESS_FAULT,
|
||||
ECALL_MMODE
|
||||
};
|
218
vendor/google_riscv-dv/target/rv32imc/testlist.yaml
vendored
Normal file
218
vendor/google_riscv-dv/target/rv32imc/testlist.yaml
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
# Copyright 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.
|
||||
|
||||
# ================================================================================
|
||||
# Regression test list format
|
||||
# --------------------------------------------------------------------------------
|
||||
# test : Assembly test name
|
||||
# description : Description of this test
|
||||
# gen_opts : Instruction generator options
|
||||
# iterations : Number of iterations of this test
|
||||
# no_iss : Enable/disable ISS simulator (Optional)
|
||||
# gen_test : Test name used by the instruction generator
|
||||
# rtl_test : RTL simulation test name
|
||||
# cmp_opts : Compile options passed to the instruction generator
|
||||
# sim_opts : Simulation options passed to the instruction generator
|
||||
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# gcc_opts : gcc compile options
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
- test: riscv_arithmetic_basic_test
|
||||
description: >
|
||||
Arithmetic instruction test, no load/store/branch instructions
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=0
|
||||
+no_fence=1
|
||||
+no_data_page=1
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_rand_instr_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,4
|
||||
+directed_instr_1=riscv_loop_instr,4
|
||||
+directed_instr_2=riscv_hazard_instr_stream,4
|
||||
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
|
||||
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
|
||||
+directed_instr_5=riscv_mem_region_stress_test,4
|
||||
+directed_instr_6=riscv_jal_instr,4
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_jump_stress_test
|
||||
description: >
|
||||
Back to back jump instruction test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_jal_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_loop_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_loop_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_non_compressed_instr_test
|
||||
description: >
|
||||
Random instruction test without compressed instructions
|
||||
iterations: 1
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+disable_compressed_instr=1
|
||||
gcc_opts: >
|
||||
-march=rv32im
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_rand_jump_test
|
||||
description: >
|
||||
Jump among large number of sub-programs, stress testing iTLB operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=20
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,8
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_mmu_stress_test
|
||||
description: >
|
||||
Test with different patterns of load/store instructions, stress test MMU
|
||||
operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,40
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
|
||||
+directed_instr_3=riscv_mem_region_stress_test,10
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_no_fence_test
|
||||
description: >
|
||||
Random instruction with FENCE disabled, used to test processor pipeline with
|
||||
less stall/flush operations caused by FENCE instruction.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+no_fence=1
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_illegal_instr_test
|
||||
description: >
|
||||
Illegal instruction test, verify the processor can detect illegal
|
||||
instruction and handle corresponding exception properly. An exception
|
||||
handling routine is designed to resume execution after illegal
|
||||
instruction exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+illegal_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_hint_instr_test
|
||||
description: >
|
||||
HINT instruction test, verify the processor can detect HINT instruction
|
||||
treat it as NOP. No illegal instruction exception is expected
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+hint_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_test
|
||||
description: >
|
||||
Random instruction test with ebreak instruction enabled. Debug mode is not
|
||||
enabled for this test, processor should raise ebreak exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_debug_mode_test
|
||||
description: >
|
||||
Ebreak instruction test with debug mode enabled.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+require_signature_addr=1
|
||||
+enable_debug_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
- test: riscv_full_interrupt_test
|
||||
description: >
|
||||
Random instruction test with complete interrupt handling
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
+enable_interrupt=1
|
||||
gen_opts: >
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+enable_irq_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
# Please enable this test for your RTL simulation
|
||||
- test: riscv_csr_test
|
||||
description: >
|
||||
Test all CSR instructions on all implemented CSR registers
|
||||
iterations: 0
|
||||
no_iss: 1
|
||||
rtl_test: core_csr_test
|
||||
no_post_compare: 1
|
||||
|
||||
- test: riscv_unaligned_load_store_test
|
||||
description: >
|
||||
Unaligned load/store test
|
||||
iterations: 1
|
||||
gen_test: riscv_instr_base_test
|
||||
gcc_opts: >
|
||||
-mno-strict-align
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,20
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
|
||||
+directed_instr_3=riscv_mem_region_stress_test,5
|
||||
+enable_unaligned_load_store=1
|
||||
rtl_test: core_base_test
|
22
vendor/google_riscv-dv/target/rv64imc/riscvOVPsim.ic
vendored
Normal file
22
vendor/google_riscv-dv/target/rv64imc/riscvOVPsim.ic
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
# riscOVPsim configuration file converted from YAML
|
||||
--variant RVB64I
|
||||
--override riscvOVPsim/cpu/add_Extensions=MC
|
||||
--override riscvOVPsim/cpu/misa_MXL=2
|
||||
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/unaligned=T
|
||||
--override riscvOVPsim/cpu/mtvec_mask=0x0 # 0
|
||||
--override riscvOVPsim/cpu/mtvec_is_ro=T
|
||||
--override riscvOVPsim/cpu/mtvec=0x80000081 # 2147483777
|
||||
--override riscvOVPsim/cpu/user_version=2.3
|
||||
--override riscvOVPsim/cpu/priv_version=1.11
|
||||
--override riscvOVPsim/cpu/mvendorid=0
|
||||
--override riscvOVPsim/cpu/marchid=0
|
||||
--override riscvOVPsim/cpu/mimpid=0
|
||||
--override riscvOVPsim/cpu/mhartid=0
|
||||
--override riscvOVPsim/cpu/cycle_undefined=F
|
||||
--override riscvOVPsim/cpu/instret_undefined=F
|
||||
--override riscvOVPsim/cpu/time_undefined=T
|
||||
--override riscvOVPsim/cpu/nmi_address=0x800000fc # 2147483900
|
||||
--override riscvOVPsim/cpu/reset_address=0x80000000
|
||||
--override riscvOVPsim/cpu/simulateexceptions=T
|
104
vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
vendored
Normal file
104
vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor feature configuration
|
||||
//-----------------------------------------------------------------------------
|
||||
// XLEN
|
||||
parameter int XLEN = 64;
|
||||
|
||||
// Parameter for SATP mode, set to BARE if address translation is not supported
|
||||
parameter satp_mode_t SATP_MODE = BARE;
|
||||
|
||||
// Supported Privileged mode
|
||||
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
|
||||
|
||||
// Unsupported instructions
|
||||
riscv_instr_name_t unsupported_instr[];
|
||||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C, RV64I, RV64M, RV64C};
|
||||
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
||||
// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is
|
||||
// supported
|
||||
int max_interrupt_vector_num = 16;
|
||||
|
||||
// Debug mode support
|
||||
bit support_debug_mode = 0;
|
||||
|
||||
// Support delegate trap to user mode
|
||||
bit support_umode_trap = 0;
|
||||
|
||||
// Support sfence.vma instruction
|
||||
bit support_sfence = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Previleged CSR implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Implemented previlieged CSR list
|
||||
`ifdef DSIM
|
||||
privileged_reg_t implemented_csr[] = {
|
||||
`else
|
||||
parameter privileged_reg_t implemented_csr[] = {
|
||||
`endif
|
||||
// Machine mode mode CSR
|
||||
MVENDORID, // Vendor ID
|
||||
MARCHID, // Architecture ID
|
||||
MIMPID, // Implementation ID
|
||||
MHARTID, // Hardware thread ID
|
||||
MSTATUS, // Machine status
|
||||
MISA, // ISA and extensions
|
||||
MIE, // Machine interrupt-enable register
|
||||
MTVEC, // Machine trap-handler base address
|
||||
MCOUNTEREN, // Machine counter enable
|
||||
MSCRATCH, // Scratch register for machine trap handlers
|
||||
MEPC, // Machine exception program counter
|
||||
MCAUSE, // Machine trap cause
|
||||
MTVAL, // Machine bad address or instruction
|
||||
MIP // Machine interrupt pending
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Supported interrupt/exception setting, used for functional coverage
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
`ifdef DSIM
|
||||
interrupt_cause_t implemented_interrupt[] = {
|
||||
`else
|
||||
parameter interrupt_cause_t implemented_interrupt[] = {
|
||||
`endif
|
||||
M_SOFTWARE_INTR,
|
||||
M_TIMER_INTR,
|
||||
M_EXTERNAL_INTR
|
||||
};
|
||||
|
||||
`ifdef DSIM
|
||||
exception_cause_t implemented_exception[] = {
|
||||
`else
|
||||
parameter exception_cause_t implemented_exception[] = {
|
||||
`endif
|
||||
INSTRUCTION_ADDRESS_MISALIGNED,
|
||||
INSTRUCTION_ACCESS_FAULT,
|
||||
ILLEGAL_INSTRUCTION,
|
||||
BREAKPOINT,
|
||||
LOAD_ADDRESS_MISALIGNED,
|
||||
LOAD_ACCESS_FAULT,
|
||||
ECALL_MMODE
|
||||
};
|
219
vendor/google_riscv-dv/target/rv64imc/testlist.yaml
vendored
Normal file
219
vendor/google_riscv-dv/target/rv64imc/testlist.yaml
vendored
Normal file
|
@ -0,0 +1,219 @@
|
|||
# Copyright 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.
|
||||
|
||||
# ================================================================================
|
||||
# Regression test list format
|
||||
# --------------------------------------------------------------------------------
|
||||
# test : Assembly test name
|
||||
# description : Description of this test
|
||||
# gen_opts : Instruction generator options
|
||||
# iterations : Number of iterations of this test
|
||||
# no_iss : Enable/disable ISS simulator (Optional)
|
||||
# gen_test : Test name used by the instruction generator
|
||||
# rtl_test : RTL simulation test name
|
||||
# cmp_opts : Compile options passed to the instruction generator
|
||||
# sim_opts : Simulation options passed to the instruction generator
|
||||
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# gcc_opts : gcc compile options
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
- test: riscv_arithmetic_basic_test
|
||||
description: >
|
||||
Arithmetic instruction test, no load/store/branch instructions
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=0
|
||||
+no_fence=1
|
||||
+no_data_page=1
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
|
||||
- test: riscv_rand_instr_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,4
|
||||
+directed_instr_1=riscv_loop_instr,4
|
||||
+directed_instr_2=riscv_hazard_instr_stream,4
|
||||
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
|
||||
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
|
||||
+directed_instr_5=riscv_mem_region_stress_test,4
|
||||
+directed_instr_6=riscv_jal_instr,4
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_jump_stress_test
|
||||
description: >
|
||||
Stress back-to-back jump instruction test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_jal_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_loop_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_loop_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_non_compressed_instr_test
|
||||
description: >
|
||||
Random instruction test without compressed instructions
|
||||
iterations: 1
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+disable_compressed_instr=1
|
||||
gcc_opts: >
|
||||
-march=rv64im
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_rand_jump_test
|
||||
description: >
|
||||
Jump among large number of sub-programs, stress testing iTLB operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=20
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,8
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_mmu_stress_test
|
||||
description: >
|
||||
Test with different patterns of load/store instructions, stress test MMU
|
||||
operations.
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,40
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,40
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
|
||||
+directed_instr_3=riscv_mem_region_stress_test,10
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_no_fence_test
|
||||
description: >
|
||||
Random instruction with FENCE disabled, used to test processor pipeline with
|
||||
less stall/flush operations caused by FENCE instruction.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+no_fence=1
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_illegal_instr_test
|
||||
description: >
|
||||
Illegal instruction test, verify the processor can detect illegal
|
||||
instruction and handle corresponding exception properly. An exception
|
||||
handling routine is designed to resume execution after illegal
|
||||
instruction exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+illegal_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_hint_instr_test
|
||||
description: >
|
||||
HINT instruction test, verify the processor can detect HINT instruction
|
||||
treat it as NOP. No illegal instruction exception is expected
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+hint_instr_ratio=5
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_test
|
||||
description: >
|
||||
Random instruction test with ebreak instruction enabled. Debug mode is not
|
||||
enabled for this test, processor should raise ebreak exception.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_ebreak_debug_mode_test
|
||||
description: >
|
||||
Ebreak instruction test with debug mode enabled.
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+no_ebreak=0
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+require_signature_addr=1
|
||||
+enable_debug_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
- test: riscv_full_interrupt_test
|
||||
description: >
|
||||
Random instruction test with complete interrupt handling
|
||||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+enable_interrupt=1
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+enable_irq_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
# Please enable this test for your RTL simulation
|
||||
- test: riscv_csr_test
|
||||
description: >
|
||||
Test all CSR instructions on all implemented CSR registers
|
||||
iterations: 0
|
||||
no_iss: 1
|
||||
rtl_test: core_csr_test
|
||||
no_post_compare: 1
|
||||
|
||||
- test: riscv_unaligned_load_store_test
|
||||
description: >
|
||||
Unaligned load/store test
|
||||
iterations: 1
|
||||
gen_test: riscv_instr_base_test
|
||||
gcc_opts: >
|
||||
-mno-strict-align
|
||||
gen_opts: >
|
||||
+instr_cnt=6000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_0=riscv_load_store_rand_instr_stream,20
|
||||
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
|
||||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
|
||||
+directed_instr_3=riscv_mem_region_stress_test,5
|
||||
+enable_unaligned_load_store=1
|
||||
rtl_test: core_base_test
|
|
@ -76,7 +76,7 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
continue;
|
||||
end
|
||||
if (!sample()) begin
|
||||
`uvm_info(`gfn, $sformatf("Skipping illegal instr name: %0s [%0s]",
|
||||
`uvm_info(`gfn, $sformatf("Found illegal instr: %0s [%0s]",
|
||||
trace["instr"], line), UVM_LOW)
|
||||
end
|
||||
end
|
||||
|
@ -105,6 +105,7 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
|
||||
function bit sample();
|
||||
riscv_instr_name_t instr_name;
|
||||
bit [XLEN-1:0] val;
|
||||
if (instr_enum::from_name(process_instr_name(trace["instr"]), instr_name)) begin
|
||||
if (cfg.instr_template.exists(instr_name)) begin
|
||||
instr.copy_base_instr(cfg.instr_template[instr_name]);
|
||||
|
@ -113,11 +114,16 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
instr_cg.sample(instr);
|
||||
return 1'b1;
|
||||
end
|
||||
end else if (trace["instr"] == "") begin
|
||||
bit [XLEN-1:0] val;
|
||||
get_val(trace["binary"], val);
|
||||
instr_cg.illegal_cg.sample(val);
|
||||
return 1'b1;
|
||||
end
|
||||
get_val(trace["binary"], val);
|
||||
if ((val[1:0] != 2'b11) && (RV32C inside {supported_isa})) begin
|
||||
instr_cg.compressed_opcode_cg.sample(val[15:0]);
|
||||
instr_cg.illegal_compressed_instr_cg.sample(val);
|
||||
end
|
||||
if (val[1:0] == 2'b11) begin
|
||||
`uvm_info("DBG", $sformatf("Sample illegal opcode: %0x [%0s]",
|
||||
val[6:2], trace["instr_str"]), UVM_LOW)
|
||||
instr_cg.opcode_cg.sample(val[6:2]);
|
||||
end
|
||||
illegal_instr_cnt++;
|
||||
return 1'b0;
|
||||
|
@ -128,7 +134,7 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
privileged_reg_t preg;
|
||||
get_val(trace["addr"], instr.pc);
|
||||
get_val(trace["binary"], instr.binary);
|
||||
instr.trace = trace["instr_str"];
|
||||
instr.trace = trace["str"];
|
||||
if (instr.instr_name inside {ECALL, EBREAK, FENCE, FENCE_I, NOP,
|
||||
C_NOP, WFI, MRET, C_EBREAK}) begin
|
||||
return;
|
||||
|
@ -152,7 +158,8 @@ class riscv_instr_cov_test extends uvm_test;
|
|||
end
|
||||
end
|
||||
if (instr.has_rs1) begin
|
||||
if (instr.format inside {CI_FORMAT, CR_FORMAT, CB_FORMAT}) begin
|
||||
if (instr.format inside {CI_FORMAT, CR_FORMAT} &&
|
||||
!(instr.instr_name inside {C_JR, C_JALR})) begin
|
||||
instr.rs1 = instr.rd;
|
||||
end else begin
|
||||
if (get_gpr(trace["rs1"], gpr)) begin
|
||||
|
|
|
@ -32,6 +32,7 @@ class riscv_rand_instr_test extends riscv_instr_base_test;
|
|||
// Mix below directed instructino streams with the random instructions
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_rand_instr_stream", 4);
|
||||
asm_gen.add_directed_instr_stream("riscv_loop_instr", 4);
|
||||
asm_gen.add_directed_instr_stream("riscv_jal_instr", 4);
|
||||
asm_gen.add_directed_instr_stream("riscv_hazard_instr_stream", 4);
|
||||
asm_gen.add_directed_instr_stream("riscv_load_store_hazard_instr_stream", 4);
|
||||
asm_gen.add_directed_instr_stream("riscv_multi_page_load_store_instr_stream", 4);
|
||||
|
|
5
vendor/google_riscv-dv/yaml/iss.yaml
vendored
5
vendor/google_riscv-dv/yaml/iss.yaml
vendored
|
@ -21,10 +21,11 @@
|
|||
path_var: OVPSIM_PATH
|
||||
cmd: >
|
||||
<path_var>/riscvOVPsim.exe
|
||||
--variant <variant>
|
||||
--controlfile ../riscv-dv/target/<variant>/riscvOVPsim.ic
|
||||
--objfilenoentry <elf>
|
||||
--override riscvOVPsim/cpu/PMP_registers=0
|
||||
--override riscvOVPsim/cpu/simulateexceptions=T
|
||||
--trace --tracechange --traceshowicount --program <elf>
|
||||
--trace --tracechange --traceshowicount --tracemode --traceregs
|
||||
--finishafter 1000000
|
||||
|
||||
- iss: sail
|
||||
|
|
20
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
20
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
|
@ -39,6 +39,7 @@
|
|||
+no_data_page=1
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
@ -78,6 +79,18 @@
|
|||
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
|
||||
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
|
||||
+directed_instr_5=riscv_mem_region_stress_test,4
|
||||
+directed_instr_6=riscv_jal_instr,4
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_jump_stress_test
|
||||
description: >
|
||||
Stress back-to-back jump instruction test
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=5000
|
||||
+num_of_sub_program=5
|
||||
+directed_instr_1=riscv_jal_instr,20
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_loop_test
|
||||
|
@ -212,6 +225,7 @@
|
|||
iterations: 2
|
||||
gen_test: riscv_rand_instr_test
|
||||
gen_opts: >
|
||||
+enable_interrupt=1
|
||||
rtl_test: core_base_test
|
||||
sim_opts: >
|
||||
+enable_irq_seq=1
|
||||
|
@ -224,12 +238,12 @@
|
|||
Test all CSR instructions on all implemented CSR registers
|
||||
iterations: 0
|
||||
no_iss: 1
|
||||
rtl_test: core_ibex_csr_test
|
||||
rtl_test: core_csr_test
|
||||
no_post_compare: 1
|
||||
|
||||
- test: riscv_unaligned_load_store_test
|
||||
description: >
|
||||
Unaligned load/store test, ibex should handle it correctly without raising any exception
|
||||
Unaligned load/store test
|
||||
iterations: 1
|
||||
gen_test: riscv_instr_base_test
|
||||
gcc_opts: >
|
||||
|
@ -242,7 +256,7 @@
|
|||
+directed_instr_2=riscv_multi_page_load_store_instr_stream,5
|
||||
+directed_instr_3=riscv_mem_region_stress_test,5
|
||||
+enable_unaligned_load_store=1
|
||||
rtl_test: core_ibex_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_amo_test
|
||||
description: >
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue