Overview
core-v-verif is a functional verification project developed by the OpenHW Group to verify RISC-V cores in the CORE-V family. The public GitHub repository describes it as a "functional verification project for the CORE-V family of RISC-V cores."
The project's verification environment was initially focused on CV32E40P, a power-efficient 32-bit RISC-V core with in-order execution and a 4-stage pipeline, implementing the RV32IMCZifencei ISA extensions. The evidence describes core-v-verif as providing a simulation environment for the CV32E40P RTL core, and notes that the environment was intended to be adapted for additional CORE-V cores such as CV32E40X, CV32E40S, CVA6, and future OpenHW roadmap cores.
The OpenHW Group established a Verification task group that set up a verification strategy plan, and supporting documentation is hosted in the CORE-V-DOCS repository.
Verification approach
core-v-verif uses UVM to make its verification environment transferable and easier for the wider SoC community to adopt. The environment is described as not being specific to a single EDA vendor because it uses class libraries based on SystemVerilog.
The CORE-V UVM environment centers on test programs executed by the core. These programs run in a simple execution environment defined by the ISA, the memory map supported by the testbench memory model, and memory-mapped virtual peripherals. The UVM environment is therefore aware of the test program and responds as part of the run flow.
The testbench overview also references a functional coverage model built from the specification, an Imperas reference model providing the functional reference, and a scoreboard that compares results. Co-simulation is supported using Spike (with a particular version required to run), and the RISC-V Formal Interface (RVFI) is used to provide information about retired instructions and instructions that produce synchronous traps for checking.
Test programs
The core-v-verif UVM environment can support test programs regardless of how they are created, provided they are compatible with the relevant Board Support Package (BSP). The environment distinguishes whether a program is pre-existing or generated at run time, and whether it is self-checking.
Supported modes described in the evidence include:
- Pre-existing, self-checking: a memory image exists in the expected location, and the environment checks the status-flags virtual peripheral for pass/fail information.
- Pre-existing, not self-checking: a memory image exists in the expected location, but the environment does not check the status-flags virtual peripheral for pass/fail information.
- Generated, self-checking: the environment uses its random instruction generator to create a test program and checks the status-flags virtual peripheral.
- Generated, not self-checking: the environment uses its random instruction generator to create a test program and does not check the status-flags virtual peripheral.
- None: a UVM test can run without a test program, for example to access CSRs via the debug module interface in debug mode.
The evidence notes that pre-existing self-checking programs and generated non-self-checking programs are expected to predominate. Many of the pre-existing self-checking test programs were inherited from the RI5CY project. It also states that checker-monitors can independently fail a simulation by signaling uvm_error, regardless of what a test program writes to the status-flags virtual peripheral. Generated test programs can also be written out and run as if they were pre-existing test programs, which from the environment's perspective is indistinguishable from a pre-existing test.
COREV-DV
COREV-DV is the name given to a library of extensions to the Google riscv-dv instruction stream generator. core-v-verif uses riscv-dv "as is" and extends it with corev-dv classes, so that core-v-verif can take advantage of updates to the Google project without modifying riscv-dv itself. riscv-dv is implemented as a collection of SystemVerilog classes extending from uvm_object, so extending riscv-dv classes to modify its behavior is straightforward. When a specific instruction stream is required, it is implemented as an extension of an existing riscv-dv class.
Each core verified in core-v-verif is free to use whatever version of riscv-dv suits that core's needs:
- A non-core-specific version of corev-dv resides at
$CORE_V_VERIF/lib/corev-dv, providing extensions intended to be common across all (or at least most) CORE-V cores. - When a Make target requires it, a specific hash of riscv-dv is cloned to
$CORE_V_VERIF/$COREV_CORE/vendor_lib/riscv-dv. - The compile Makefiles compile in the required extensions to generate the core-specific version of corev-dv needed for a test.
- The README at
$CORE_V_VERIF/mk/uvmtprovides instructions for building and running a corev-dv-generated test program.
Extending COREV-DV
It is expected that each unique core will require multiple extensions to riscv-dv. These should be placed in $CORE_V_VERIF/$COREV_CORE/env/corev-dv. For example, $CORE_V_VERIF/lib/corev-dv/corev_asm_program_gen.sv implements an override of riscv_gen_program_header::gen_program_header() to enforce the use of common symbols required by the board support package. Because each core's verification environment is likely to use a core-specific BSP, each core is expected to need core-specific extensions to corev_asm_program_gen.sv.
Board Support Package and virtual peripherals
The core testbench memory module implements virtual peripherals by responding to read or write cycles at specific data-bus addresses. To keep software tests aligned with resources supported by the device under test and testbench, core-v-verif uses Board Support Package files. These can include:
- Linker scripts defining program sections and memory regions.
- Control/status-register configuration files.
- Assembly files that provide the minimum startup support required to run a C program.
The cited evidence explicitly states that test-program environment files must match the testbench resources.
UVM test structure
In the CV32E environment described by the evidence, all UVM tests should extend the base test class uvmt_cv32_base_test_c, which directly extends uvm_test. The base test preserves the intended test flow and reduces duplicated boilerplate for test writers.
A typical CORE-V UVM test extends work in three phases:
- Reset phase: often calls
super.reset_phase()to invoke the default reset sequence (which is a random sequence), though a test-specific reset virtual sequence may also be used. - Configure phase: can load pre-compiled programs into instruction memory when required.
- Run phase: usually contains the procedural code for the test.
The cited run-flow example raises an objection, asserts the core fetch_en input, waits for the core and/or environments to signal completion, and then drops the objection.
Repository
The public GitHub repository is openhwgroup/core-v-verif. Public repository metadata identifies the project language as Assembly and describes the repository as the functional verification project for the CORE-V family of RISC-V cores.