mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 21:17:59 -04:00
Update google_riscv-dv to google/riscv-dv@e905e9f (#234)
Update code from upstream repository https://github.com/google/riscv- dv to revision e905e9f134e0b7cf7da491218d1a30c75ce8649a * add pass_val and fail_val into csr test flow for EOT correctness checking (Udi) * Support unaligned load/store (Tao Liu) * refactored test generation logic (Udi) * refactored test generation logic (Udi) * Give error when mutually exclusive between -co, and -so argument (dang hai) * documentation, and small fixes (Udi) * no_iss bug (Udi) * no_iss/no_post_compare optional, CSR read_only is now only specified at field level granularity (Udi) * made no_iss optional (Udi) * rm print (Udi) * setup_logging call (Udi) * undo overriding --verbose in run.py, comment cleanup in csr gen script (Udi) * missed verbose arguments (Udi) * verbose arg (Udi) * updated csr description, integrated csr test into flow (Udi) * updated csr description, integrated csr test into flow (Udi) * Enhance verbose information by logging instead of using print (dang hai) * Report date time for output directory (dang hai) * Add main entry point for run.py (dang hai) * Separate command line parser by function (dang hai) * Skip generating S/U mode program for machine mode test (Tao Liu) * minor update to README.md (Tao Liu) * Update the README.md to match command reference from --help (Tao Liu) * Ignore untrack file from python script (dang hai) * Make questa work for new YAML based regression flow (dang hai) * Fix typo in README (Tao Liu) * Fix README google/riscv-dv#54 (Tao Liu) * changed formatting of generator option table (Udi)
This commit is contained in:
parent
9a231c9ba6
commit
97105f42b1
16 changed files with 569 additions and 297 deletions
2
vendor/google_riscv-dv.lock.hjson
vendored
2
vendor/google_riscv-dv.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/google/riscv-dv
|
||||
rev: a07e0a726edf0230314c08d31546eecbed23054b
|
||||
rev: e905e9f134e0b7cf7da491218d1a30c75ce8649a
|
||||
}
|
||||
}
|
||||
|
|
1
vendor/google_riscv-dv/.gitignore
vendored
1
vendor/google_riscv-dv/.gitignore
vendored
|
@ -2,3 +2,4 @@
|
|||
*.bin
|
||||
out_*/
|
||||
work/
|
||||
*.pyc
|
||||
|
|
209
vendor/google_riscv-dv/README.md
vendored
209
vendor/google_riscv-dv/README.md
vendored
|
@ -15,6 +15,10 @@ processor verification. It currently supports the following features:
|
|||
- Supports mixing directed instructions with random instruction stream
|
||||
- Supports co-simulation with multiple ISS : spike, riscv-ovpsim
|
||||
|
||||
A CSR test generation script written in Python is also provided, to generate a
|
||||
directed test suite that stresses all CSR instructions on all of the CSRs that
|
||||
the core implements.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
@ -24,9 +28,26 @@ which supports SystemVerilog and UVM 1.2. This generator has been verified with
|
|||
Synopsys VCS, Cadence Incisive/Xcelium, and Mentor Questa simulators. Please
|
||||
make sure the EDA tool environment is properly setup before running the generator.
|
||||
|
||||
To be able to run the CSR generation script, the open-source `bitstring`
|
||||
Python library is required ([bitstring](https://github.com/scott-griffiths/bitstring)).
|
||||
To install this library, either clone the repository and run the `setup.py`
|
||||
setup script, or run only one of the below commands:
|
||||
```
|
||||
1) sudo apt-get install python3-bitstring (or your OS-specific package manager)
|
||||
2) pip install bitstring
|
||||
```
|
||||
|
||||
### Running the generator
|
||||
|
||||
A simple script "run" is provided for you to run a single test or a regression.
|
||||
|
||||
A simple script "run.py" is provided for you to run a single test or a regression.
|
||||
|
||||
You can use --help to get the complete command reference:
|
||||
|
||||
```
|
||||
python3 run.py --help
|
||||
```
|
||||
|
||||
Here is the command to run a single test:
|
||||
|
||||
```
|
||||
|
@ -35,9 +56,9 @@ python3 run.py --test=riscv_arithmetic_basic_test
|
|||
You can specify the simulator by "-simulator" option
|
||||
|
||||
```
|
||||
python3 run.py --test=riscv_arithmetic_basic_test --simulator=irun
|
||||
python3 run.py --test=riscv_arithmetic_basic_test --simulator=vcs
|
||||
python3 run.py --test=riscv_arithmetic_basic_test --simulator=questa
|
||||
python3 run.py --test riscv_arithmetic_basic_test --simulator ius
|
||||
python3 run.py --test riscv_arithmetic_basic_test --simulator vcs
|
||||
python3 run.py --test riscv_arithmetic_basic_test --simulator questa
|
||||
```
|
||||
The complete test list can be found in [yaml/testlist.yaml](https://github.com/google/riscv-dv/blob/master/yaml/testlist.yaml). To run a full
|
||||
regression, simply use below command
|
||||
|
@ -55,36 +76,129 @@ python3 run.py --lsf_cmd="bsub -Is"
|
|||
Here's a few more examples of the run command:
|
||||
|
||||
```
|
||||
// Get the complete command reference info
|
||||
python3 run.py --help
|
||||
|
||||
// Run a single test 10 times
|
||||
python3 run.py --test=riscv_page_table_exception_test --iterations=10
|
||||
python3 run.py --test riscv_page_table_exception_test --iterations 10
|
||||
|
||||
// Run a test with verbose logging
|
||||
python3 run.py --test riscv_page_table_exception_test --verbose
|
||||
|
||||
// Run a test with a specified seed
|
||||
python3 run.py --test=riscv_page_table_exception_test --seed=123
|
||||
python3 run.py --test riscv_page_table_exception_test --seed 123
|
||||
|
||||
// Skip the generation, run ISS simulation with previously generated program
|
||||
python3 run.py --test=riscv_page_table_exception_test --steps=iss_sim
|
||||
python3 run.py --test riscv_page_table_exception_test --steps iss_sim
|
||||
|
||||
// Run the generator only, do not compile and simluation with ISS
|
||||
python3 run.py --test riscv_page_table_exception_test --steps gen
|
||||
|
||||
// Compile the generator only, do not simulate
|
||||
python3 run.py --test riscv_page_table_exception_test --co
|
||||
|
||||
....
|
||||
```
|
||||
|
||||
### 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.
|
||||
To quickly generate a basic CSR test, run the below command:
|
||||
|
||||
```
|
||||
python3 scripts/gen_csr_test.py
|
||||
```
|
||||
|
||||
To create a new processor-specific CSR description YAML file, format it as
|
||||
detailed below, and then run:
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --csr_file PATH_TO_NEW_CSR_DESCRIPTION_FILE
|
||||
```
|
||||
|
||||
If the CSRs are a different XLEN, such as 64-bit or 128-bit, use the `--xlen`
|
||||
option to change the ISA length used to generate the test.
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --xlen 64
|
||||
```
|
||||
|
||||
To input the number of CSR test files that should be generated, use the
|
||||
`--iterations` option. Say 10 tests should be generated:
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --iterations 10
|
||||
```
|
||||
|
||||
To change the output directory that the tests are generated into, use the
|
||||
`--out` option. Say the tests should be generated into the home directory:
|
||||
```
|
||||
python3 scripts/gen_csr_test.py --out ~
|
||||
```
|
||||
|
||||
Any number of the above options can be combined together, and all of them have
|
||||
default values should they not be specified at runtime.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Setup CSR description list
|
||||
|
||||
This YAML description file of all CSRs is only required for the privileged CSR
|
||||
test. All other standard tests do not use this description.
|
||||
|
||||
[CSR descriptions in YAML
|
||||
format](https://github.com/google/riscv-dv/blob/master/yaml/csr_template.yaml)
|
||||
|
||||
```
|
||||
- csr: CSR_NAME
|
||||
description: >
|
||||
BRIEF_DESCRIPTION
|
||||
address: 0x###
|
||||
privilege_mode: MODE (D/M/S/H/U)
|
||||
rv32:
|
||||
- MSB_FIELD_NAME:
|
||||
- description: >
|
||||
BRIEF_DESCRIPTION
|
||||
- type: TYPE (WPRI/WLRL/WARL/R)
|
||||
- reset_val: RESET_VAL
|
||||
- msb: MSB_POS
|
||||
- lsb: LSB_POS
|
||||
- ...
|
||||
- ...
|
||||
- LSB_FIELD_NAME:
|
||||
- description: ...
|
||||
- type: ...
|
||||
- ...
|
||||
rv64:
|
||||
- MSB_FIELD_NAME:
|
||||
- description: >
|
||||
BRIEF_DESCRIPTION
|
||||
- type: TYPE (WPRI/WLRL/WARL/R)
|
||||
- reset_val: RESET_VAL
|
||||
- msb: MSB_POS
|
||||
- lsb: LSB_POS
|
||||
- ...
|
||||
- ...
|
||||
- LSB_FIELD_NAME:
|
||||
- description: ...
|
||||
- type: ...
|
||||
- ...
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Setup regression test list
|
||||
|
||||
[Test list in YAML format](https://github.com/google/riscv-dv/blob/master/yaml/testlist.yaml)
|
||||
|
||||
```
|
||||
# test : Assembly test name
|
||||
# description : Description of this test
|
||||
# gen_opts : Instruction generator options
|
||||
# iterations : Number of iterations of this test
|
||||
# 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
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# 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 simulation (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 log comparison (Optional)
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
|
||||
- test: riscv_arithmetic_basic_test
|
||||
description: >
|
||||
|
@ -102,6 +216,11 @@ python3 run.py --test=riscv_page_table_exception_test --steps=iss_sim
|
|||
|
||||
```
|
||||
|
||||
Note: To automatically generate CSR tests without having to explicitly run the
|
||||
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
|
||||
|
@ -133,23 +252,23 @@ riscv_instr_group_t supported_isa[] = {RV32I, RV32M, RV64I, RV64M};
|
|||
|
||||
### Runtime options of the generator
|
||||
|
||||
| Option | Description | default |
|
||||
|----------|:-------------:|:------:|
|
||||
| num_of_tests | Number of assembly tests to be generated | 1 |
|
||||
| num_of_sub_program | Number of sub-program in one test | 5 |
|
||||
| instr_cnt | Instruction count per test | 200 |
|
||||
| enable_page_table_exception | Enable page table exception | 0 |
|
||||
| no_ebreak | Disable ebreak instruction | 1 |
|
||||
| no_wfi | Disable WFI instruction | 1 |
|
||||
| no_branch_jump | Disable branch/jump instruction | 0 |
|
||||
| no_load_store | Disable load/store instruction | 0 |
|
||||
| no_csr_instr | Disable CSR instruction | 0 |
|
||||
| no_fence | Disable fence instruction | 0 |
|
||||
| enable_illegal_instruction | Enable illegal instructions | 0 |
|
||||
| enable_hint_instruction | Enable HINT instruction | 0 |
|
||||
| boot_mode | m:Machine mode, s:Supervisor mode, u:User mode | m |
|
||||
| no_directed_instr | Disable directed instruction stream | 0 |
|
||||
| enable_interrupt | Enable MStatus.MIE, used in interrupt test | 0 |
|
||||
| Option | Description | Default |
|
||||
|:---------------------------:|:-----------------------------------------------:|:-------:|
|
||||
| num_of_tests | Number of assembly tests to be generated | 1 |
|
||||
| num_of_sub_program | Number of sub-program in one test | 5 |
|
||||
| instr_cnt | Instruction count per test | 200 |
|
||||
| enable_page_table_exception | Enable page table exception | 0 |
|
||||
| no_ebreak | Disable ebreak instruction | 1 |
|
||||
| no_wfi | Disable WFI instruction | 1 |
|
||||
| no_branch_jump | Disable branch/jump instruction | 0 |
|
||||
| no_load_store | Disable load/store instruction | 0 |
|
||||
| no_csr_instr | Disable CSR instruction | 0 |
|
||||
| no_fence | Disable fence instruction | 0 |
|
||||
| enable_illegal_instruction | Enable illegal instructions | 0 |
|
||||
| enable_hint_instruction | Enable HINT instruction | 0 |
|
||||
| boot_mode | m:Machine mode, s:Supervisor mode, u:User mode | m |
|
||||
| no_directed_instr | Disable directed instruction stream | 0 |
|
||||
| enable_interrupt | Enable MStatus.MIE, used in interrupt test | 0 |
|
||||
|
||||
### Adding new instruction stream and test
|
||||
|
||||
|
@ -163,7 +282,13 @@ it with random instructions
|
|||
+directed_instr_5=riscv_multi_page_load_store_instr_stream,4
|
||||
```
|
||||
|
||||
## Run ISS(Instruction Set Simulator) simulation
|
||||
## Compile generated programs with GCC
|
||||
|
||||
- Install [riscv-gcc](https://github.com/riscv/riscv-gcc) toolchain
|
||||
- Set environment variable RISCV_GCC to the directory of the RISC-V gcc
|
||||
executable. (example: <install_dir>/bin/riscv32-unknown-elf-gcc)
|
||||
|
||||
## Run ISS (Instruction Set Simulator) simulation
|
||||
|
||||
The default ISS is spike. Thanks for the great support from Imperas Software Ltd.,
|
||||
we have added the support for [riscv-ovpsim](https://github.com/riscv/riscv-ovpsim).
|
||||
|
@ -181,10 +306,10 @@ You can use -iss to run with different ISS.
|
|||
|
||||
```
|
||||
// Run ISS with spike
|
||||
python3 run.py --test=riscv_page_table_exception_test --iss=spike
|
||||
python3 run.py --test riscv_page_table_exception_test --iss spike
|
||||
|
||||
// Run ISS with riscv-ovpsim
|
||||
python3 run.py --test=riscv_rand_instr_test --iss=ovpsim
|
||||
python3 run.py --test riscv_rand_instr_test --iss ovpsim
|
||||
```
|
||||
|
||||
To run with ISS simulation for RV32IMC, you can specify ISA and ABI from command
|
||||
|
@ -192,7 +317,7 @@ line like this:
|
|||
|
||||
```
|
||||
// Run a full regression with RV32IMC
|
||||
python3 run.py --isa=rv32imc --mabi=ilp32
|
||||
python3 run.py --isa rv32imc --mabi ilp32
|
||||
```
|
||||
|
||||
We have added a flow to run ISS simulation with both spike and riscv-ovpsim,
|
||||
|
@ -218,13 +343,13 @@ You can add a new entry in [iss.yaml](https://github.com/google/riscv-dv/blob/ma
|
|||
Simulate with the new ISS
|
||||
|
||||
```
|
||||
python3 run.py --test=riscv_page_table_exception_test --iss=new_iss_name
|
||||
python3 run.py --test riscv_page_table_exception_test --iss new_iss_name
|
||||
```
|
||||
|
||||
## End-to-end RTL and ISS co-simulation flow
|
||||
|
||||
We have collaborated with LowRISC to apply this flow for [IBEX RISC-V core
|
||||
verification](https://github.com/lowRISC/ibex/tree/master/dv/uvm). You can use
|
||||
verification](https://github.com/lowRISC/ibex/blob/master/doc/verification.rst). You can use
|
||||
it as a reference to setup end-to-end co-simulation flow. It's also a good
|
||||
reference for [customizing the generator](https://github.com/lowRISC/ibex/tree/master/dv/uvm/riscv_dv_extension) without getting impacted by upstream
|
||||
changes.
|
||||
|
|
348
vendor/google_riscv-dv/run.py
vendored
348
vendor/google_riscv-dv/run.py
vendored
|
@ -21,12 +21,16 @@ import os
|
|||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from datetime import date
|
||||
from scripts.lib import *
|
||||
from scripts.spike_log_to_trace_csv import *
|
||||
from scripts.ovpsim_log_to_trace_csv import *
|
||||
from scripts.instr_trace_compare import *
|
||||
|
||||
LOGGER = logging.getLogger()
|
||||
|
||||
def get_generator_cmd(simulator, simulator_yaml):
|
||||
""" Setup the compile and simulation command for the generator
|
||||
|
||||
|
@ -38,16 +42,16 @@ def get_generator_cmd(simulator, simulator_yaml):
|
|||
compile_cmd : RTL simulator command to compile the instruction generator
|
||||
sim_cmd : RTL simulator command to run the instruction generator
|
||||
"""
|
||||
print("Processing simulator setup file : %s" % simulator_yaml)
|
||||
logging.info("Processing simulator setup file : %s" % simulator_yaml)
|
||||
yaml_data = read_yaml(simulator_yaml)
|
||||
# Search for matched simulator
|
||||
for entry in yaml_data:
|
||||
if entry['tool'] == simulator:
|
||||
print ("Found matching simulator: %s" % entry['tool'])
|
||||
logging.info("Found matching simulator: %s" % entry['tool'])
|
||||
compile_cmd = entry['compile_cmd']
|
||||
sim_cmd = entry['sim_cmd']
|
||||
return compile_cmd, sim_cmd
|
||||
print ("Cannot find RTL simulator %0s" % simulator)
|
||||
logging.error("Cannot find RTL simulator %0s" % simulator)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -62,12 +66,12 @@ def parse_iss_yaml(iss, iss_yaml, isa):
|
|||
Returns:
|
||||
cmd : ISS run command
|
||||
"""
|
||||
print("Processing ISS setup file : %s" % iss_yaml)
|
||||
logging.info("Processing ISS setup file : %s" % iss_yaml)
|
||||
yaml_data = read_yaml(iss_yaml)
|
||||
# Search for matched ISS
|
||||
for entry in yaml_data:
|
||||
if entry['iss'] == iss:
|
||||
print ("Found matching ISS: %s" % entry['iss'])
|
||||
logging.info("Found matching ISS: %s" % entry['iss'])
|
||||
cmd = entry['cmd'].rstrip()
|
||||
cmd = re.sub("\<path_var\>", get_env_var(entry['path_var']), cmd)
|
||||
if iss == "ovpsim":
|
||||
|
@ -75,7 +79,7 @@ def parse_iss_yaml(iss, iss_yaml, isa):
|
|||
else:
|
||||
cmd = re.sub("\<variant\>", isa, cmd)
|
||||
return cmd
|
||||
print ("Cannot find ISS %0s" % iss)
|
||||
logging.error("Cannot find ISS %0s" % iss)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -95,68 +99,84 @@ def get_iss_cmd(base_cmd, elf, log):
|
|||
return cmd
|
||||
|
||||
|
||||
def gen(test_list, simulator, simulator_yaml, output_dir, sim_only,
|
||||
compile_only, lsf_cmd, seed, cwd, cmp_opts, sim_opts, timeout_s, verbose):
|
||||
def gen(test_list, csr_file, end_signature_addr, isa, simulator,
|
||||
simulator_yaml, output_dir, sim_only, compile_only, lsf_cmd, seed,
|
||||
cwd, cmp_opts, sim_opts, timeout_s):
|
||||
"""Run the instruction generator
|
||||
|
||||
Args:
|
||||
test_list : List of assembly programs to be compiled
|
||||
simulator : RTL simulator used to run instruction generator
|
||||
simulator_yaml : RTL simulator configuration file in YAML format
|
||||
output_dir : Output directory of the ELF files
|
||||
sim_only : Simulation only
|
||||
compile_only : Compile the generator only
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
seed : Seed to the instruction generator
|
||||
cmp_opts : Compile options for the generator
|
||||
sim_opts : Simulation options for the generator
|
||||
timeout_s : Timeout limit in seconds
|
||||
verbose : Verbose logging
|
||||
test_list : List of assembly programs to be compiled
|
||||
csr_file : YAML file containing description of all CSRs
|
||||
end_signature_addr : Address that tests will write pass/fail signature to at end of test
|
||||
isa : Processor supported ISA subset
|
||||
simulator : RTL simulator used to run instruction generator
|
||||
simulator_yaml : RTL simulator configuration file in YAML format
|
||||
output_dir : Output directory of the ELF files
|
||||
sim_only : Simulation only
|
||||
compile_only : Compile the generator only
|
||||
lsf_cmd : LSF command used to run the instruction generator
|
||||
seed : Seed to the instruction generator
|
||||
cmp_opts : Compile options for the generator
|
||||
sim_opts : Simulation options for the generator
|
||||
timeout_s : Timeout limit in seconds
|
||||
"""
|
||||
# Mutually exclusive options between compile_only and sim_only
|
||||
if compile_only and sim_only:
|
||||
logging.error("argument -co is not allowed with argument -so")
|
||||
# Setup the compile and simulation command for the generator
|
||||
compile_cmd = []
|
||||
sim_cmd = ""
|
||||
compile_cmd, sim_cmd = get_generator_cmd(simulator, simulator_yaml);
|
||||
# Compile the instruction generator
|
||||
if not sim_only:
|
||||
print ("Building RISC-V instruction generator")
|
||||
logging.info("Building RISC-V instruction generator")
|
||||
for cmd in compile_cmd:
|
||||
cmd = re.sub("<out>", os.path.abspath(output_dir), cmd)
|
||||
cmd = re.sub("<cwd>", cwd, cmd)
|
||||
cmd = re.sub("<cmp_opts>", cmp_opts, cmd)
|
||||
if verbose:
|
||||
print("Compile command: %s" % cmd)
|
||||
output = run_cmd(cmd)
|
||||
if verbose:
|
||||
print(output)
|
||||
logging.debug("Compile command: %s" % cmd)
|
||||
logging.debug(run_cmd(cmd))
|
||||
# Run the instruction generator
|
||||
if not compile_only:
|
||||
cmd_list = []
|
||||
sim_cmd = re.sub("<out>", os.path.abspath(output_dir), sim_cmd)
|
||||
sim_cmd = re.sub("<cwd>", cwd, sim_cmd)
|
||||
sim_cmd = re.sub("<sim_opts>", sim_opts, sim_cmd)
|
||||
print ("Running RISC-V instruction generator")
|
||||
logging.info("Running RISC-V instruction generator")
|
||||
for test in test_list:
|
||||
if test['iterations'] > 0:
|
||||
rand_seed = get_seed(seed)
|
||||
cmd = lsf_cmd + " " + sim_cmd.rstrip() + \
|
||||
(" +UVM_TESTNAME=%s " % test['gen_test']) + \
|
||||
(" +num_of_tests=%d " % test['iterations']) + \
|
||||
(" +asm_file_name=%s/asm_tests/%s " % (output_dir, test['test'])) + \
|
||||
(" -l %s/sim_%s.log " % (output_dir, test['test']))
|
||||
cmd = re.sub("<seed>", str(rand_seed), cmd)
|
||||
if "gen_opts" in test:
|
||||
cmd += test['gen_opts']
|
||||
print("Generating %d %s" % (test['iterations'], test['test']))
|
||||
iterations = test['iterations']
|
||||
if iterations > 0:
|
||||
"""
|
||||
If we are running a CSR test, need to call a separate python script
|
||||
to generate directed CSR test code, located at scripts/gen_csr_test.py.
|
||||
"""
|
||||
if test['test'] == 'riscv_csr_test':
|
||||
cmd = "python3 scripts/gen_csr_test.py" + \
|
||||
(" --csr_file %s" % csr_file) + \
|
||||
(" --xlen %s" % re.search(r"(?P<xlen>[0-9]+)", isa).group("xlen")) + \
|
||||
(" --iterations %i" % iterations) + \
|
||||
(" --out %s/asm_tests" % output_dir) + \
|
||||
(" --end_signature_addr %s" % end_signature_addr)
|
||||
else:
|
||||
rand_seed = get_seed(seed)
|
||||
cmd = lsf_cmd + " " + sim_cmd.rstrip() + \
|
||||
(" +UVM_TESTNAME=%s " % test['gen_test']) + \
|
||||
(" +num_of_tests=%d " % 'iterations') + \
|
||||
(" +asm_file_name=%s/asm_tests/%s " % (output_dir, test['test'])) + \
|
||||
(" -l %s/sim_%s.log " % (output_dir, test['test']))
|
||||
cmd = re.sub("<seed>", str(rand_seed), cmd)
|
||||
if "gen_opts" in test:
|
||||
cmd += test['gen_opts']
|
||||
logging.info("Generating %d %s" % (iterations, test['test']))
|
||||
if lsf_cmd:
|
||||
cmd_list.append(cmd)
|
||||
else:
|
||||
run_cmd(cmd, verbose, timeout_s)
|
||||
run_cmd(cmd, timeout_s)
|
||||
if lsf_cmd:
|
||||
run_parallel_cmd(cmd_list, verbose, timeout_s)
|
||||
run_parallel_cmd(cmd_list, timeout_s)
|
||||
|
||||
|
||||
def gcc_compile(test_list, output_dir, isa, mabi, verbose):
|
||||
def gcc_compile(test_list, output_dir, isa, mabi):
|
||||
"""Use riscv gcc toolchain to compile the assembly program
|
||||
|
||||
Args:
|
||||
|
@ -164,7 +184,6 @@ def gcc_compile(test_list, output_dir, isa, mabi, verbose):
|
|||
output_dir : Output directory of the ELF files
|
||||
isa : ISA variant passed to GCC
|
||||
mabi : MABI variant passed to GCC
|
||||
verbose : Verbose logging
|
||||
"""
|
||||
for test in test_list:
|
||||
for i in range(0, test['iterations']):
|
||||
|
@ -178,21 +197,18 @@ def gcc_compile(test_list, output_dir, isa, mabi, verbose):
|
|||
-nostartfiles \
|
||||
-Tscripts/link.ld %s -o %s" % \
|
||||
(get_env_var("RISCV_GCC") ,isa, mabi, asm, elf))
|
||||
print("Compiling %s" % asm)
|
||||
if verbose:
|
||||
print(cmd)
|
||||
logging.info("Compiling %s" % asm)
|
||||
logging.debug(cmd)
|
||||
output = subprocess.check_output(cmd.split())
|
||||
if verbose:
|
||||
print(output)
|
||||
logging.debug(output)
|
||||
# Convert the ELF to plain binary, used in RTL sim
|
||||
print ("Converting to %s" % binary)
|
||||
logging.info("Converting to %s" % binary)
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY"), elf, binary))
|
||||
output = subprocess.check_output(cmd.split())
|
||||
if verbose:
|
||||
print(output)
|
||||
logging.debug(output)
|
||||
|
||||
|
||||
def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, timeout_s, verbose):
|
||||
def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, timeout_s):
|
||||
"""Run ISS simulation with the generated test program
|
||||
|
||||
Args:
|
||||
|
@ -202,26 +218,27 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, timeout_s, verbose):
|
|||
iss_yaml : ISS configuration file in YAML format
|
||||
isa : ISA variant passed to the ISS
|
||||
timeout_s : Timeout limit in seconds
|
||||
verbose : Verbose logging
|
||||
"""
|
||||
for iss in iss_list.split(","):
|
||||
log_dir = ("%s/%s_sim" % (output_dir, iss))
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa)
|
||||
print ("%s sim log dir: %s" % (iss, log_dir))
|
||||
logging.info("%s sim log dir: %s" % (iss, log_dir))
|
||||
subprocess.run(["mkdir", "-p", log_dir])
|
||||
for test in test_list:
|
||||
for i in range(0, test['iterations']):
|
||||
prefix = ("%s/asm_tests/%s.%d" % (output_dir, test['test'], i))
|
||||
elf = prefix + ".o"
|
||||
log = ("%s/%s.%d.log" % (log_dir, test['test'], i))
|
||||
cmd = get_iss_cmd(base_cmd, elf, log)
|
||||
print ("Running ISS simulation: %s" % elf)
|
||||
run_cmd(cmd, 0, timeout_s)
|
||||
if verbose:
|
||||
print (cmd)
|
||||
if 'no_iss' in test and test['no_iss'] == 1:
|
||||
continue
|
||||
else:
|
||||
for i in range(0, test['iterations']):
|
||||
prefix = ("%s/asm_tests/%s.%d" % (output_dir, test['test'], i))
|
||||
elf = prefix + ".o"
|
||||
log = ("%s/%s.%d.log" % (log_dir, test['test'], i))
|
||||
cmd = get_iss_cmd(base_cmd, elf, log)
|
||||
logging.info("Running ISS simulation: %s" % elf)
|
||||
run_cmd(cmd, timeout_s)
|
||||
logging.debug(cmd)
|
||||
|
||||
|
||||
def iss_cmp(test_list, iss, output_dir, isa, verbose):
|
||||
def iss_cmp(test_list, iss, output_dir, isa):
|
||||
"""Compare ISS simulation reult
|
||||
|
||||
Args:
|
||||
|
@ -229,7 +246,6 @@ def iss_cmp(test_list, iss, output_dir, isa, verbose):
|
|||
iss : List of instruction set simulators
|
||||
output_dir : Output directory of the ELF files
|
||||
isa : ISA
|
||||
verbose : Verbose logging
|
||||
"""
|
||||
iss_list = iss.split(",")
|
||||
if len(iss_list) != 2:
|
||||
|
@ -239,8 +255,8 @@ def iss_cmp(test_list, iss, output_dir, isa, verbose):
|
|||
for test in test_list:
|
||||
for i in range(0, test['iterations']):
|
||||
elf = ("%s/asm_tests/%s.%d.o" % (output_dir, test['test'], i))
|
||||
print("Comparing ISS sim result %s/%s : %s" %
|
||||
(iss_list[0], iss_list[1], elf))
|
||||
logging.info("Comparing ISS sim result %s/%s : %s" %
|
||||
(iss_list[0], iss_list[1], elf))
|
||||
csv_list = []
|
||||
run_cmd(("echo 'Test binary: %s' >> %s" % (elf, report)))
|
||||
for iss in iss_list:
|
||||
|
@ -252,99 +268,145 @@ def iss_cmp(test_list, iss, output_dir, isa, verbose):
|
|||
elif iss == "ovpsim":
|
||||
process_ovpsim_sim_log(log, csv)
|
||||
else:
|
||||
print("Unsupported ISS" % iss)
|
||||
logging.error("Unsupported ISS" % iss)
|
||||
sys.exit(1)
|
||||
compare_trace_csv(csv_list[0], csv_list[1], iss_list[0], iss_list[1], report)
|
||||
passed_cnt = run_cmd("grep PASSED %s | wc -l" % report).strip()
|
||||
failed_cnt = run_cmd("grep FAILED %s | wc -l" % report).strip()
|
||||
summary = ("%s PASSED, %s FAILED" % (passed_cnt, failed_cnt))
|
||||
print(summary)
|
||||
logging.info(summary)
|
||||
run_cmd(("echo %s >> %s" % (summary, report)))
|
||||
print("ISS regression report is saved to %s" % report)
|
||||
logging.info("ISS regression report is saved to %s" % report)
|
||||
|
||||
|
||||
# Parse input arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
def setup_parser():
|
||||
"""Create a command line parser.
|
||||
|
||||
parser.add_argument("--o", type=str, default="./out",
|
||||
help="Output directory name")
|
||||
parser.add_argument("--testlist", type=str, default="",
|
||||
help="Regression testlist")
|
||||
parser.add_argument("--isa", type=str, default="rv64imc",
|
||||
help="RISC-V ISA subset")
|
||||
parser.add_argument("--mabi", type=str, default="lp64",
|
||||
help="mabi used for compilation, lp32 or lp64")
|
||||
parser.add_argument("--test", type=str, default="all",
|
||||
help="Test name, 'all' means all tests in the list")
|
||||
parser.add_argument("--seed", type=int, default=-1,
|
||||
help="Randomization seed, default -1 means random seed")
|
||||
parser.add_argument("--iterations", type=int, default=0,
|
||||
help="Override the iteration count in the test list")
|
||||
parser.add_argument("--simulator", type=str, default="vcs",
|
||||
help="Simulator used to run the generator, default VCS")
|
||||
parser.add_argument("--simulator_yaml", type=str, default="",
|
||||
help="RTL simulator setting YAML")
|
||||
parser.add_argument("--iss", type=str, default="spike",
|
||||
help="RISC-V instruction set simulator: spike, ovpsim")
|
||||
parser.add_argument("--iss_yaml", type=str, default="",
|
||||
help="ISS setting YAML")
|
||||
parser.add_argument("--verbose", type=int, default=0,
|
||||
help="Verbose logging")
|
||||
parser.add_argument("--co", type=int, default=0,
|
||||
help="Compile the generator only")
|
||||
parser.add_argument("--so", type=int, default=0,
|
||||
help="Simulate the generator only")
|
||||
parser.add_argument("--cmp_opts", type=str, default="",
|
||||
help="Compile options for the generator")
|
||||
parser.add_argument("--sim_opts", type=str, default="",
|
||||
help="Simulation options for the generator")
|
||||
parser.add_argument("--steps", type=str, default="all",
|
||||
help="Run steps: gen,gcc_compile,iss_sim,iss_cmp")
|
||||
parser.add_argument("--lsf_cmd", type=str, default="",
|
||||
help="LSF command. Run in local sequentially if lsf \
|
||||
command is not specified")
|
||||
parser.add_argument("--gen_timeout", type=int, default=360,
|
||||
help="Generator timeout limit in seconds")
|
||||
parser.add_argument("--iss_timeout", type=int, default=50,
|
||||
help="ISS sim timeout limit in seconds")
|
||||
Returns: The created parser.
|
||||
"""
|
||||
# Parse input arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
args = parser.parse_args()
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
parser.add_argument("--o", type=str,
|
||||
help="Output directory name")
|
||||
parser.add_argument("--testlist", type=str, default="",
|
||||
help="Regression testlist")
|
||||
parser.add_argument("--csr_yaml", type=str, default="",
|
||||
help="CSR description file")
|
||||
parser.add_argument("--end_signature_addr", type=str, default="0",
|
||||
help="Address that privileged CSR test writes to at EOT")
|
||||
parser.add_argument("--isa", type=str, default="rv64imc",
|
||||
help="RISC-V ISA subset")
|
||||
parser.add_argument("--mabi", type=str, default="lp64",
|
||||
help="mabi used for compilation, lp32 or lp64")
|
||||
parser.add_argument("--test", type=str, default="all",
|
||||
help="Test name, 'all' means all tests in the list")
|
||||
parser.add_argument("--seed", type=int, default=-1,
|
||||
help="Randomization seed, default -1 means random seed")
|
||||
parser.add_argument("--iterations", type=int, default=0,
|
||||
help="Override the iteration count in the test list")
|
||||
parser.add_argument("--simulator", type=str, default="vcs",
|
||||
help="Simulator used to run the generator, default VCS")
|
||||
parser.add_argument("--simulator_yaml", type=str, default="",
|
||||
help="RTL simulator setting YAML")
|
||||
parser.add_argument("--iss", type=str, default="spike",
|
||||
help="RISC-V instruction set simulator: spike, ovpsim")
|
||||
parser.add_argument("--iss_yaml", type=str, default="",
|
||||
help="ISS setting YAML")
|
||||
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
|
||||
help="Verbose logging")
|
||||
parser.add_argument("--co", dest="co", action="store_true",
|
||||
help="Compile the generator only")
|
||||
parser.add_argument("--so", dest="so", action="store_true",
|
||||
help="Simulate the generator only")
|
||||
parser.add_argument("--cmp_opts", type=str, default="",
|
||||
help="Compile options for the generator")
|
||||
parser.add_argument("--sim_opts", type=str, default="",
|
||||
help="Simulation options for the generator")
|
||||
parser.add_argument("--steps", type=str, default="all",
|
||||
help="Run steps: gen,gcc_compile,iss_sim,iss_cmp")
|
||||
parser.add_argument("--lsf_cmd", type=str, default="",
|
||||
help="LSF command. Run in local sequentially if lsf \
|
||||
command is not specified")
|
||||
parser.add_argument("--gen_timeout", type=int, default=360,
|
||||
help="Generator timeout limit in seconds")
|
||||
parser.add_argument("--iss_timeout", type=int, default=50,
|
||||
help="ISS sim timeout limit in seconds")
|
||||
|
||||
if not args.iss_yaml:
|
||||
args.iss_yaml = cwd + "/yaml/iss.yaml"
|
||||
parser.set_defaults(co=False)
|
||||
parser.set_defaults(so=False)
|
||||
parser.set_defaults(verbose=False)
|
||||
|
||||
if not args.simulator_yaml:
|
||||
args.simulator_yaml = cwd + "/yaml/simulator.yaml"
|
||||
return parser
|
||||
|
||||
if not args.testlist:
|
||||
args.testlist = cwd + "/yaml/testlist.yaml"
|
||||
|
||||
# Create output directory
|
||||
subprocess.run(["mkdir", "-p", args.o])
|
||||
subprocess.run(["mkdir", "-p", ("%s/asm_tests" % args.o)])
|
||||
def setup_logging(verbose):
|
||||
"""Setup the root logger.
|
||||
|
||||
# Process regression test list
|
||||
matched_list = []
|
||||
process_regression_list(args.testlist, args.test, args.iterations, matched_list)
|
||||
if len(matched_list) == 0:
|
||||
sys.exit("Cannot find %s in %s" % (args.test, args.testlist))
|
||||
Args:
|
||||
verbose: Verbose logging
|
||||
"""
|
||||
if verbose:
|
||||
logging.basicConfig(format="%(asctime)s %(filename)s:%(lineno)-5s %(levelname)-8s %(message)s",
|
||||
datefmt='%a, %d %b %Y %H:%M:%S',
|
||||
level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(format="%(asctime)s %(levelname)-8s %(message)s",
|
||||
datefmt='%a, %d %b %Y %H:%M:%S',
|
||||
level=logging.INFO)
|
||||
|
||||
# Run instruction generator
|
||||
if args.steps == "all" or re.match("gen", args.steps):
|
||||
gen(matched_list, args.simulator, args.simulator_yaml, args.o,
|
||||
args.so, args.co, args.lsf_cmd, args.seed, cwd,
|
||||
args.cmp_opts, args.sim_opts, args.gen_timeout, args.verbose)
|
||||
|
||||
# Compile the assembly program to ELF, convert to plain binary
|
||||
if args.steps == "all" or re.match("gcc_compile", args.steps):
|
||||
gcc_compile(matched_list, args.o, args.isa, args.mabi, args.verbose)
|
||||
def main():
|
||||
"""This is the main entry point."""
|
||||
|
||||
# Run ISS simulation
|
||||
if args.steps == "all" or re.match("iss_sim", args.steps):
|
||||
iss_sim(matched_list, args.o, args.iss, args.iss_yaml,
|
||||
args.isa, args.iss_timeout, args.verbose)
|
||||
parser = setup_parser()
|
||||
args = parser.parse_args()
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
setup_logging(args.verbose)
|
||||
|
||||
# Compare ISS simulation result
|
||||
if args.steps == "all" or re.match("iss_cmp", args.steps):
|
||||
iss_cmp(matched_list, args.iss, args.o, args.isa, args.verbose)
|
||||
if not args.iss_yaml:
|
||||
args.iss_yaml = cwd + "/yaml/iss.yaml"
|
||||
|
||||
if not args.simulator_yaml:
|
||||
args.simulator_yaml = cwd + "/yaml/simulator.yaml"
|
||||
|
||||
if not args.testlist:
|
||||
args.testlist = cwd + "/yaml/testlist.yaml"
|
||||
|
||||
# Create output directory
|
||||
if args.o is None:
|
||||
output_dir = "out_" + str(date.today())
|
||||
else:
|
||||
output_dir = args.o
|
||||
subprocess.run(["mkdir", "-p", output_dir])
|
||||
subprocess.run(["mkdir", "-p", ("%s/asm_tests" % output_dir)])
|
||||
|
||||
# Process regression test list
|
||||
matched_list = []
|
||||
process_regression_list(args.testlist, args.test, args.iterations, matched_list)
|
||||
if len(matched_list) == 0:
|
||||
sys.exit("Cannot find %s in %s" % (args.test, args.testlist))
|
||||
|
||||
# Run instruction generator
|
||||
if args.steps == "all" or re.match("gen", args.steps):
|
||||
gen(matched_list, args.csr_yaml, args.end_signature_addr, args.isa,
|
||||
args.simulator, args.simulator_yaml, output_dir, args.so,
|
||||
args.co, args.lsf_cmd, args.seed, cwd, args.cmp_opts,
|
||||
args.sim_opts, args.gen_timeout)
|
||||
|
||||
if not args.co:
|
||||
# Compile the assembly program to ELF, convert to plain binary
|
||||
if args.steps == "all" or re.match("gcc_compile", args.steps):
|
||||
gcc_compile(matched_list, output_dir, args.isa, args.mabi)
|
||||
|
||||
# Run ISS simulation
|
||||
if args.steps == "all" or re.match("iss_sim", args.steps):
|
||||
iss_sim(matched_list, output_dir, args.iss, args.iss_yaml,
|
||||
args.isa, args.iss_timeout)
|
||||
|
||||
# Compare ISS simulation result
|
||||
if args.steps == "all" or re.match("iss_cmp", args.steps):
|
||||
iss_cmp(matched_list, args.iss, output_dir, args.isa)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
0
vendor/google_riscv-dv/scripts/__init__.py
vendored
Normal file
0
vendor/google_riscv-dv/scripts/__init__.py
vendored
Normal file
165
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
165
vendor/google_riscv-dv/scripts/gen_csr_test.py
vendored
|
@ -33,6 +33,12 @@ import argparse
|
|||
import random
|
||||
from bitstring import BitArray as bitarray
|
||||
|
||||
"""
|
||||
Defines the test's success/failure values, one of which will be written to
|
||||
the chosen signature address to indicate the test's result.
|
||||
"""
|
||||
PASS_VAL = 1
|
||||
FAIL_VAL = 0
|
||||
|
||||
def get_csr_map(csr_file, xlen):
|
||||
"""
|
||||
|
@ -44,7 +50,7 @@ def get_csr_map(csr_file, xlen):
|
|||
|
||||
Returns:
|
||||
A dictionary contining mappings for each CSR, of the form:
|
||||
{ csr_name : [csr_val_bitarray, csr_mask_bitarray] }
|
||||
{ csr_name : [csr_address, csr_val_bitarray, csr_write_mask_bitarray, csr_read_mask_bitarray] }
|
||||
"""
|
||||
rv_string = "rv{}".format(str(xlen))
|
||||
csrs = {}
|
||||
|
@ -52,23 +58,28 @@ def get_csr_map(csr_file, xlen):
|
|||
csr_description = yaml.safe_load(c)
|
||||
for csr_dict in csr_description:
|
||||
csr_name = csr_dict.get("csr")
|
||||
csr_address = csr_dict.get("address")
|
||||
assert(rv_string in csr_dict), "The {} CSR must be configured for rv{}".format(csr_name, str(rv))
|
||||
csr_value = bitarray(uintbe=0, length=xlen)
|
||||
csr_mask = bitarray(uintbe=0, length=xlen)
|
||||
csr_write_mask = []
|
||||
csr_read_mask = bitarray(uintbe=0, length=xlen)
|
||||
csr_field_list = csr_dict.get(rv_string)
|
||||
for csr_field_detail_dict in csr_field_list:
|
||||
field_type = csr_field_detail_dict.get("type")
|
||||
field_val = csr_field_detail_dict.get("reset_val")
|
||||
field_msb = csr_field_detail_dict.get("msb")
|
||||
field_lsb = csr_field_detail_dict.get("lsb")
|
||||
field_size = field_msb - field_lsb
|
||||
field_size = field_msb - field_lsb + 1
|
||||
if field_type != "WPRI":
|
||||
val_size = field_msb - field_lsb + 1
|
||||
val_bitarray = bitarray(uint=field_val, length=val_size)
|
||||
mask_bitarray = bitarray(uint=1, length=1) * val_size
|
||||
val_bitarray = bitarray(uint=field_val, length=field_size)
|
||||
mask_bitarray = bitarray(uint=1, length=1) * field_size
|
||||
start_pos = xlen - 1 - field_msb
|
||||
end_pos = xlen - 1 - field_lsb
|
||||
csr_read_mask.overwrite(mask_bitarray, xlen - 1 - field_msb)
|
||||
csr_value.overwrite(val_bitarray, xlen - 1 - field_msb)
|
||||
csr_mask.overwrite(mask_bitarray, xlen - 1 - field_msb)
|
||||
csrs.update({csr_name : [csr_value, csr_mask]})
|
||||
access = True if field_type == "R" else False
|
||||
csr_write_mask.append([mask_bitarray, (start_pos, end_pos), access])
|
||||
csrs.update({csr_name : [csr_address, csr_value, csr_write_mask, csr_read_mask]})
|
||||
return csrs
|
||||
|
||||
|
||||
|
@ -102,38 +113,46 @@ def get_rs1_val(iteration, xlen):
|
|||
return val
|
||||
|
||||
|
||||
def csr_write(val, csr_val, csr_mask):
|
||||
def csr_write(val, csr_val, csr_write_mask):
|
||||
"""
|
||||
Performs a CSR write.
|
||||
|
||||
Args:
|
||||
val: A bitarray containing the value to be written.
|
||||
csr_val: A bitarray containing the current CSR value.
|
||||
csr_mask: A bitarray containing the CSR's mask.
|
||||
csr_write_mask: A bitarray containing the CSR's mask.
|
||||
"""
|
||||
if val.len != csr_mask.len:
|
||||
csr_val.overwrite(val & csr_mask, 0)
|
||||
for bitslice in csr_write_mask:
|
||||
read_only = bitslice[2]
|
||||
start_index = bitslice[1][0]
|
||||
end_index = bitslice[1][1]
|
||||
length = end_index - start_index + 1
|
||||
mask_val = bitslice[0]
|
||||
# only write if not read only
|
||||
if not read_only:
|
||||
val_slice = val[start_index:end_index+1]
|
||||
csr_val.overwrite(mask_val & val_slice, start_index)
|
||||
|
||||
|
||||
"""
|
||||
CSR Read:
|
||||
Reads the given CSR, after applying the bitmask
|
||||
"""
|
||||
def csr_read(csr_val, csr_mask):
|
||||
def csr_read(csr_val, csr_read_mask):
|
||||
"""
|
||||
Performs a CSR read.
|
||||
|
||||
Args:
|
||||
csr_val: A bitarray containing the current CSR value.
|
||||
csr_mask: A bitarray containing the CSR's mask.
|
||||
csr_read_mask: A bitarray containing the CSR's read mask.
|
||||
|
||||
Returns:
|
||||
A bitarray of the logical AND of csr_val and csr_mask.
|
||||
A bitarray of the logical AND of csr_val and csr_read_mask.
|
||||
"""
|
||||
return csr_val & csr_mask
|
||||
return csr_val & csr_read_mask
|
||||
|
||||
|
||||
def predict_csr_val(csr_op, rs1_val, csr_val, csr_mask):
|
||||
def predict_csr_val(csr_op, rs1_val, csr_val, csr_write_mask, csr_read_mask):
|
||||
"""
|
||||
Predicts the CSR reference value, based on the current CSR operation.
|
||||
|
||||
|
@ -141,7 +160,8 @@ def predict_csr_val(csr_op, rs1_val, csr_val, csr_mask):
|
|||
csr_op: A string of the CSR operation being performed.
|
||||
rs1_val: A bitarray containing the value to be written to the CSR.
|
||||
csr_val: A bitarray containing the current value of the CSR.
|
||||
csr_mask: A bitarray containing the CSR's mask.
|
||||
csr_write_mask: A bitarray containing the CSR's write mask.
|
||||
csr_read_mask: A bitarray containing the CSR's read mask
|
||||
|
||||
Returns:
|
||||
A hexadecimal string of the predicted CSR value.
|
||||
|
@ -150,58 +170,82 @@ def predict_csr_val(csr_op, rs1_val, csr_val, csr_mask):
|
|||
# create a zero bitarray to zero extend immediates
|
||||
zero = bitarray(uint=0, length=csr_val.len - 5)
|
||||
if csr_op == 'csrrw':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
csr_write(rs1_val, csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
csr_write(rs1_val, csr_val, csr_write_mask)
|
||||
elif csr_op == 'csrrs':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
csr_write(rs1_val | prediction, csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
csr_write(rs1_val | prediction, csr_val, csr_write_mask)
|
||||
elif csr_op == 'csrrc':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
csr_write((~rs1_val) & prediction, csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
csr_write((~rs1_val) & prediction, csr_val, csr_write_mask)
|
||||
elif csr_op == 'csrrwi':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
zero.append(rs1_val[-5:])
|
||||
csr_write(zero, csr_val, csr_mask)
|
||||
csr_write(zero, csr_val, csr_write_mask)
|
||||
elif csr_op == 'csrrsi':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
zero.append(rs1_val[-5:])
|
||||
csr_write(zero | prediction, csr_val, csr_mask)
|
||||
csr_write(zero | prediction, csr_val, csr_write_mask)
|
||||
elif csr_op == 'csrrci':
|
||||
prediction = csr_read(csr_val, csr_mask)
|
||||
prediction = csr_read(csr_val, csr_read_mask)
|
||||
zero.append(rs1_val[-5:])
|
||||
csr_write((~zero) & prediction, csr_val, csr_mask)
|
||||
csr_write((~zero) & prediction, csr_val, csr_write_mask)
|
||||
return f"0x{prediction.hex}"
|
||||
|
||||
|
||||
def gen_csr_test_fail(test_file):
|
||||
def gen_setup(test_file):
|
||||
"""
|
||||
Generates the setup code for the CSR test.
|
||||
|
||||
Args:
|
||||
test_file: the file containing the generated assembly code.
|
||||
"""
|
||||
test_file.write(f".macro init\n")
|
||||
test_file.write(f".endm\n")
|
||||
test_file.write(f".section .text.init\n")
|
||||
test_file.write(f".globl _start\n")
|
||||
test_file.write(f".option norvc\n")
|
||||
for i in range(32):
|
||||
test_file.write(f"j csr_fail\n")
|
||||
test_file.write(f"_start:\n")
|
||||
|
||||
|
||||
def gen_csr_test_fail(test_file, end_addr):
|
||||
"""
|
||||
Generates code to handle a test failure.
|
||||
This code consists of writing 1 to the GP register in an infinite loop.
|
||||
The testbench will poll this register at the end of the test to detect failure.
|
||||
|
||||
Args:
|
||||
The file containing the generated assembly test code.
|
||||
test_file: the file containing the generated assembly test code.
|
||||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_fail:\n")
|
||||
test_file.write(f"\tli gp, 1\n")
|
||||
test_file.write(f"\tli x1, {FAIL_VAL}\n")
|
||||
test_file.write(f"\tli x2, {end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_fail\n")
|
||||
|
||||
|
||||
def gen_csr_test_pass(test_file):
|
||||
def gen_csr_test_pass(test_file, end_addr):
|
||||
"""
|
||||
Generates code to handle test success.
|
||||
This code consists of writing 2 to the GP register in an infinite loop.
|
||||
The testbench will poll this register at the end of the test to detect success.
|
||||
|
||||
Args:
|
||||
The file containing the generated assembly test code.
|
||||
test_file: the file containing the generated assembly test code.
|
||||
end_addr: address that should be written to at end of test
|
||||
"""
|
||||
test_file.write(f"csr_pass:\n")
|
||||
test_file.write(f"\tli gp, 1\n")
|
||||
test_file.write(f"\tli x1, {PASS_VAL}\n")
|
||||
test_file.write(f"\tli x2, {end_addr}\n")
|
||||
test_file.write(f"\tsw x1, 0(x2)\n")
|
||||
test_file.write(f"\tj csr_pass\n")
|
||||
|
||||
|
||||
def gen_csr_instr(csr_map, csr_instructions, xlen, iterations, out):
|
||||
def gen_csr_instr(csr_map, csr_instructions, xlen,
|
||||
iterations, out, end_signature_addr):
|
||||
"""
|
||||
Uses the information in the map produced by get_csr_map() to generate
|
||||
test CSR instructions operating on the generated random values.
|
||||
|
@ -212,6 +256,7 @@ def gen_csr_instr(csr_map, csr_instructions, xlen, iterations, out):
|
|||
xlen: The RISC-V ISA bit length.
|
||||
iterations: Indicates how many randomized test files will be generated.
|
||||
out: A string containing the directory path that the tests will be generated in.
|
||||
end_signature_addr: The address the test should write to upon terminating
|
||||
|
||||
Returns:
|
||||
No explicit return value, but will write the randomized assembly test code
|
||||
|
@ -220,13 +265,13 @@ def gen_csr_instr(csr_map, csr_instructions, xlen, iterations, out):
|
|||
for i in range(iterations):
|
||||
# pick two GPRs at random to act as source and destination registers
|
||||
# for CSR operations
|
||||
source_reg, dest_reg = [f"x{i}" for i in random.sample(range(5, 15), 2)]
|
||||
source_reg, dest_reg = [f"x{i}" for i in random.sample(range(1, 16), 2)]
|
||||
csr_list = list(csr_map.keys())
|
||||
with open(f"{out}/riscv_csr_test.{i}.S", "w") as csr_test_file:
|
||||
csr_test_file.write(f"csr_test:\n")
|
||||
gen_setup(csr_test_file)
|
||||
for csr in csr_list:
|
||||
last_csr = csr
|
||||
csr_val, csr_mask = csr_map.get(csr)
|
||||
csr_address, csr_val, csr_write_mask, csr_read_mask = csr_map.get(csr)
|
||||
csr_test_file.write(f"\t# {csr}\n")
|
||||
for op in csr_instructions:
|
||||
for i in range(3):
|
||||
# hex string
|
||||
|
@ -235,11 +280,16 @@ def gen_csr_instr(csr_map, csr_instructions, xlen, iterations, out):
|
|||
first_li = ""
|
||||
if op[-1] == "i":
|
||||
imm = rand_rs1_val[-5:]
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr}, 0b{imm.bin}\n"
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr_address}, 0b{imm.bin}\n"
|
||||
imm_val = bitarray(uint=0, length=xlen-5)
|
||||
imm_val.append(imm)
|
||||
predict_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val(op, imm_val, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
else:
|
||||
first_li = f"\tli {source_reg}, 0x{rand_rs1_val.hex}\n"
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr}, {source_reg}\n"
|
||||
predict_li = f"\tli {source_reg}, {predict_csr_val(op, rand_rs1_val, csr_val, csr_mask)}\n"
|
||||
csr_inst = f"\t{op} {dest_reg}, {csr_address}, {source_reg}\n"
|
||||
predict_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val(op, rand_rs1_val, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
branch_check = f"\tbne {source_reg}, {dest_reg}, csr_fail\n"
|
||||
csr_test_file.write(first_li)
|
||||
csr_test_file.write(csr_inst)
|
||||
|
@ -250,25 +300,32 @@ def gen_csr_instr(csr_map, csr_instructions, xlen, iterations, out):
|
|||
been written to the CSR has not been tested.
|
||||
"""
|
||||
if csr == csr_list[-1] and op == csr_instructions[-1] and i == 2:
|
||||
final_csr_read = f"\tcsrr {dest_reg}, {csr_list[-1]}\n"
|
||||
final_csr_read = f"\tcsrr {dest_reg}, {csr_address}\n"
|
||||
csrrs_read_mask = bitarray(uint=0, length=xlen)
|
||||
final_li = f"\tli {source_reg}, {predict_csr_val('csrrs', csrrs_read_mask, csr_val, csr_mask)}\n"
|
||||
final_li = (f"\tli {source_reg}, "
|
||||
f"{predict_csr_val('csrrs', csrrs_read_mask, csr_val, csr_write_mask, csr_read_mask)}\n")
|
||||
final_branch_check = f"\tbne {source_reg}, {dest_reg}, csr_fail\n"
|
||||
csr_test_file.write(final_csr_read)
|
||||
csr_test_file.write(final_li)
|
||||
csr_test_file.write(final_branch_check)
|
||||
gen_csr_test_pass(csr_test_file)
|
||||
gen_csr_test_fail(csr_test_file)
|
||||
gen_csr_test_pass(csr_test_file, end_signature_addr)
|
||||
gen_csr_test_fail(csr_test_file, end_signature_addr)
|
||||
|
||||
|
||||
"""
|
||||
Define command line arguments.
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--csr_file", type=str, help="The YAML file contating descriptions of all processor supported CSRs")
|
||||
parser.add_argument("--xlen", type=int, default=32, help="Specify the ISA width, e.g. 32 or 64 or 128")
|
||||
parser.add_argument("--num_test", type=int, default=1, help="Specify how many tests to be generated")
|
||||
parser.add_argument("--out", type=str, default="./", help="Specify output directory")
|
||||
parser.add_argument("--csr_file", type=str, default="yaml/csr_template.yaml",
|
||||
help="The YAML file contating descriptions of all processor supported CSRs")
|
||||
parser.add_argument("--xlen", type=int, default=32,
|
||||
help="Specify the ISA width, e.g. 32 or 64 or 128")
|
||||
parser.add_argument("--iterations", type=int, default=1,
|
||||
help="Specify how many tests to be generated")
|
||||
parser.add_argument("--out", type=str, default="./",
|
||||
help="Specify output directory")
|
||||
parser.add_argument("--end_signature_addr", type=str, default="0",
|
||||
help="Address that should be written to at end of this test")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
|
@ -277,4 +334,6 @@ A list containing all supported CSR instructions.
|
|||
"""
|
||||
csr_ops = ['csrrw', 'csrrs', 'csrrc', 'csrrwi', 'csrrsi', 'csrrci']
|
||||
|
||||
gen_csr_instr(get_csr_map(args.csr_file, args.xlen), csr_ops, args.xlen, args.num_test, args.out)
|
||||
gen_csr_instr(get_csr_map(args.csr_file, args.xlen),
|
||||
csr_ops, args.xlen, args.iterations, args.out,
|
||||
args.end_signature_addr)
|
||||
|
|
32
vendor/google_riscv-dv/scripts/lib.py
vendored
32
vendor/google_riscv-dv/scripts/lib.py
vendored
|
@ -22,6 +22,7 @@ import sys
|
|||
import subprocess
|
||||
import time
|
||||
import yaml
|
||||
import logging
|
||||
|
||||
def read_yaml(yaml_file):
|
||||
""" Read YAML file to a dictionary
|
||||
|
@ -36,7 +37,7 @@ def read_yaml(yaml_file):
|
|||
try:
|
||||
yaml_data = yaml.safe_load(f)
|
||||
except yaml.YAMLError as exc:
|
||||
print(exc)
|
||||
logging.error(exc)
|
||||
sys.exit(1)
|
||||
return yaml_data
|
||||
|
||||
|
@ -53,7 +54,7 @@ def get_env_var(var):
|
|||
try:
|
||||
val = os.environ[var]
|
||||
except KeyError:
|
||||
print ("Please set the environment variable %0s" % var)
|
||||
logging.warning("Please set the environment variable %0s" % var)
|
||||
sys.exit(1)
|
||||
return val
|
||||
|
||||
|
@ -73,7 +74,7 @@ def get_seed(seed):
|
|||
return random.getrandbits(32)
|
||||
|
||||
|
||||
def run_cmd(cmd, verbose = 0, timeout_s = 999):
|
||||
def run_cmd(cmd, timeout_s = 999):
|
||||
"""Run a command and return output
|
||||
|
||||
Args:
|
||||
|
@ -89,20 +90,19 @@ def run_cmd(cmd, verbose = 0, timeout_s = 999):
|
|||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
print(ps.communicate()[0])
|
||||
logging.error(ps.communicate()[0])
|
||||
sys.exit(1)
|
||||
try:
|
||||
output = ps.communicate(timeout = timeout_s)[0]
|
||||
except subprocess.TimeoutExpired:
|
||||
print("Timeout[%ds]: %s" % (timeout_s, cmd))
|
||||
logging.error("Timeout[%ds]: %s" % (timeout_s, cmd))
|
||||
output = ""
|
||||
ps.kill()
|
||||
if verbose:
|
||||
print(output)
|
||||
logging.debug(output)
|
||||
return output
|
||||
|
||||
|
||||
def run_parallel_cmd(cmd_list, verbose = 0, timeout_s = 999):
|
||||
def run_parallel_cmd(cmd_list, timeout_s = 999):
|
||||
"""Run a list of commands in parallel
|
||||
|
||||
Args:
|
||||
|
@ -120,18 +120,16 @@ def run_parallel_cmd(cmd_list, verbose = 0, timeout_s = 999):
|
|||
stderr=subprocess.STDOUT)
|
||||
children.append(ps)
|
||||
for i in range(len(children)):
|
||||
print("Command progress: %d/%d" % (i, len(children)))
|
||||
if verbose:
|
||||
print("Waiting for command: %s" % cmd_list[i])
|
||||
logging.info("Command progress: %d/%d" % (i, len(children)))
|
||||
logging.debug("Waiting for command: %s" % cmd_list[i])
|
||||
try:
|
||||
output = children[i].communicate(timeout = timeout_s)[0]
|
||||
except subprocess.TimeoutExpired:
|
||||
print("Timeout[%ds]: %s" % (timeout_s, cmd))
|
||||
logging.error("Timeout[%ds]: %s" % (timeout_s, cmd))
|
||||
children[i].kill()
|
||||
# Restore stty setting otherwise the terminal may go crazy
|
||||
os.system("stty sane")
|
||||
if verbose:
|
||||
print(output)
|
||||
logging.debug(output)
|
||||
|
||||
|
||||
def process_regression_list(testlist, test, iterations, matched_list):
|
||||
|
@ -145,13 +143,13 @@ def process_regression_list(testlist, test, iterations, matched_list):
|
|||
Returns:
|
||||
matched_list : A list of matched tests
|
||||
"""
|
||||
print("Processing regression test list : %s, test: %s" % (testlist, test))
|
||||
logging.info("Processing regression test list : %s, test: %s" % (testlist, test))
|
||||
yaml_data = read_yaml(testlist)
|
||||
for entry in yaml_data:
|
||||
if (entry['test'] == test) or (test == "all"):
|
||||
if iterations > 0:
|
||||
entry['iterations'] = iterations
|
||||
if entry['iterations'] > 0:
|
||||
print ("Found matched tests: %s, iterations:%0d" %
|
||||
(entry['test'], entry['iterations']))
|
||||
logging.info("Found matched tests: %s, iterations:%0d" %
|
||||
(entry['test'], entry['iterations']))
|
||||
matched_list.append(entry)
|
||||
|
|
|
@ -18,6 +18,7 @@ Convert ovpsim sim log to standard riscv instruction trace format
|
|||
import re
|
||||
import os
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from riscv_trace_csv import *
|
||||
|
||||
|
@ -27,7 +28,7 @@ def process_ovpsim_sim_log(ovpsim_log, csv):
|
|||
Extract instruction and affected register information from ovpsim simulation
|
||||
log and save to a list.
|
||||
"""
|
||||
print("Processing ovpsim log : %s" % ovpsim_log)
|
||||
logging.info("Processing ovpsim log : %s" % ovpsim_log)
|
||||
instr_cnt = 0
|
||||
trace_instr = ""
|
||||
trace_bin = ""
|
||||
|
@ -66,7 +67,7 @@ def process_ovpsim_sim_log(ovpsim_log, csv):
|
|||
rv_instr_trace.binary = trace_bin
|
||||
rv_instr_trace.addr = trace_addr
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
print("Processed instruction count : %d" % instr_cnt)
|
||||
logging.info("Processed instruction count : %d" % instr_cnt)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -20,6 +20,7 @@ import argparse
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import logging
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
|
@ -31,7 +32,7 @@ def process_spike_sim_log(spike_log, csv):
|
|||
Extract instruction and affected register information from spike simulation
|
||||
log and save to a list.
|
||||
"""
|
||||
print("Processing spike log : %s" % spike_log)
|
||||
logging.info("Processing spike log : %s" % spike_log)
|
||||
instr_cnt = 0
|
||||
spike_instr = ""
|
||||
|
||||
|
@ -65,7 +66,7 @@ def process_spike_sim_log(spike_log, csv):
|
|||
rv_instr_trace.binary = m.group("bin")
|
||||
rv_instr_trace.instr_str = spike_instr
|
||||
trace_csv.write_trace_entry(rv_instr_trace)
|
||||
print("Processed instruction count : %d" % instr_cnt)
|
||||
logging.info("Processed instruction count : %d" % instr_cnt)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -199,13 +199,17 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
virtual function void gen_kernel_sections();
|
||||
instr_stream.push_back("_kernel_start: .align 12");
|
||||
// Kernel programs
|
||||
smode_accessible_umode_program = riscv_instr_sequence::type_id::
|
||||
create("smode_accessible_umode_program");
|
||||
if (cfg.init_privileged_mode != MACHINE_MODE) begin
|
||||
smode_accessible_umode_program = riscv_instr_sequence::type_id::
|
||||
create("smode_accessible_umode_program");
|
||||
gen_kernel_program(smode_accessible_umode_program);
|
||||
end
|
||||
smode_program = riscv_instr_sequence::type_id::create("smode_program");
|
||||
gen_kernel_program(smode_accessible_umode_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);
|
||||
if (cfg.init_privileged_mode != MACHINE_MODE) begin
|
||||
smode_ls_umem_program = riscv_instr_sequence::type_id::create("smode_ls_umem_program");
|
||||
gen_kernel_program(smode_ls_umem_program);
|
||||
end
|
||||
// All trap/interrupt handling is in the kernel region
|
||||
// Trap/interrupt delegation to user mode is not supported now
|
||||
// Trap handler
|
||||
|
|
|
@ -79,6 +79,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
bit no_ebreak = 1; // No ebreak instruction
|
||||
bit no_fence; // No fence instruction
|
||||
bit no_wfi = 1; // No WFI instruction
|
||||
bit enable_unaligned_load_store;
|
||||
bit enable_illegal_instruction;
|
||||
bit enable_hint_instruction;
|
||||
int bin_program_instr_cnt = 200;
|
||||
|
@ -249,6 +250,7 @@ class riscv_instr_gen_config extends uvm_object;
|
|||
get_bool_arg_value("+no_directed_instr=", no_directed_instr);
|
||||
get_bool_arg_value("+no_fence=", no_fence);
|
||||
get_bool_arg_value("+no_delegation=", no_delegation);
|
||||
get_bool_arg_value("+enable_unaligned_load_store=", enable_unaligned_load_store);
|
||||
get_bool_arg_value("+enable_illegal_instruction=", enable_illegal_instruction);
|
||||
get_bool_arg_value("+enable_hint_instruction=", enable_hint_instruction);
|
||||
get_bool_arg_value("+force_m_delegation=", force_m_delegation);
|
||||
|
|
|
@ -121,7 +121,11 @@ class riscv_load_store_base_instr_stream extends riscv_directed_instr_stream;
|
|||
`DV_CHECK_RANDOMIZE_WITH_FATAL(rand_instr,
|
||||
solve rs1 before rd;
|
||||
rs1 == rs1_reg;
|
||||
instr_name inside {allowed_instr};
|
||||
if (!cfg.enable_unaligned_load_store) {
|
||||
instr_name inside {allowed_instr};
|
||||
} else {
|
||||
category inside {LOAD, STORE};
|
||||
}
|
||||
if(avail_regs.size() > 0) {
|
||||
rd inside {avail_regs};
|
||||
}
|
||||
|
|
|
@ -64,26 +64,28 @@ class riscv_instr_base_test extends uvm_test;
|
|||
endfunction
|
||||
|
||||
function void get_directed_instr_stream_opts();
|
||||
string instr_name;
|
||||
int ratio;
|
||||
string cmd_opts_prefix;
|
||||
string opts;
|
||||
string opt[$];
|
||||
int i = 0;
|
||||
while(1) begin
|
||||
cmd_opts_prefix = $sformatf("directed_instr_%0d", i);
|
||||
if($value$plusargs({cmd_opts_prefix, "=%0s"}, instr_name) &&
|
||||
$value$plusargs({cmd_opts_prefix, "_ratio=%0d"}, ratio)) begin
|
||||
asm_gen.add_directed_instr_stream(instr_name, ratio);
|
||||
if($value$plusargs({cmd_opts_prefix, "=%0s"}, opts)) begin
|
||||
uvm_split_string(opts, ",", opt);
|
||||
`DV_CHECK_FATAL(opt.size() == 2)
|
||||
asm_gen.add_directed_instr_stream(opt[0], opt[1].atoi());
|
||||
end else begin
|
||||
break;
|
||||
end
|
||||
`uvm_info(`gfn, $sformatf("Got directed instr[%0d] %0s, ratio = %0d/1000",
|
||||
i, instr_name, ratio), UVM_LOW)
|
||||
`uvm_info(`gfn, $sformatf("Got directed instr[%0d] %0s, ratio = %0s/1000",
|
||||
i, opt[0], opt[1]), UVM_LOW)
|
||||
i++;
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
virtual function void apply_directed_instr();
|
||||
|
||||
endfunction
|
||||
|
||||
task run_phase(uvm_phase phase);
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
#- csr: CSR_NAME
|
||||
# description: >
|
||||
# BRIEF_DESCRIPTION
|
||||
# address: 0x###
|
||||
# privilege_mode: MODE (D/M/S/H/U)
|
||||
# rv32:
|
||||
# - MSB_FIELD_NAME:
|
||||
# - description: >
|
||||
# BRIEF_DESCRIPTION
|
||||
# - type: TYPE (WPRI/WLRL/WARL)
|
||||
# - type: TYPE (WPRI/WLRL/WARL/R)
|
||||
# - reset_val: RESET_VAL
|
||||
# - msb: MSB_POS
|
||||
# - lsb: LSB_POS
|
||||
|
@ -36,7 +37,7 @@
|
|||
# - MSB_FIELD_NAME:
|
||||
# - description: >
|
||||
# BRIEF_DESCRIPTION
|
||||
# - type: TYPE (WPRI/WLRL/WARL)
|
||||
# - type: TYPE (WPRI/WLRL/WARL/R)
|
||||
# - reset_val: RESET_VAL
|
||||
# - msb: MSB_POS
|
||||
# - lsb: LSB_POS
|
||||
|
@ -53,6 +54,7 @@
|
|||
- csr: misa
|
||||
description: >
|
||||
Machine ISA Register
|
||||
address: 0x301
|
||||
privilege_mode: M
|
||||
rv32:
|
||||
- field_name: MXL
|
||||
|
|
21
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
21
vendor/google_riscv-dv/yaml/simulator.yaml
vendored
|
@ -36,15 +36,16 @@
|
|||
compile_cmd:
|
||||
- "vmap mtiUvm $QUESTA_HOME/questasim/uvm-1.2"
|
||||
- "vlog -64
|
||||
 -access=rwc
|
||||
 -f <cwd>/files.f
|
||||
 -sv
|
||||
 -mfcu -cuname design_cuname
|
||||
 +define+UVM_REGEX_NO_DPI
|
||||
 -writetoplevels <out>/top.list
|
||||
 -l <out>/compile.log <cmp_opts>"
|
||||
-access=rwc
|
||||
-f <cwd>/files.f
|
||||
-sv
|
||||
-mfcu -cuname design_cuname
|
||||
+define+UVM_REGEX_NO_DPI
|
||||
-writetoplevels <out>/top.list
|
||||
-l <out>/compile.log <cmp_opts>"
|
||||
- "vopt -64 -debug
|
||||
 +designfile -f <out>/top.list
|
||||
 -o design_opt"
|
||||
+designfile -f <out>/top.list
|
||||
-l <out>/optimize.log <cmp_opts>
|
||||
-o design_opt"
|
||||
sim_cmd: >
|
||||
vsim -64 -c -do <cwd>/questa_sim.tcl design_opt <sim_opts> -svseed <seed>
|
||||
vsim -64 -c -do <cwd>/questa_sim.tcl design_opt <sim_opts> -sv_seed <seed>
|
||||
|
|
34
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
34
vendor/google_riscv-dv/yaml/testlist.yaml
vendored
|
@ -12,19 +12,21 @@
|
|||
# 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
|
||||
# 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
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# ----------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------------
|
||||
# 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
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
- test: riscv_arithmetic_basic_test
|
||||
description: >
|
||||
|
@ -205,3 +207,11 @@
|
|||
+enable_irq_seq=1
|
||||
compare_opts: >
|
||||
+compare_final_value_only=1
|
||||
|
||||
- test: riscv_csr_test
|
||||
description: >
|
||||
Test all CSR instructions on all implemented CSR registers
|
||||
iterations: 1
|
||||
no_iss: 1
|
||||
rtl_test: core_ibex_csr_test
|
||||
no_post_compare: 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue