mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
Update google_riscv-dv to google/riscv-dv@a655f34 (#564)
Update code from upstream repository https://github.com/google/riscv- dv to revision a655f34eb5058da442b38ca010b0d008291c11b5 * Support running C test (google/riscv-dv#453) (Hai Hoang Dang) * run.py: Do not compare csv file when specified -debug switch (google/riscv-dv#451) (Hai Hoang Dang) * adjust location of nested interrupt mstatus.mie enable (google/riscv-dv#444) (udinator) * Implement storing the commands that would be executed as a script (google/riscv-dv#450) (Hai Hoang Dang) * Move document from README to docs, add HTML preview for the new doc (google/riscv-dv#448) (taoliug) * Use single HTML format (google/riscv-dv#447) (taoliug) * Update HTML document (google/riscv-dv#446) (taoliug) * Add framework for custom extensions (google/riscv-dv#442) (taoliug) Signed-off-by: Udi <udij@google.com>
This commit is contained in:
parent
f95518a46e
commit
3d8089c235
21 changed files with 445 additions and 627 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: d23da3862f95954e6374aaec787e0fb0c1878a16
|
||||
rev: a655f34eb5058da442b38ca010b0d008291c11b5
|
||||
}
|
||||
}
|
||||
|
|
548
vendor/google_riscv-dv/README.md
vendored
548
vendor/google_riscv-dv/README.md
vendored
|
@ -16,20 +16,9 @@ processor verification. It currently supports the following features:
|
|||
- Supports mixing directed instructions with random instruction stream
|
||||
- Debug mode support, with fully randomized debug ROM
|
||||
- Instruction generation coverage model
|
||||
- Communication of information to any integrated SV testbench
|
||||
- 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.
|
||||
|
||||
## External contributions and collaborations
|
||||
|
||||
This repository is still under active development. We hope the RISC-V processor
|
||||
verification platform development to be a collaborative effort of the RISC-V
|
||||
community. Free feel to submit issues, feature requests, pull requests through
|
||||
Github. You can also send your private collaboration request to [riscv_dv_dev@google.com](riscv_dv_dev@google.com).
|
||||
Please refer to CONTRIBUTING.md for license related questions.
|
||||
- Handshake communication with testbench
|
||||
- Support handcoded assembly test
|
||||
- Co-simulation with multiple ISS : spike, riscv-ovpsim, whisper, sail-riscv
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
@ -73,533 +62,18 @@ run --help
|
|||
cov --help
|
||||
```
|
||||
|
||||
### Setup RISCV-GCC compiler toolchain
|
||||
## Document
|
||||
|
||||
- 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)
|
||||
To understand how to setup and customize the generator, please check the full document under docs directory. You can use the makefile to generate the document. [HTML preview](https://htmlpreview.github.io/?https://github.com/google/riscv-dv/blob/master/docs/build/singlehtml/index.html#document-index)
|
||||
|
||||
```bash
|
||||
# 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"
|
||||
```
|
||||
## External contributions and collaborations
|
||||
|
||||
### Setup ISS (instruction set simulator)
|
||||
This repository is still under active development. We hope the RISC-V processor
|
||||
verification platform development to be a collaborative effort of the RISC-V
|
||||
community. Free feel to submit issues, feature requests, pull requests through
|
||||
Github. You can also send your private collaboration request to [riscv_dv_dev@google.com](riscv_dv_dev@google.com).
|
||||
Please refer to CONTRIBUTING.md for license related questions.
|
||||
|
||||
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
|
||||
- Build 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
|
||||
- [whisper(swerv-ISS)](https://github.com/westerndigitalcorporation/swerv-ISS) setup
|
||||
- Follow the instruction to install the ISS, and set WHISPER_ISS to the
|
||||
whisper 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 path of sail-riscv binary
|
||||
|
||||
```bash
|
||||
export SPIKE_PATH=$RISCV_TOOLCHAIN/bin
|
||||
export SAIL_RISCV="xx/xxx/ocaml_emulator"
|
||||
export OVPSIM_PATH=/xx/xxx/riscv-ovpsim/bin/Linux64
|
||||
export WHISPER_ISS="xx/xxx/swerv-ISS/build-Linux/whisper"
|
||||
```
|
||||
|
||||
## Running the generator
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
run --help
|
||||
```
|
||||
|
||||
Here is the command to run a single test:
|
||||
|
||||
```bash
|
||||
run --test=riscv_arithmetic_basic_test
|
||||
```
|
||||
You can specify the simulator by "-simulator" option
|
||||
|
||||
```bash
|
||||
run --test riscv_arithmetic_basic_test --simulator ius
|
||||
run --test riscv_arithmetic_basic_test --simulator vcs
|
||||
run --test riscv_arithmetic_basic_test --simulator questa
|
||||
run --test riscv_arithmetic_basic_test --simulator dsim
|
||||
run --test riscv_arithmetic_basic_test --simulator qrun
|
||||
```
|
||||
The complete test list can be found in [yaml/base_testlist.yaml](https://github.com/google/riscv-dv/blob/master/yaml/base_testlist.yaml). To run a full
|
||||
regression, simply use below command
|
||||
|
||||
```bash
|
||||
run
|
||||
```
|
||||
|
||||
You can also run multiple generator jobs in parallel through LSF
|
||||
|
||||
```bash
|
||||
run --lsf_cmd="bsub -Is"
|
||||
```
|
||||
|
||||
Here's a few more examples of the run command:
|
||||
|
||||
```bash
|
||||
# Run a single test 10 times
|
||||
run --test riscv_arithmetic_basic_test --iterations 10
|
||||
|
||||
# Run multiple tests
|
||||
run --test riscv_arithmetic_basic_test,riscv_rand_instr_test
|
||||
|
||||
# Run a test with verbose logging
|
||||
run --test riscv_arithmetic_basic_test --verbose
|
||||
|
||||
# Run a test with a specified seed
|
||||
run --test riscv_arithmetic_basic_test --seed 123
|
||||
|
||||
# Skip the generation, run ISS simulation with previously generated program
|
||||
run --test riscv_arithmetic_basic_test --steps iss_sim
|
||||
|
||||
# Run the generator only, do not compile and simluation with ISS
|
||||
run --test riscv_arithmetic_basic_test --steps gen
|
||||
|
||||
# Compile the generator only, do not simulate
|
||||
run --test riscv_arithmetic_basic_test --co
|
||||
|
||||
....
|
||||
```
|
||||
|
||||
### Run ISS simulation
|
||||
|
||||
You can use -iss to run with different ISS.
|
||||
|
||||
```bash
|
||||
# Run ISS with spike
|
||||
run --test riscv_arithmetic_basic_test --iss spike
|
||||
|
||||
# Run ISS with riscv-ovpsim
|
||||
run --test riscv_rand_instr_test --iss ovpsim
|
||||
|
||||
# Run ISS with whisper (swerv-ISS)
|
||||
run --test riscv_rand_instr_test --iss whisper
|
||||
|
||||
# Run ISS with sail-riscv
|
||||
run --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:
|
||||
|
||||
```bash
|
||||
# Run a full regression with RV32IMC
|
||||
run --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.
|
||||
|
||||
```bash
|
||||
run --test=riscv_rand_instr_test --iss=spike,ovpsim
|
||||
run --test=riscv_rand_instr_test --iss=ovpsim,whisper
|
||||
run --test=riscv_rand_instr_test --iss=spike,sail
|
||||
```
|
||||
### Run directed assembly tests
|
||||
|
||||
Sometimes it might be useful to run some hand-coded assembly tests to hit some
|
||||
corner cases:
|
||||
|
||||
```bash
|
||||
# Run a single/multiple assembly test
|
||||
run --asm_tests asm_test_path1/asm_test1.S,asm_test_path2/asm_test2.S
|
||||
|
||||
# Run regression with all assembly tests(*.S) under a given directory
|
||||
run --asm_tests asm_test_path1,asm_test_path2
|
||||
|
||||
# Run mix between the assembly test and assembly tests under a directory
|
||||
run --asm_tests asm_test_path1/asm_test1.S,asm_test_path2
|
||||
```
|
||||
|
||||
You could also use this approach to integrate the assembly tests
|
||||
from other sources to riscv-dv flow.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Configure the generator to match your processor features
|
||||
|
||||
The default configuration of the instruction generator is **RV32IMC** (machine
|
||||
mode only). A few pre-defined configurations can be found under "target" directory,
|
||||
you can run with these targets if it matches your processor specification.
|
||||
|
||||
```bash
|
||||
run # Default target rv32imc
|
||||
run --target rv32i # rv32i, machine mode only
|
||||
run --target rv32imc # rv32imc, machine mode only
|
||||
run --target rv64imc # rv64imc, machine mode only
|
||||
run --target rv64gc # rv64gc, SV39, M/S/U mode
|
||||
```
|
||||
|
||||
If you want to have a custom setting for your processor, you can make a copy of
|
||||
existing target directory as the template, and modify riscv_core_setting.sv to
|
||||
match your processor capability.
|
||||
|
||||
```verilog
|
||||
// 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};
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
You can then run the generator with "--custom_target <target_dir>"
|
||||
|
||||
```bash
|
||||
# You need to manually specify isa and mabi for your custom target
|
||||
run --custom_target <target_dir> --isa <isa> --mabi <mabi>
|
||||
...
|
||||
```
|
||||
|
||||
### 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)
|
||||
|
||||
```verilog
|
||||
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)
|
||||
|
||||
```yaml
|
||||
# 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
|
||||
# asm_tests : Path to directed, hand-coded assembly test file or directory
|
||||
# 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: >
|
||||
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'b1
|
||||
+no_branch_jump=1'b1
|
||||
+boot_mode=m
|
||||
iterations: 2
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_csr_test
|
||||
description: >
|
||||
Stress CSR accesses on all implemented CSRs
|
||||
iterations: 2
|
||||
no_iss: 1
|
||||
rtl_test: core_base_test
|
||||
no_post_compare: 1
|
||||
|
||||
- test: riscv_directed_asm_test
|
||||
description: >
|
||||
Hand-coded assembly test to test corner case
|
||||
iterations: 1
|
||||
asm_tests: <asm_test_dir_path or asm_test_file path>
|
||||
rtl_test: core_base_test
|
||||
|
||||
```
|
||||
|
||||
Note: To automatically generate CSR stress tests without having to explicitly run the
|
||||
script, include a test entry `riscv_csr_test` in the testlist as shown in the
|
||||
example YAML file above.
|
||||
|
||||
|
||||
The generation flow now supports inclusion of handcoded assembly tests into the
|
||||
overall regression. To do this, simply create a YAML entry in the appropriate
|
||||
testlist as shown above in `riscv_directed_asm_test`, using the `asm_tests`
|
||||
field to point to the location of the assembly test file or directory.
|
||||
The run flow will then locate these file(s) and include them into the overall
|
||||
regression run. These directed test targets can also be run individually from
|
||||
the python script, as shown below:
|
||||
|
||||
```bash
|
||||
|
||||
# Run directed assembly test 10 times
|
||||
python3 run.py --test riscv_directed_asm_test --iterations 10
|
||||
|
||||
```
|
||||
|
||||
Note: when using the `asm_tests` field to specify some directed/handcoded
|
||||
assembly tests to the flow, make sure that the `gen_test` field is not defined,
|
||||
as this will cause the flow to throw an error.
|
||||
|
||||
|
||||
### 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 |
|
||||
| enable_unaligned_load_store | Enable unaligned memory operations | 0 |
|
||||
| no_ebreak | Disable ebreak instruction | 1 |
|
||||
| no_wfi | Disable WFI instruction | 1 |
|
||||
| no_dret | Disable dret 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 |
|
||||
| illegal_instr_ratio | Number of illegal instructions every 1000 instr | 0 |
|
||||
| hint_instr_ratio | Number of HINT instructions every 1000 instr | 0 |
|
||||
| boot_mode | m:Machine mode, s:Supervisor mode, u:User mode | m |
|
||||
| no_directed_instr | Disable directed instruction stream | 0 |
|
||||
| require_signature_addr | Set to 1 if test needs to talk to testbench | 0 |
|
||||
| signature_addr | Write to this addr to send data to testbench | 0 |
|
||||
| enable_interrupt | Enable MStatus.MIE, used in interrupt test | 0 |
|
||||
| gen_debug_section | Disables randomized debug_rom section | 0 |
|
||||
| num_debug_sub_program | Number of debug sub-programs in test | 0 |
|
||||
| enable_ebreak_in_debug_rom | Generate ebreak instructions inside debug ROM | 0 |
|
||||
| set_dcsr_ebreak | Randomly enable dcsr.ebreak(m/s/u) | 0 |
|
||||
| randomize_csr | Fully randomize main CSRs (xSTATUS, xIE) | 0 |
|
||||
|
||||
|
||||
### Setup Privileged CSR description (optional)
|
||||
|
||||
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)
|
||||
|
||||
```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.
|
||||
|
||||
### Privileged CSR Test Generation (optional)
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
python3 scripts/gen_csr_test.py --help
|
||||
```
|
||||
|
||||
### Adding new instruction stream and test
|
||||
|
||||
Please refer to src/src/riscv_load_store_instr_lib.sv for an example on how to
|
||||
add a new instruction stream.
|
||||
After the new instruction stream is created, you can use a runtime option to mix
|
||||
it with random instructions
|
||||
|
||||
```bash
|
||||
//+directed_instr_n=instr_sequence_name,frequency(number of insertions per 1000 instructions)
|
||||
+directed_instr_5=riscv_multi_page_load_store_instr_stream,4
|
||||
|
||||
// An alternative command line options for directed instruction stream
|
||||
+stream_name_0=riscv_multi_page_load_store_instr_stream
|
||||
+stream_freq_0=4
|
||||
```
|
||||
|
||||
## Integrate a new ISS
|
||||
|
||||
You can add a new entry in [iss.yaml](https://github.com/google/riscv-dv/blob/master/yaml/iss.yaml)
|
||||
|
||||
```yaml
|
||||
- iss: new_iss_name
|
||||
path_var: ISS_PATH
|
||||
cmd: >
|
||||
<path_var>/iss_executable --isa=<variant> -l <elf>
|
||||
```
|
||||
|
||||
Simulate with the new ISS
|
||||
|
||||
```bash
|
||||
run --test riscv_arithmetic_basic_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/blob/master/doc/verification.rst). You can use
|
||||
it as a reference to setup end-to-end co-simulation flow.
|
||||
This repo is still under active development, this is the recommended approach to
|
||||
customize the instruction generator while keeping the effort of merging
|
||||
upstream changes to a minimum.
|
||||
- Do not modify the upstream classes directly. When possible, extend from
|
||||
the upstream classses and implement your own functionalities.
|
||||
- Add your extensions under user_extension directory, and add the files to
|
||||
user_extension/user_extension.svh. If you prefer to put your extensions in a
|
||||
different directory, you can use "-ext <user_extension_path>" to override the
|
||||
user extension path.
|
||||
- Create a new target directory and customize the setting and testlist
|
||||
- Run the generator with `--custom_target <target_dir> --isa <isa> --mabi <mabi>`
|
||||
- Use command line type override to use your extended classes.
|
||||
`--sim_opts="+uvm_set_type_override=<upstream_class>,<extended_class>"`
|
||||
- If extending `riscv_asm_program_gen` class is desired, must use this command
|
||||
line override:
|
||||
`--sim_opts="+uvm_set_inst_override=riscv_asm_program_gen,<extended
|
||||
class>,'uvm_test_top.asm_gen'"`
|
||||
|
||||
You can refer to [riscv-dv extension for ibex](https://github.com/lowRISC/ibex/blob/master/dv/uvm/Makefile#L68) for a working example.
|
||||
|
||||
We have plan to open-source the end-to-end environments of other advanced RISC-V
|
||||
processors. Stay tuned!
|
||||
|
||||
## Handshaking Mechanism
|
||||
|
||||
This mechanism allows the generator to generate small, directed sequences of
|
||||
instructions that write critical information to a specified address in memory,
|
||||
that the testbench monitors for write accesses to.
|
||||
This allows for more in-depth verification of scenarios that involve external
|
||||
stimulus to the core, such as interrupts and debug requests.
|
||||
|
||||
For more information, detailed documentation of this mechanism can be found in
|
||||
[HANDSHAKE.md](./HANDSHAKE.md).
|
||||
|
||||
## Functional coverage (work in progress)
|
||||
|
||||
This flow extracts functional coverage information from the
|
||||
instruction trace generated by ISS. It's independent of the instruction generation
|
||||
flow and does not require a tracer implementation in the RTL. You can use this
|
||||
flow as long as your program can be run with an ISS supported in this flow. The
|
||||
flow parses the instruction trace log and converts it to a CSV trace format. After
|
||||
that, a SV test is run to process the CSV trace files and sample functional
|
||||
coverage from there.
|
||||
|
||||
The functional covergroup is defined in [riscv_instr_cover_group.sv](https://github.com/google/riscv-dv/blob/master/src/riscv_instr_cover_group.sv). It includes below major categories:
|
||||
- Cover all operands for each instruction
|
||||
- Hazard conditions
|
||||
- Corner cases like overflow, underflow, divide by zero
|
||||
- Aligned/unaligned load/store
|
||||
- Positive/negative immediate value
|
||||
- Forward/backward branches, branch hit history
|
||||
- Hint instruction
|
||||
- Illegal instruction
|
||||
- All compressed and non-compressed opcode
|
||||
- Access to all implemened privileged CSR
|
||||
- Exception and interrupt
|
||||
|
||||
The functional covergroup is still under active development. Please feel free to
|
||||
add anything you are interested or file a bug for any feature request.
|
||||
|
||||
Before start, please check the you have modified [riscv_core_setting.sv](https://github.com/google/riscv-dv/blob/master/setting/riscv_core_setting.sv) to reflect your processor capabilities. The covergroup is selectively instantiated based on this setting so that you don't need to deal with excluding unrelated coverpoints later. You also need to get the Spike ISS or riscvOVPsim ISS (riscv-ovpsim) setup before running this flow.
|
||||
|
||||
|
||||
```bash
|
||||
# Process spike simulation log and collect functional coverage
|
||||
cov --dir out/spike_sim
|
||||
|
||||
# Get the command reference
|
||||
cov --help
|
||||
|
||||
# Run the coverage flow with predefined targets
|
||||
cov --dir out/spike_sim --target rv32imc
|
||||
```
|
||||
|
||||
The coverage sampling from the CSV could be time consuming if you have a large
|
||||
number of log to process. You can split them to small batches and run with LSF
|
||||
in parallel.
|
||||
|
||||
```
|
||||
# Split the run to process 5 CSV at a time, and run with LSF
|
||||
cov --dir out/spike_sim --lsf_cmd "bsub ....." -bz 5
|
||||
```
|
||||
## Supporting model
|
||||
|
||||
Please file an issue under this repository for any bug report / integration
|
||||
|
|
13
vendor/google_riscv-dv/cov.py
vendored
13
vendor/google_riscv-dv/cov.py
vendored
|
@ -53,7 +53,7 @@ def build_cov(out, cfg, cwd, opts_vec, opts_cov):
|
|||
build_cmd += (" --custom_target %s" % argv.custom_target)
|
||||
if argv.stop_on_first_error:
|
||||
build_cmd += (" --stop_on_first_error")
|
||||
run_cmd(build_cmd)
|
||||
run_cmd(build_cmd, debug_cmd = argv.debug)
|
||||
|
||||
def sim_cov(out, cfg, cwd, opts_vec, opts_cov, csv_list):
|
||||
"""Simulation the coverage collection
|
||||
|
@ -101,7 +101,7 @@ def sim_cov(out, cfg, cwd, opts_vec, opts_cov, csv_list):
|
|||
sim_cmd += (" --log_suffix _%d" % file_idx)
|
||||
if argv.lsf_cmd == "":
|
||||
logging.info("Processing batch %0d/%0d" % (file_idx+1, batch_cnt))
|
||||
run_cmd(sim_cmd)
|
||||
run_cmd(sim_cmd, debug_cmd = argv.debug)
|
||||
else:
|
||||
sim_cmd += (" --lsf_cmd \"%s\"" % argv.lsf_cmd)
|
||||
sim_cmd_list.append(sim_cmd)
|
||||
|
@ -127,8 +127,9 @@ def collect_cov(out, cfg, cwd):
|
|||
sys.exit(RET_FAIL)
|
||||
logging.info("Processing trace log under %s" % argv.dir)
|
||||
if not os.path.isdir(argv.dir) or not os.listdir(argv.dir):
|
||||
logging.error("Cannot find %s directory, or it is empty", argv.dir)
|
||||
sys.exit(RET_FAIL)
|
||||
if not argv.debug:
|
||||
logging.error("Cannot find %s directory, or it is empty", argv.dir)
|
||||
sys.exit(RET_FAIL)
|
||||
if argv.core:
|
||||
"""
|
||||
If functional coverage is being collected from an RTL core implementation,
|
||||
|
@ -239,6 +240,8 @@ def setup_parser():
|
|||
help="Controlling coverage coverpoints")
|
||||
parser.add_argument("--exp", action="store_true", default=False,
|
||||
help="Run generator with experimental features")
|
||||
parser.add_argument("-d", "--debug", type=str, default="",
|
||||
help="Generate debug command log file")
|
||||
return parser
|
||||
|
||||
def load_config(args, cwd):
|
||||
|
@ -250,6 +253,8 @@ def load_config(args, cwd):
|
|||
Returns:
|
||||
Loaded configuration dictionary.
|
||||
"""
|
||||
if args.debug:
|
||||
args.debug = open(args.debug, "w")
|
||||
if args.verbose:
|
||||
args.opts += "-v"
|
||||
|
||||
|
|
1
vendor/google_riscv-dv/docs/make.bat
vendored
1
vendor/google_riscv-dv/docs/make.bat
vendored
|
@ -9,6 +9,7 @@ if "%SPHINXBUILD%" == "" (
|
|||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
set SPHINXOPTS="-html_theme classic"
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
|
|
49
vendor/google_riscv-dv/docs/source/appendix.rst
vendored
Normal file
49
vendor/google_riscv-dv/docs/source/appendix.rst
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
Appendix
|
||||
========
|
||||
|
||||
Trace CSV format
|
||||
----------------
|
||||
|
||||
A standard CSV format is defined for the instruction execution trace. It's used for co-simulation result comparison and functional coverage collection.
|
||||
|
||||
.. image:: trace_csv.png
|
||||
|
||||
**The CSV format includes the following fields:**
|
||||
|
||||
- pc : Program counter (instruction memory address)
|
||||
- instr: Instruction name
|
||||
- gpr: General purpose register updated by the instruction (rd, fd, vd etc.)
|
||||
|
||||
- Format: <GPR name>:<Value>
|
||||
- GPR can be any integer/floating point/vector register
|
||||
- If more than one general purpose registers are updated, separate them with semicolon
|
||||
- csr: Privileged CSR updated by the instruction
|
||||
|
||||
- The same format as the GPR field
|
||||
- binary: Instruction binary
|
||||
- instr_str: Instruction in assmebly format
|
||||
- operand: Instruction operands
|
||||
- pad: Unused
|
||||
|
||||
**Here's a sample of the CSV trace file:**
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
pc,instr,gpr,csr,binary,mode,instr_str,operand,pad
|
||||
ffffffff8000000c,c.addi,ra:daab700e,,000000b9,3,"c.addi ra, 14","ra,14",
|
||||
ffffffff8000000e,lui,sp:ff8e6000,,ff8e6137,3,"lui sp, 0xff8e6","sp,0xff8e6",
|
||||
ffffffff80000012,addi,sp:ff8e6541,,54110113,3,"addi sp, sp, 1345","sp,sp,1345",
|
||||
ffffffff80000016,c.li,gp:00000000,,00004181,3,"c.li gp, 0","gp,0",
|
||||
ffffffff80000018,lui,tp:80000000,,80000237,3,"lui tp, 0x80000","tp,0x80000",
|
||||
ffffffff8000001c,lui,t0:f999d000,,f999d2b7,3,"lui t0, 0xf999d","t0,0xf999d",
|
||||
ffffffff80000020,addi,t0:f999cbf0,,bf028293,3,"addi t0, t0, -1040","t0,t0,-1040",
|
||||
ffffffff80000024,lui,t1:0416b000,,0416b337,3,"lui t1, 0x416b","t1,0x416b",
|
||||
ffffffff80000028,addi,t1:0416b6ee,,6ee30313,3,"addi t1, t1, 1774","t1,t1,1774",
|
||||
ffffffff8000002c,lui,t2:e6420000,,e64203b7,3,"lui t2, 0xe6420","t2,0xe6420",
|
||||
...
|
||||
|
||||
To integrate a new ISS or processor with the co-simualtion or coverage flow, user must implement a
|
||||
python script to convert the custom trace log format to this CSV format. You can find a sample
|
||||
script `here`_.
|
||||
|
||||
.. _here: https://github.com/google/riscv-dv/blob/master/scripts/spike_log_to_trace_csv.py
|
30
vendor/google_riscv-dv/docs/source/conf.py
vendored
30
vendor/google_riscv-dv/docs/source/conf.py
vendored
|
@ -14,6 +14,7 @@
|
|||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
from pallets_sphinx_themes import ProjectLink
|
||||
import sphinx_rtd_theme
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
|
@ -35,6 +36,7 @@ extensions = [
|
|||
"sphinxcontrib.log_cabinet",
|
||||
"sphinx_issues",
|
||||
"rst2pdf.pdfbuilder",
|
||||
'sphinx_rtd_theme',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
|
@ -51,20 +53,20 @@ exclude_patterns = []
|
|||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = "jinja"
|
||||
html_theme_options = {"index_sidebar_logo": False}
|
||||
|
||||
html_context = {
|
||||
"project_links": [
|
||||
ProjectLink("Source Code", "https://github.com/google/riscv-dv.git"),
|
||||
ProjectLink("Issue Tracker", "https://github.com/google/riscv-dv/issues"),
|
||||
]
|
||||
}
|
||||
|
||||
html_sidebars = {
|
||||
"index": ["project.html", "localtoc.html", "searchbox.html"],
|
||||
"**": ["localtoc.html", "relations.html", "searchbox.html"],
|
||||
}
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
#html_theme_options = {"index_sidebar_logo": False}
|
||||
#
|
||||
#html_context = {
|
||||
# "project_links": [
|
||||
# ProjectLink("Source Code", "https://github.com/google/riscv-dv.git"),
|
||||
# ProjectLink("Issue Tracker", "https://github.com/google/riscv-dv/issues"),
|
||||
# ]
|
||||
#}
|
||||
#
|
||||
#html_sidebars = {
|
||||
# "index": ["project.html", "localtoc.html", "searchbox.html"],
|
||||
# "**": ["localtoc.html", "relations.html", "searchbox.html"],
|
||||
#}
|
||||
|
||||
# -- For PDF output ---------------------------------------------------------
|
||||
pdf_documents = [('index', u'riscv-dv', u'RISCV-DV', u'Google, Inc'),]
|
||||
|
|
|
@ -108,7 +108,7 @@ Test list in `YAML format`_
|
|||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_base_test
|
||||
|
||||
.. _YAML format: https://github.com/google/riscv-dv/blob/master/yaml/testlist.yaml
|
||||
.. _YAML format: https://github.com/google/riscv-dv/blob/master/yaml/base_testlist.yaml
|
||||
|
||||
.. 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
|
||||
|
|
|
@ -1,2 +1,29 @@
|
|||
Customize and Extend Generator
|
||||
==============================
|
||||
|
||||
Add custom instructions
|
||||
-----------------------
|
||||
|
||||
1. Add the new instruction enum to `riscv_custom_instr_enum.sv`_
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
CUSTOM_ADD,
|
||||
CUSTOM_SUB,
|
||||
...
|
||||
|
||||
2. Add custom instruction definition to `rv32x_instr.sv`_/`rv64x_instr.sv`_
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
`DEFINE_CUSTOM_INSTR(CUSTOM_ADD, R_FORMAT, ARITHMETIC, RV32X)
|
||||
`DEFINE_CUSTOM_INSTR(CUSTOM_SUB, R_FORMAT, ARITHMETIC, RV32X)
|
||||
...
|
||||
|
||||
3. Extend `riscv_custom_instr.sv`_ and implement key functions like get_instr_name, convert2asm
|
||||
4. Add RV32X/RV64X to supported_isa in riscv_core_setting.sv
|
||||
|
||||
.. _riscv_custom_instr_enum.sv: https://github.com/google/riscv-dv/blob/master/src/isa/custom/riscv_custom_instr_enum.sv
|
||||
.. _riscv_custom_instr.sv: https://github.com/google/riscv-dv/blob/master/src/isa/custom/riscv_custom_instr.sv
|
||||
.. _rv32x_instr.sv: https://github.com/google/riscv-dv/blob/master/src/isa/custom/rv32x_instr.sv
|
||||
.. _rv64x_instr.sv: https://github.com/google/riscv-dv/blob/master/src/isa/custom/rv64x_instr.sv
|
||||
|
|
1
vendor/google_riscv-dv/docs/source/index.rst
vendored
1
vendor/google_riscv-dv/docs/source/index.rst
vendored
|
@ -19,6 +19,7 @@ Welcome to riscv-dv's documentation!
|
|||
customize_extend_generator
|
||||
class_reference
|
||||
cmd_line_reference
|
||||
appendix
|
||||
|
||||
|
||||
|
||||
|
|
BIN
vendor/google_riscv-dv/docs/source/trace_csv.png
vendored
Normal file
BIN
vendor/google_riscv-dv/docs/source/trace_csv.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
1
vendor/google_riscv-dv/requirements.txt
vendored
1
vendor/google_riscv-dv/requirements.txt
vendored
|
@ -4,4 +4,5 @@ Sphinx
|
|||
Pallets-Sphinx-Themes
|
||||
sphinxcontrib-log-cabinet
|
||||
sphinx-issues
|
||||
sphinx_rtd_theme
|
||||
rst2pdf
|
||||
|
|
227
vendor/google_riscv-dv/run.py
vendored
227
vendor/google_riscv-dv/run.py
vendored
|
@ -33,7 +33,7 @@ from types import SimpleNamespace
|
|||
|
||||
LOGGER = logging.getLogger()
|
||||
|
||||
def get_generator_cmd(simulator, simulator_yaml, cov, exp):
|
||||
def get_generator_cmd(simulator, simulator_yaml, cov, exp, debug_cmd):
|
||||
""" Setup the compile and simulation command for the generator
|
||||
|
||||
Args:
|
||||
|
@ -41,6 +41,7 @@ def get_generator_cmd(simulator, simulator_yaml, cov, exp):
|
|||
simulator_yaml : RTL simulator configuration file in YAML format
|
||||
cov : Enable functional coverage
|
||||
exp : Use experimental version
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
|
||||
Returns:
|
||||
compile_cmd : RTL simulator command to compile the instruction generator
|
||||
|
@ -69,14 +70,15 @@ def get_generator_cmd(simulator, simulator_yaml, cov, exp):
|
|||
if 'env_var' in entry:
|
||||
for env_var in entry['env_var'].split(','):
|
||||
for i in range(len(compile_cmd)):
|
||||
compile_cmd[i] = re.sub("<"+env_var+">", get_env_var(env_var), compile_cmd[i])
|
||||
sim_cmd = re.sub("<"+env_var+">", get_env_var(env_var), sim_cmd)
|
||||
compile_cmd[i] = re.sub("<"+env_var+">", get_env_var(env_var, debug_cmd = debug_cmd),
|
||||
compile_cmd[i])
|
||||
sim_cmd = re.sub("<"+env_var+">", get_env_var(env_var, debug_cmd = debug_cmd), sim_cmd)
|
||||
return compile_cmd, sim_cmd
|
||||
logging.error("Cannot find RTL simulator %0s" % simulator)
|
||||
sys.exit(RET_FAIL)
|
||||
|
||||
|
||||
def parse_iss_yaml(iss, iss_yaml, isa, setting_dir):
|
||||
def parse_iss_yaml(iss, iss_yaml, isa, setting_dir, debug_cmd):
|
||||
"""Parse ISS YAML to get the simulation command
|
||||
|
||||
Args:
|
||||
|
@ -84,6 +86,7 @@ def parse_iss_yaml(iss, iss_yaml, isa, setting_dir):
|
|||
iss_yaml : ISS configuration file in YAML format
|
||||
isa : ISA variant passed to the ISS
|
||||
setting_dir : Generator setting directory
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
|
||||
Returns:
|
||||
cmd : ISS run command
|
||||
|
@ -95,7 +98,7 @@ def parse_iss_yaml(iss, iss_yaml, isa, setting_dir):
|
|||
if entry['iss'] == 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)
|
||||
cmd = re.sub("\<path_var\>", get_env_var(entry['path_var'], debug_cmd = debug_cmd), cmd)
|
||||
m = re.search(r"rv(?P<xlen>[0-9]+?)(?P<variant>[a-z]+?)$", isa)
|
||||
if m:
|
||||
cmd = re.sub("\<xlen\>", m.group('xlen'), cmd)
|
||||
|
@ -130,7 +133,8 @@ def get_iss_cmd(base_cmd, elf, log):
|
|||
cmd += (" &> %s" % log)
|
||||
return cmd
|
||||
|
||||
def do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir, cmp_opts, output_dir):
|
||||
def do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir,
|
||||
cmp_opts, output_dir, debug_cmd):
|
||||
"""Compile the instruction generator
|
||||
|
||||
Args:
|
||||
|
@ -141,6 +145,7 @@ def do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir, cmp_opts,
|
|||
ext_dir : User extension directory
|
||||
cmd_opts : Compile options for the generator
|
||||
output_dir : Output directory of the ELF files
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
if (not((len(test_list) == 1) and (test_list[0]['test'] == 'riscv_csr_test'))):
|
||||
logging.info("Building RISC-V instruction generator")
|
||||
|
@ -155,10 +160,10 @@ def do_compile(compile_cmd, test_list, core_setting_dir, cwd, ext_dir, cmp_opts,
|
|||
cmd = re.sub("<cmp_opts>", cmp_opts, cmd)
|
||||
|
||||
logging.debug("Compile command: %s" % cmd)
|
||||
run_cmd(cmd)
|
||||
run_cmd(cmd, debug_cmd = debug_cmd)
|
||||
|
||||
def run_csr_test(cmd_list, cwd, csr_file, isa, iterations, lsf_cmd,
|
||||
end_signature_addr, timeout_s, output_dir):
|
||||
end_signature_addr, timeout_s, output_dir, debug_cmd):
|
||||
"""Run CSR test
|
||||
It calls a separate python script to generate directed CSR test code,
|
||||
located at scripts/gen_csr_test.py.
|
||||
|
@ -172,11 +177,11 @@ def run_csr_test(cmd_list, cwd, csr_file, isa, iterations, lsf_cmd,
|
|||
if lsf_cmd:
|
||||
cmd_list.append(cmd)
|
||||
else:
|
||||
run_cmd(cmd, timeout_s)
|
||||
run_cmd(cmd, timeout_s, debug_cmd = debug_cmd)
|
||||
|
||||
def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file,
|
||||
isa, end_signature_addr, lsf_cmd, timeout_s, log_suffix,
|
||||
batch_size, output_dir, verbose, check_return_code):
|
||||
batch_size, output_dir, verbose, check_return_code, debug_cmd):
|
||||
"""Run the instruction generator
|
||||
|
||||
Args:
|
||||
|
@ -195,6 +200,7 @@ def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file,
|
|||
batch_size : Number of tests to generate per run
|
||||
output_dir : Output directory of the ELF files
|
||||
check_return_code : Check return code of the command
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
cmd_list = []
|
||||
sim_cmd = re.sub("<out>", os.path.abspath(output_dir), sim_cmd)
|
||||
|
@ -212,7 +218,7 @@ def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file,
|
|||
# Running a CSR test
|
||||
if test['test'] == 'riscv_csr_test':
|
||||
run_csr_test(cmd_list, cwd, csr_file, isa, iterations, lsf_cmd,
|
||||
end_signature_addr, timeout_s, output_dir)
|
||||
end_signature_addr, timeout_s, output_dir, debug_cmd)
|
||||
else:
|
||||
batch_cnt = 1
|
||||
if batch_size > 0:
|
||||
|
@ -247,12 +253,13 @@ def do_simulate(sim_cmd, test_list, cwd, sim_opts, seed_yaml, seed, csr_file,
|
|||
else:
|
||||
logging.info("Running %s, batch %0d/%0d, test_cnt:%0d" %
|
||||
(test['test'], i+1, batch_cnt, test_cnt))
|
||||
run_cmd(cmd, timeout_s, check_return_code = check_return_code)
|
||||
run_cmd(cmd, timeout_s, check_return_code = check_return_code, debug_cmd = debug_cmd)
|
||||
if sim_seed:
|
||||
with open(('%s/seed.yaml' % os.path.abspath(output_dir)) , 'w') as outfile:
|
||||
yaml.dump(sim_seed, outfile, default_flow_style=False)
|
||||
if lsf_cmd:
|
||||
run_parallel_cmd(cmd_list, timeout_s, check_return_code = check_return_code)
|
||||
run_parallel_cmd(cmd_list, timeout_s, check_return_code = check_return_code,
|
||||
debug_cmd = debug_cmd)
|
||||
|
||||
|
||||
def gen(test_list, cfg, output_dir, cwd):
|
||||
|
@ -281,19 +288,20 @@ def gen(test_list, cfg, output_dir, cwd):
|
|||
# Setup the compile and simulation command for the generator
|
||||
compile_cmd = []
|
||||
sim_cmd = ""
|
||||
compile_cmd, sim_cmd = get_generator_cmd(argv.simulator, argv.simulator_yaml, argv.cov, argv.exp);
|
||||
compile_cmd, sim_cmd = get_generator_cmd(argv.simulator, argv.simulator_yaml, argv.cov,
|
||||
argv.exp, argv.debug);
|
||||
# Compile the instruction generator
|
||||
if not argv.so:
|
||||
do_compile(compile_cmd, test_list, argv.core_setting_dir, cwd, argv.user_extension_dir,
|
||||
argv.cmp_opts, output_dir)
|
||||
argv.cmp_opts, output_dir, argv.debug)
|
||||
# Run the instruction generator
|
||||
if not argv.co:
|
||||
do_simulate(sim_cmd, test_list, cwd, argv.sim_opts, argv.seed_yaml, argv.seed, argv.csr_yaml,
|
||||
argv.isa, argv.end_signature_addr, argv.lsf_cmd, argv.gen_timeout, argv.log_suffix,
|
||||
argv.batch_size, output_dir, argv.verbose, check_return_code)
|
||||
argv.batch_size, output_dir, argv.verbose, check_return_code, argv.debug)
|
||||
|
||||
|
||||
def gcc_compile(test_list, output_dir, isa, mabi, opts):
|
||||
def gcc_compile(test_list, output_dir, isa, mabi, opts, debug_cmd):
|
||||
"""Use riscv gcc toolchain to compile the assembly program
|
||||
|
||||
Args:
|
||||
|
@ -301,6 +309,7 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts):
|
|||
output_dir : Output directory of the ELF files
|
||||
isa : ISA variant passed to GCC
|
||||
mabi : MABI variant passed to GCC
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
for test in test_list:
|
||||
|
@ -312,7 +321,7 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts):
|
|||
elf = prefix + ".o"
|
||||
binary = prefix + ".bin"
|
||||
test_isa = isa
|
||||
if not os.path.isfile(asm):
|
||||
if not os.path.isfile(asm) and not debug_cmd:
|
||||
logging.error("Cannot find assembly test: %s\n", asm)
|
||||
sys.exit(RET_FAIL)
|
||||
# gcc comilation
|
||||
|
@ -321,7 +330,7 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts):
|
|||
-nostartfiles %s \
|
||||
-I%s/user_extension \
|
||||
-T%s/scripts/link.ld %s -o %s " % \
|
||||
(get_env_var("RISCV_GCC"), asm, cwd, cwd, opts, elf))
|
||||
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), asm, cwd, cwd, opts, elf))
|
||||
if 'gcc_opts' in test:
|
||||
cmd += test['gcc_opts']
|
||||
if 'gen_opts' in test:
|
||||
|
@ -335,15 +344,16 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts):
|
|||
if not re.search('mabi', cmd):
|
||||
cmd += (" -mabi=%s" % mabi)
|
||||
logging.info("Compiling %s" % asm)
|
||||
run_cmd_output(cmd.split())
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
# Convert the ELF to plain binary, used in RTL sim
|
||||
logging.info("Converting to %s" % binary)
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY"), elf, binary))
|
||||
run_cmd_output(cmd.split())
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY", debug_cmd = debug_cmd),
|
||||
elf, binary))
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
|
||||
|
||||
def run_assembly(asm_test, iss_yaml, isa, mabi, gcc_opts, iss_opts, output_dir,
|
||||
setting_dir):
|
||||
setting_dir, debug_cmd):
|
||||
"""Run a directed assembly test with ISS
|
||||
|
||||
Args:
|
||||
|
@ -355,6 +365,7 @@ def run_assembly(asm_test, iss_yaml, isa, mabi, gcc_opts, iss_opts, output_dir,
|
|||
iss_opts : Instruction set simulators
|
||||
output_dir : Output directory of compiled test files
|
||||
setting_dir : Generator setting directory
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
if not asm_test.endswith(".S"):
|
||||
logging.error("%s is not an assembly .S file" % asm_test)
|
||||
|
@ -377,30 +388,31 @@ def run_assembly(asm_test, iss_yaml, isa, mabi, gcc_opts, iss_opts, output_dir,
|
|||
-nostartfiles %s \
|
||||
-I%s/user_extension \
|
||||
-T%s/scripts/link.ld %s -o %s " % \
|
||||
(get_env_var("RISCV_GCC"), asm_test, cwd, cwd, gcc_opts, elf))
|
||||
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), asm_test, cwd,
|
||||
cwd, gcc_opts, elf))
|
||||
cmd += (" -march=%s" % isa)
|
||||
cmd += (" -mabi=%s" % mabi)
|
||||
run_cmd_output(cmd.split())
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
# Convert the ELF to plain binary, used in RTL sim
|
||||
logging.info("Converting to %s" % binary)
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY"), elf, binary))
|
||||
run_cmd_output(cmd.split())
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY", debug_cmd = debug_cmd), elf, binary))
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
log_list = []
|
||||
# ISS simulation
|
||||
for iss in iss_list:
|
||||
run_cmd("mkdir -p %s/%s_sim" % (output_dir, iss))
|
||||
log = ("%s/%s_sim/%s.log" % (output_dir, iss, asm))
|
||||
log_list.append(log)
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, setting_dir)
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, setting_dir, debug_cmd)
|
||||
logging.info("[%0s] Running ISS simulation: %s" % (iss, elf))
|
||||
cmd = get_iss_cmd(base_cmd, elf, log)
|
||||
run_cmd(cmd, 10)
|
||||
run_cmd(cmd, 10, debug_cmd = debug_cmd)
|
||||
logging.info("[%0s] Running ISS simulation: %s ...done" % (iss, elf))
|
||||
if len(iss_list) == 2:
|
||||
compare_iss_log(iss_list, log_list, report)
|
||||
|
||||
def run_assembly_from_dir(asm_test_dir, iss_yaml, isa, mabi, gcc_opts, iss,
|
||||
output_dir, setting_dir):
|
||||
output_dir, setting_dir, debug_cmd):
|
||||
"""Run a directed assembly test from a directory with spike
|
||||
|
||||
Args:
|
||||
|
@ -412,6 +424,7 @@ def run_assembly_from_dir(asm_test_dir, iss_yaml, isa, mabi, gcc_opts, iss,
|
|||
iss : Instruction set simulators
|
||||
output_dir : Output directory of compiled test files
|
||||
setting_dir : Generator setting directory
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
result = run_cmd("find %s -name \"*.S\"" % asm_test_dir)
|
||||
if result:
|
||||
|
@ -420,14 +433,102 @@ def run_assembly_from_dir(asm_test_dir, iss_yaml, isa, mabi, gcc_opts, iss,
|
|||
(len(asm_list), asm_test_dir))
|
||||
for asm_file in asm_list:
|
||||
run_assembly(asm_file, iss_yaml, isa, mabi, gcc_opts, iss, output_dir,
|
||||
setting_dir)
|
||||
setting_dir, debug_cmd)
|
||||
if "," in iss:
|
||||
report = ("%s/iss_regr.log" % output_dir).rstrip()
|
||||
save_regr_report(report)
|
||||
else:
|
||||
logging.error("No assembly test(*.S) found under %s" % asm_test_dir)
|
||||
|
||||
def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, setting_dir, timeout_s):
|
||||
def run_c(c_test, iss_yaml, isa, mabi, gcc_opts, iss_opts, output_dir,
|
||||
setting_dir, debug_cmd):
|
||||
"""Run a directed c test with ISS
|
||||
|
||||
Args:
|
||||
c_test : C test file
|
||||
iss_yaml : ISS configuration file in YAML format
|
||||
isa : ISA variant passed to the ISS
|
||||
mabi : MABI variant passed to GCC
|
||||
gcc_opts : User-defined options for GCC compilation
|
||||
iss_opts : Instruction set simulators
|
||||
output_dir : Output directory of compiled test files
|
||||
setting_dir : Generator setting directory
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
if not c_test.endswith(".c"):
|
||||
logging.error("%s is not a .c file" % c_test)
|
||||
return
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
c_test = os.path.expanduser(c_test)
|
||||
report = ("%s/iss_regr.log" % output_dir).rstrip()
|
||||
c = re.sub(r"^.*\/", "", c_test)
|
||||
c = re.sub(r"\.c$", "", c)
|
||||
prefix = ("%s/directed_c_tests/%s" % (output_dir, c))
|
||||
elf = prefix + ".o"
|
||||
binary = prefix + ".bin"
|
||||
iss_list = iss_opts.split(",")
|
||||
run_cmd("mkdir -p %s/directed_c_tests" % output_dir)
|
||||
logging.info("Compiling c test : %s" % c_test)
|
||||
|
||||
# gcc compilation
|
||||
cmd = ("%s -mcmodel=medany -nostdlib \
|
||||
-nostartfiles %s \
|
||||
-I%s/user_extension \
|
||||
-T%s/scripts/link.ld %s -o %s " % \
|
||||
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), c_test, cwd,
|
||||
cwd, gcc_opts, elf))
|
||||
cmd += (" -march=%s" % isa)
|
||||
cmd += (" -mabi=%s" % mabi)
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
# Convert the ELF to plain binary, used in RTL sim
|
||||
logging.info("Converting to %s" % binary)
|
||||
cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY", debug_cmd = debug_cmd), elf, binary))
|
||||
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
|
||||
log_list = []
|
||||
# ISS simulation
|
||||
for iss in iss_list:
|
||||
run_cmd("mkdir -p %s/%s_sim" % (output_dir, iss))
|
||||
log = ("%s/%s_sim/%s.log" % (output_dir, iss, c))
|
||||
log_list.append(log)
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, setting_dir, debug_cmd)
|
||||
logging.info("[%0s] Running ISS simulation: %s" % (iss, elf))
|
||||
cmd = get_iss_cmd(base_cmd, elf, log)
|
||||
run_cmd(cmd, 10, debug_cmd = debug_cmd)
|
||||
logging.info("[%0s] Running ISS simulation: %s ...done" % (iss, elf))
|
||||
if len(iss_list) == 2:
|
||||
compare_iss_log(iss_list, log_list, report)
|
||||
|
||||
def run_c_from_dir(c_test_dir, iss_yaml, isa, mabi, gcc_opts, iss,
|
||||
output_dir, setting_dir, debug_cmd):
|
||||
"""Run a directed assembly test from a directory with spike
|
||||
|
||||
Args:
|
||||
c_test_dir : C test file directory
|
||||
iss_yaml : ISS configuration file in YAML format
|
||||
isa : ISA variant passed to the ISS
|
||||
mabi : MABI variant passed to GCC
|
||||
gcc_opts : User-defined options for GCC compilation
|
||||
iss : Instruction set simulators
|
||||
output_dir : Output directory of compiled test files
|
||||
setting_dir : Generator setting directory
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
result = run_cmd("find %s -name \"*.c\"" % c_test_dir)
|
||||
if result:
|
||||
c_list = result.splitlines()
|
||||
logging.info("Found %0d c tests under %s" %
|
||||
(len(c_list), c_test_dir))
|
||||
for c_file in c_list:
|
||||
run_c(c_file, iss_yaml, isa, mabi, gcc_opts, iss, output_dir,
|
||||
setting_dir, debug_cmd)
|
||||
if "," in iss:
|
||||
report = ("%s/iss_regr.log" % output_dir).rstrip()
|
||||
save_regr_report(report)
|
||||
else:
|
||||
logging.error("No c test(*.c) found under %s" % c_test_dir)
|
||||
|
||||
def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa,
|
||||
setting_dir, timeout_s, debug_cmd):
|
||||
"""Run ISS simulation with the generated test program
|
||||
|
||||
Args:
|
||||
|
@ -438,10 +539,11 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, setting_dir, timeout
|
|||
isa : ISA variant passed to the ISS
|
||||
setting_dir : Generator setting directory
|
||||
timeout_s : Timeout limit in seconds
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
for iss in iss_list.split(","):
|
||||
log_dir = ("%s/%s_sim" % (output_dir, iss))
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, setting_dir)
|
||||
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, setting_dir, debug_cmd)
|
||||
logging.info("%s sim log dir: %s" % (iss, log_dir))
|
||||
run_cmd_output(["mkdir", "-p", log_dir])
|
||||
for test in test_list:
|
||||
|
@ -455,13 +557,13 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, setting_dir, timeout
|
|||
cmd = get_iss_cmd(base_cmd, elf, log)
|
||||
logging.info("Running %s sim: %s" % (iss, elf))
|
||||
if iss == "ovpsim":
|
||||
run_cmd(cmd, timeout_s, check_return_code=False)
|
||||
run_cmd(cmd, timeout_s, check_return_code=False, debug_cmd = debug_cmd)
|
||||
else:
|
||||
run_cmd(cmd, timeout_s)
|
||||
run_cmd(cmd, timeout_s, debug_cmd = debug_cmd)
|
||||
logging.debug(cmd)
|
||||
|
||||
|
||||
def iss_cmp(test_list, iss, output_dir, stop_on_first_error, exp):
|
||||
def iss_cmp(test_list, iss, output_dir, stop_on_first_error, exp, debug_cmd):
|
||||
"""Compare ISS simulation reult
|
||||
|
||||
Args:
|
||||
|
@ -470,7 +572,10 @@ def iss_cmp(test_list, iss, output_dir, stop_on_first_error, exp):
|
|||
output_dir : Output directory of the ELF files
|
||||
stop_on_first_error : will end run on first error detected
|
||||
exp : Use experimental version
|
||||
debug_cmd : Produce the debug cmd log without running
|
||||
"""
|
||||
if debug_cmd:
|
||||
return
|
||||
iss_list = iss.split(",")
|
||||
if len(iss_list) != 2:
|
||||
return
|
||||
|
@ -593,6 +698,8 @@ def setup_parser():
|
|||
help="Path for the user extension directory")
|
||||
parser.add_argument("--asm_tests", type=str, default="",
|
||||
help="Directed assembly tests")
|
||||
parser.add_argument("--c_tests", type=str, default="",
|
||||
help="Directed c tests")
|
||||
parser.add_argument("--log_suffix", type=str, default="",
|
||||
help="Simulation log name suffix")
|
||||
parser.add_argument("--exp", action="store_true", default=False,
|
||||
|
@ -605,6 +712,8 @@ def setup_parser():
|
|||
help="Stop on detecting first error")
|
||||
parser.add_argument("--noclean", action="store_true", default=True,
|
||||
help="Do not clean the output of the previous runs")
|
||||
parser.add_argument("-d", "--debug", type=str, default="",
|
||||
help="Generate debug command log file")
|
||||
return parser
|
||||
|
||||
def load_config(args, cwd):
|
||||
|
@ -615,6 +724,8 @@ def load_config(args, cwd):
|
|||
Returns:
|
||||
Loaded configuration dictionary.
|
||||
"""
|
||||
if args.debug:
|
||||
args.debug = open(args.debug, "w")
|
||||
if not args.csr_yaml:
|
||||
args.csr_yaml = cwd + "/yaml/csr_template.yaml"
|
||||
|
||||
|
@ -687,11 +798,31 @@ def main():
|
|||
# path_asm_test is a directory
|
||||
if os.path.isdir(full_path):
|
||||
run_assembly_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
|
||||
args.gcc_opts, args.iss, output_dir, args.core_setting_dir)
|
||||
args.gcc_opts, args.iss, output_dir,
|
||||
args.core_setting_dir, args.debug)
|
||||
# path_asm_test is an assembly file
|
||||
elif os.path.isfile(full_path):
|
||||
elif os.path.isfile(full_path) or args.debug:
|
||||
run_assembly(full_path, args.iss_yaml, args.isa, args.mabi, args.gcc_opts,
|
||||
args.iss, output_dir, args.core_setting_dir)
|
||||
args.iss, output_dir, args.core_setting_dir, args.debug)
|
||||
else:
|
||||
logging.error('%s does not exist' % full_path)
|
||||
sys.exit(RET_FAIL)
|
||||
return
|
||||
|
||||
# Run any handcoded/directed c tests specified by args.c_tests
|
||||
if args.c_tests != "":
|
||||
c_test = args.c_tests.split(',')
|
||||
for path_c_test in c_test:
|
||||
full_path = os.path.expanduser(path_c_test)
|
||||
# path_c_test is a directory
|
||||
if os.path.isdir(full_path):
|
||||
run_c_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
|
||||
args.gcc_opts, args.iss, output_dir,
|
||||
args.core_setting_dir, args.debug)
|
||||
# path_c_test is a c file
|
||||
elif os.path.isfile(full_path) or args.debug:
|
||||
run_c(full_path, args.iss_yaml, args.isa, args.mabi, args.gcc_opts,
|
||||
args.iss, output_dir, args.core_setting_dir, args.debug)
|
||||
else:
|
||||
logging.error('%s does not exist' % full_path)
|
||||
sys.exit(RET_FAIL)
|
||||
|
@ -729,30 +860,34 @@ def main():
|
|||
# path_asm_test is a directory
|
||||
if os.path.isdir(path_asm_test):
|
||||
run_assembly_from_dir(path_asm_test, args.iss_yaml, args.isa, args.mabi,
|
||||
gcc_opts, args.iss, output_dir, args.core_setting_dir)
|
||||
gcc_opts, args.iss, output_dir,
|
||||
args.core_setting_dir, args.debug)
|
||||
# path_asm_test is an assembly file
|
||||
elif os.path.isfile(path_asm_test):
|
||||
run_assembly(path_asm_test, args.iss_yaml, args.isa, args.mabi, gcc_opts,
|
||||
args.iss, output_dir, args.core_setting_dir)
|
||||
args.iss, output_dir, args.core_setting_dir, args.debug)
|
||||
else:
|
||||
logging.error('%s does not exist' % path_asm_test)
|
||||
sys.exit(RET_FAIL)
|
||||
if not args.debug:
|
||||
logging.error('%s does not exist' % path_asm_test)
|
||||
sys.exit(RET_FAIL)
|
||||
# Run remaining tests using the instruction generator
|
||||
gen(matched_list, cfg, output_dir, cwd)
|
||||
|
||||
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, args.gcc_opts)
|
||||
gcc_compile(matched_list, output_dir, args.isa, args.mabi,
|
||||
args.gcc_opts, args.debug)
|
||||
|
||||
# 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.core_setting_dir, args.iss_timeout)
|
||||
args.isa, args.core_setting_dir, args.iss_timeout, args.debug)
|
||||
|
||||
# Compare ISS simulation result
|
||||
if args.steps == "all" or re.match(".*iss_cmp.*", args.steps):
|
||||
iss_cmp(matched_list, args.iss, output_dir, args.stop_on_first_error, args.exp)
|
||||
iss_cmp(matched_list, args.iss, output_dir, args.stop_on_first_error,
|
||||
args.exp, args.debug)
|
||||
|
||||
sys.exit(RET_SUCCESS)
|
||||
except KeyboardInterrupt:
|
||||
|
|
29
vendor/google_riscv-dv/scripts/lib.py
vendored
29
vendor/google_riscv-dv/scripts/lib.py
vendored
|
@ -65,7 +65,7 @@ def read_yaml(yaml_file):
|
|||
return yaml_data
|
||||
|
||||
|
||||
def get_env_var(var):
|
||||
def get_env_var(var, debug_cmd = None):
|
||||
"""Get the value of environment variable
|
||||
|
||||
Args:
|
||||
|
@ -77,8 +77,11 @@ def get_env_var(var):
|
|||
try:
|
||||
val = os.environ[var]
|
||||
except KeyError:
|
||||
logging.warning("Please set the environment variable %0s" % var)
|
||||
sys.exit(RET_FAIL)
|
||||
if debug_cmd:
|
||||
return var
|
||||
else:
|
||||
logging.warning("Please set the environment variable %0s" % var)
|
||||
sys.exit(RET_FAIL)
|
||||
return val
|
||||
|
||||
|
||||
|
@ -96,7 +99,7 @@ def get_seed(seed):
|
|||
return random.getrandbits(32)
|
||||
|
||||
|
||||
def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True):
|
||||
def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True, debug_cmd = None):
|
||||
"""Run a command and return output
|
||||
|
||||
Args:
|
||||
|
@ -106,6 +109,10 @@ def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True):
|
|||
command output
|
||||
"""
|
||||
logging.debug(cmd)
|
||||
if debug_cmd:
|
||||
debug_cmd.write(cmd)
|
||||
debug_cmd.write("\n\n")
|
||||
return
|
||||
try:
|
||||
ps = subprocess.Popen("exec " + cmd,
|
||||
shell=True,
|
||||
|
@ -135,7 +142,8 @@ def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True):
|
|||
return output
|
||||
|
||||
|
||||
def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0, check_return_code = True):
|
||||
def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0,
|
||||
check_return_code = True, debug_cmd = None):
|
||||
"""Run a list of commands in parallel
|
||||
|
||||
Args:
|
||||
|
@ -144,6 +152,11 @@ def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0, check_return_
|
|||
Returns:
|
||||
command output
|
||||
"""
|
||||
if debug_cmd:
|
||||
for cmd in cmd_list:
|
||||
debug_cmd.write(cmd)
|
||||
debug_cmd.write("\n\n")
|
||||
return
|
||||
children = []
|
||||
for cmd in cmd_list:
|
||||
ps = subprocess.Popen("exec " + cmd,
|
||||
|
@ -174,12 +187,16 @@ def run_parallel_cmd(cmd_list, timeout_s = 999, exit_on_error = 0, check_return_
|
|||
os.system("stty sane")
|
||||
logging.debug(output)
|
||||
|
||||
def run_cmd_output(cmd):
|
||||
def run_cmd_output(cmd, debug_cmd = None):
|
||||
"""Run a command and return output
|
||||
Args:
|
||||
cmd : Command line to execute
|
||||
"""
|
||||
logging.debug(" ".join(cmd))
|
||||
if debug_cmd:
|
||||
debug_cmd.write(" ".join(cmd))
|
||||
debug_cmd.write("\n\n")
|
||||
return
|
||||
try:
|
||||
output = subprocess.check_output(cmd)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
|
|
51
vendor/google_riscv-dv/src/isa/custom/riscv_custom_instr.sv
vendored
Normal file
51
vendor/google_riscv-dv/src/isa/custom/riscv_custom_instr.sv
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// Custom instruction class
|
||||
|
||||
class riscv_custom_instr extends riscv_instr;
|
||||
|
||||
// TODO: Add custom operands here, example:
|
||||
// rand riscv_reg_t rs3;
|
||||
|
||||
`uvm_object_utils(riscv_custom_instr)
|
||||
`uvm_object_new
|
||||
|
||||
virtual function string get_instr_name();
|
||||
get_instr_name = instr_name.name();
|
||||
// TODO: Add custom instruction name encoding here
|
||||
return get_instr_name;
|
||||
endfunction : get_instr_name
|
||||
|
||||
// Convert the instruction to assembly code
|
||||
virtual function string convert2asm(string prefix = "");
|
||||
string asm_str;
|
||||
asm_str = format_string("nop", MAX_INSTR_STR_LEN);
|
||||
/* TODO: Convert custom instruction to assembly format. Example:
|
||||
asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN);
|
||||
case (instr_name)
|
||||
CUSTOM_1: asm_str = $sformatf("%0s %0s, (%0s)", asm_str, rd.name(), rs1.name());
|
||||
CUSTOM_2: asm_str = $sformatf("%0s %0s", asm_str, r3.name());
|
||||
endcase
|
||||
*/
|
||||
comment = {get_instr_name(), " ", comment};
|
||||
if (comment != "") begin
|
||||
asm_str = {asm_str, " #",comment};
|
||||
end
|
||||
return asm_str.tolower();
|
||||
endfunction : convert2asm
|
||||
|
||||
endclass : riscv_custom_instr
|
2
vendor/google_riscv-dv/src/isa/custom/riscv_custom_instr_enum.sv
vendored
Normal file
2
vendor/google_riscv-dv/src/isa/custom/riscv_custom_instr_enum.sv
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
// TODO: Add custom instruction name enum
|
||||
CUSTOM_1,
|
18
vendor/google_riscv-dv/src/isa/custom/rv32x_instr.sv
vendored
Normal file
18
vendor/google_riscv-dv/src/isa/custom/rv32x_instr.sv
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// TODO: Add custom RV32X instruction. Example:
|
||||
`DEFINE_CUSTOM_INSTR(CUSTOM_1, R_FORMAT, ARITHMETIC, RV32X)
|
18
vendor/google_riscv-dv/src/isa/custom/rv64x_instr.sv
vendored
Normal file
18
vendor/google_riscv-dv/src/isa/custom/rv64x_instr.sv
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// TODO: Add custom RV32X instruction. Example:
|
||||
// `DEFINE_CUSTOM_INSTR(CUSTOM1, R_FORMAT, LOAD, RV64X)
|
|
@ -362,6 +362,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
RV32F, RV64F, RV32FC : misa[MISA_EXT_F] = 1'b1;
|
||||
RV32D, RV64D, RV32DC : misa[MISA_EXT_D] = 1'b1;
|
||||
RV32V, RV64V : misa[MISA_EXT_V] = 1'b1;
|
||||
RV32X, RV64X : misa[MISA_EXT_X] = 1'b1;
|
||||
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported",
|
||||
supported_isa[i].name()))
|
||||
endcase
|
||||
|
@ -820,21 +821,6 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
for (int i = 1; i < max_interrupt_vector_num; i++) begin
|
||||
string intr_handler[$];
|
||||
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, intr_handler);
|
||||
// If nested interrupts are enabled, set xSTATUS.xIE in the interrupt handler
|
||||
// to re-enable interrupt handling capabilities
|
||||
if (cfg.enable_nested_interrupt) begin
|
||||
case (status)
|
||||
MSTATUS: begin
|
||||
intr_handler.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 8));
|
||||
end
|
||||
SSTATUS: begin
|
||||
intr_handler.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 2));
|
||||
end
|
||||
USTATUS: begin
|
||||
intr_handler.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 1));
|
||||
end
|
||||
endcase
|
||||
end
|
||||
gen_signature_handshake(.instr(intr_handler), .signature_type(CORE_STATUS), .core_status(HANDLING_IRQ));
|
||||
intr_handler = {intr_handler,
|
||||
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()),
|
||||
|
@ -845,7 +831,7 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
gen_signature_handshake(.instr(intr_handler), .signature_type(WRITE_CSR), .csr(cause));
|
||||
gen_signature_handshake(.instr(intr_handler), .signature_type(WRITE_CSR), .csr(ie));
|
||||
gen_signature_handshake(.instr(intr_handler), .signature_type(WRITE_CSR), .csr(ip));
|
||||
// Jump to commmon interrupt handling routine
|
||||
// Jump to commmon interrupt handling routine
|
||||
intr_handler = {intr_handler,
|
||||
$sformatf("j %0smode_intr_handler", mode),
|
||||
"1: j test_done"};
|
||||
|
@ -1022,6 +1008,25 @@ class riscv_asm_program_gen extends uvm_object;
|
|||
end
|
||||
default: `uvm_fatal(get_full_name(), $sformatf("Unsupported mode: %0s", mode.name()))
|
||||
endcase
|
||||
// If nested interrupts are enabled, set xSTATUS.xIE in the interrupt handler
|
||||
// to re-enable interrupt handling capabilities
|
||||
if (cfg.enable_nested_interrupt) begin
|
||||
interrupt_handler_instr.push_back($sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], scratch));
|
||||
interrupt_handler_instr.push_back($sformatf("bgtz x%0d, 1f", cfg.gpr[0]));
|
||||
interrupt_handler_instr.push_back($sformatf("csrwi 0x%0x, 0x1", scratch));
|
||||
case (status)
|
||||
MSTATUS: begin
|
||||
interrupt_handler_instr.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 8));
|
||||
end
|
||||
SSTATUS: begin
|
||||
interrupt_handler_instr.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 2));
|
||||
end
|
||||
USTATUS: begin
|
||||
interrupt_handler_instr.push_back($sformatf("csrsi 0x%0x, 0x%0x", status, 1));
|
||||
end
|
||||
endcase
|
||||
interrupt_handler_instr.push_back($sformatf("1: csrwi 0x%0x,0", scratch));
|
||||
end
|
||||
// Read back interrupt related privileged CSR
|
||||
// The value of these CSR are checked by comparing with spike simulation result.
|
||||
interrupt_handler_instr = {
|
||||
|
|
5
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
5
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
|
@ -93,3 +93,8 @@
|
|||
`define DEFINE_VA_INSTR(instr_n, instr_format, instr_category, instr_group, vav = {}, imm_tp = IMM) \
|
||||
class riscv_``instr_n``_instr extends riscv_vector_instr; \
|
||||
`VA_INSTR_BODY(instr_n, instr_format, instr_category, instr_group, vav, imm_tp)
|
||||
|
||||
// Custom extension instruction
|
||||
`define DEFINE_CUSTOM_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM) \
|
||||
class riscv_``instr_n``_instr extends riscv_custom_instr; \
|
||||
`INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp)
|
||||
|
|
|
@ -90,7 +90,9 @@ package riscv_instr_pkg;
|
|||
RV32V,
|
||||
RV32B,
|
||||
RV64V,
|
||||
RV64B
|
||||
RV64B,
|
||||
RV32X,
|
||||
RV64X
|
||||
} riscv_instr_group_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -491,6 +493,8 @@ package riscv_instr_pkg;
|
|||
SRET,
|
||||
WFI,
|
||||
SFENCE_VMA,
|
||||
// Custom instructions
|
||||
`include "isa/custom/riscv_custom_instr_enum.sv"
|
||||
// You can add other instructions here
|
||||
INVALID_INSTR
|
||||
} riscv_instr_name_t;
|
||||
|
@ -1106,6 +1110,9 @@ package riscv_instr_pkg;
|
|||
`include "isa/rv64m_instr.sv"
|
||||
`include "isa/rv128c_instr.sv"
|
||||
`include "isa/rv32v_instr.sv"
|
||||
`include "isa/custom/riscv_custom_instr.sv"
|
||||
`include "isa/custom/rv32x_instr.sv"
|
||||
`include "isa/custom/rv64x_instr.sv"
|
||||
`endif
|
||||
|
||||
`include "riscv_pseudo_instr.sv"
|
||||
|
|
|
@ -31,7 +31,7 @@ riscv_instr_name_t unsupported_instr[];
|
|||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A,
|
||||
RV32F, RV64F, RV32D, RV64D};
|
||||
RV32F, RV64F, RV32D, RV64D, RV32X};
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue