The RISC-V Architectural Certification Tests (ACTs) are a set of assembly language tests designed to certify that a design faithfully implements the RISC-V specification.
See the codeThe RISC-V Architectural Certification Tests (ACTs) are a set of assembly language tests intended to help test that a design faithfully implements the RISC-V specification. These are not verification tests and additional verification should be run on all processors.
The Architectural Certification Tests are used with the ACT4 Framework, a Makefile and Python based tool that replaces the deprecated riscof tool. The ACT4 Framework generates and compiles self-checking tests in Executable Linkable Format (ELF) for a device under test (DUT) and optionally collects coverage showing that the tests hit the coverpoints that check the normative rules. The user is then responsible for running all of the ELF files on the DUT with the user's own testbench. Each test reports success or failure, and if possible prints error messages to a console.
The ACT4 Framework requires a UDB configuration file specifying the extensions and parameters supported by the DUT; an rvmodel_macros.h file defining DUT-specific operations such as printing to a console, terminating a test with a success/failure code, and generating interrupts; and a linker script describing the DUT memory map.
RISC-V is highly configurable, such as whether misaligned accesses are allowed or how many PMP registers are implemented. Therefore, the expected results of the tests differ based on the configuration of the DUT. The ACT4 Framework selects the appropriate tests to compile based on the capabilities of the DUT. It then uses the RISC-V Sail reference model, configured to match the DUT, to compute the expected results of each test. These results are then compiled into the final self-checking ELFs.
The Architectural Certification Tests are described in full detail in the Certification Test Plan (CTP). The ACT4 Framework principles of operation are detailed in [LINK COMING SOON]. For details on adding more tests and coverpoints, see the ACT Developer's Guide. Learn more about RVA23 Certification Testing.
This section provides detailed step-by-step instructions to set up the ACT environment and generate ELFs for a Device Under Test (DUT).
The ACTs require several tools to generate and run correctly. Ensure all of the following tools are installed before proceeding.
The ACT4 framework uses make to run top-level commands. git is needed to clone the riscv-arch-test repository. Both of these packages are available in your system package manager.
To install system dependencies:
# On Ubuntu/Debian
sudo apt-get install make git
# On Fedora/CentOS/RHEL
sudo dnf install make git
mise (Tool Manager)The test generator and framework are written in Python. The recommended way of installing and running Python is using the uv project manager, which will handle Python versions, virtual environments, and dependencies transparently.
The framework also relies on the riscv-unified-db (UDB) gem, which requires Ruby and Bundler.
The recommended way of installing both of these tools (uv and Ruby) is using mise. mise handles tool versions and installation automatically — you don't need to install uv, Python, Ruby, or UDB manually.
To install mise:
curl https://mise.jdx.dev/install.sh | sh
After installation, verify mise is available:
mise --version
[!NOTE]
For more details on mise and alternate installation methods, see the mise getting started guide.
If you do not want to install mise, you can install
uvdirectly (see the uv installation guide) or use an existing Python environment as described in Installing without uv or mise.
[!NOTE]
See note on enabling trust in the
.mise.tomlfile below.
If you already have your own Python environment, you can install the
framework packages into it with pip instead of using mise/uv. You are
responsible for providing Python 3.10+, and Ruby/Bundler must be installed
separately (see the UDB repository).
Activate your venv, then from the cloned repository run:
pip install -e ./framework -e ./generators/testgen -e ./generators/coverage
With the venv active, make, make tests, make coverage, make spike-*,
and the other documented targets work as usual.
The ACT framework is compatible with GCC/Binutils or LLVM/Clang. Only the latest release of each is officially supported and tested in CI. Currently, that is GCC 15/Binutils 2.44 or LLVM/Clang 22.
This guide uses GCC, but if you prefer LLVM you just need to set the path for the compiler appropriately when creating your config file. See config/sail/sail-rv64-max-clang/test_config.yaml for an example.
[!NOTE]
The toolchain installation will take significant time (up to several hours depending on your system).
To install riscv64-unknown-elf-gcc:
# On Ubuntu/Debian: install dependencies
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip \
python3-tomli libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison \
flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build \
git cmake libglib2.0-dev libslirp-dev libncurses-dev
# On Fedora/CentOS/RHEL: install dependencies
sudo dnf install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel \
gawk bison flex texinfo patchutils gcc gcc-c++ zlib-devel expat-devel \
libslirp-devel ncurses-devel
# On all distros: clone and build the toolchain:
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=</path/to/install> --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
sudo make # sudo may be required depending on the selected `prefix`
[!NOTE] If you don't have sudo access, you can install the tools locally in your home directory. Simply replace
</path/to/install>with a local directory (e.g.,$HOME/riscv) and runmakewithoutsudo.
Important: Add the toolchain to your PATH by adding this line to your ~/.bashrc:
export PATH="/path/to/install/bin:$PATH"
Then verify the installation (from a new shell):
riscv64-unknown-elf-gcc --version
For more information or if you have issues installing the RISC-V toolchain, refer to the riscv-gnu-toolchain README.
The ACTs use the RISC-V Sail model to generate expected results. It is currently compatible with version 0.16 of the model.
To install the sail model:
curl --location https://github.com/riscv/sail-riscv/releases/download/0.16/sail-riscv-$(uname)-$(arch).tar.gz | sudo tar xvz --directory=/path/to/install --strip-components=1
[!NOTE] Replace
/path/to/installwith your desired directory location. This is simpler if it matches the directory used for theriscv-gnu-toolchainso both tools share the samebinfolder.
Add /path/to/install/bin to your PATH if you used a different directory than for the riscv-gnu-toolchain.
[!NOTE] If you don't have sudo access, you can extract the Sail model into your home directory by specifying a local path:
curl --location <url> | tar xvz --directory=$HOME/riscv/ --strip-components=1
Verify the installation:
sail_riscv_sim --version
For more details on the RISC-V Sail model and alternate installation methods, see the sail-riscv README.
Clone the riscv-arch-test repo:
git clone https://github.com/riscv/riscv-arch-test
On entering the top-level directory of the repository for the first
time, or on the first use of one of the build commands below, you may
see messages or a prompt from mise requiring enabling trust before
the .mise.toml configuration file can be used. This can be done by
selecting Yes in the prompt or with the following command in the
top-level directory of the repository:
mise trust .mise.toml
Several configuration files are needed to tell the ACT framework how to find your tools, what extensions and parameters are supported by your implementation, and how to perform implementation-specific functions.
Create a configuration directory for your DUT. If adding the configuration to the riscv-arch-test repo, it is recommended to place it under config/cores/<vendor>/<dut-config-name>/. For example: config/cores/cvw/cvw-rv64gc/. Configs can also be placed outside the repo. See Generate Tests and Compile ELFs for instructions on specifying the desired config file.
Your configuration directory should contain the following files:
test_config.yaml - ACT Framework configuration<dut-name>.yaml - UDB configuration filervmodel_macros.h - DUT-specific macro implementationslink.ld - Linker scriptsail.json, rvtest_config.svh, rvtest_config.h - Additional configs (will be auto-generated in the future)See config/cores/cvw/cvw-rv64gc for a complete example configuration directory.
The ACT Framework configuration YAML file contains all of the top-level configuration options. It specifies the compiler and reference model along with the paths to your UDB config file, linker script, and header directory.
It should contain the following fields:
name: Identifier for your DUT (used in output directories)compiler_exe: GCC or LLVM executable for compiling tests; absolute path or executable name on PATHobjdump_exe: Optional; absolute path or executable name on PATH; if not provided, objdump will be skippedref_model_exe: RISC-V Sail model executable (sail_riscv_sim); absolute path or executable name on PATHudb_config: Path to UDB YAML file; interpreted relative to framework config filelinker_script: Path to linker script; interpreted relative to framework config filedut_include_dir: Directory containing rvmodel_macros.h; interpreted relative to framework config file (use . for same directory as config file)harts: Optional; number of harts available for testing; defaults to 1include_priv_tests: Optional; defaults to True; if set to False, all tests that rely on privilege modes will be skippedSee test_config.yaml for an example framework config file.
A UDB configuration file is used to specify all of the implementation details for your DUT. This includes all of the supported extensions and the value of all relevant parameters.
See cvw-rv64gc.yaml for an example and the riscv-unified-db repo for more details.
rvmodel_macros.h DUT-Specific Macro ImplementationThe ACT Framework uses a selection of assembly macros to run DUT-specific code to boot the DUT, print to a console, terminate the test, and trigger interrupts. These macros are defined and explained in detail in the CTP.
Required Macros:
RVMODEL_HALT_PASSRVMODEL_HALT_FAILPrinting Macros: Can be left blank if no console is available
RVMODEL_IO_INIT(_R1, _R2, _R3) (can be omitted if not needed)RVMODEL_IO_WRITE_STR(_R1, _R2, _R3, _STR_PTR)DUT-Specific Functions: Can be left blank if not needed
RVMODEL_DATA_SECTIONRVMODEL_BOOT (can be omitted if not needed)RVMODEL_ACCESS_FAULT_ADDRESS (can be omitted if DUT does not generate some/all access faults)RVMODEL_INVISIBLE_TRAP_HANDLER(_PC_REG, _INSTRUCTION_REG, _ACTION_REG, _DEST_REG, _VALUE_REG) (can be omitted if the DUT does not trap and emulate instructions)Timer Macros: Can be left blank if machine mode is not supported.
RVMODEL_MTIME_ADDRESS (can be omitted if MTIME is not implemented)RVMODEL_MTIMECMP_ADDRESS (can be omitted if MTIMECMP is not implemented)RVMODEL_TIMER_INT_SOON_DELAYMSIP Macro: Required only for Sm version 1.13 and above. Can be omitted if machine software interrupts are not supported.
RVMODEL_MSIP_ADDRESS (can be omitted if MSIP is not memory-mapped or not tested)Interrupt Macros: Defined if a platform-specific interrupt controller is used to set or clear. MSW and SSW preferably use msip and mip.ssip rather than a platform-specific controller, but are available to be defined for designs that only support a controller. _M flavors run in machine mode and do not use T-SBI. Others may be invoked from any mode and may need T-SBI if they access memory-mapped I/O that requires machine permissions. If the _M flavor is identical to the regular flavor, it does not need to be defined.
RVMODEL_SET_MEXT_INT(_R1, _R2)RVMODEL_SET_MEXT_INT_M(_R1, _R2)RVMODEL_CLR_MEXT_INT(_R1, _R2)RVMODEL_CLR_MEXT_INT_M(_R1, _R2)RVMODEL_SET_MSW_INT(_R1, _R2)RVMODEL_CLR_MSW_INT(_R1, _R2)RVMODEL_CLR_MSW_INT_M(_R1, _R2)RVMODEL_SET_SEXT_INT(_R1, _R2)RVMODEL_SET_SEXT_INT_M(_R1, _R2)RVMODEL_CLR_SEXT_INT(_R1, _R2)RVMODEL_CLR_SEXT_INT_M(_R1, _R2)RVMODEL_SET_SSW_INT(_R1, _R2)RVMODEL_CLR_SSW_INT(_R1, _R2)RVMODEL_CLR_SSW_INT_M(_R1, _R2)RVMODEL_INTERRUPT_LATENCYSscofpmf Macros: Required if Sscofpmf is supported.
RVMODEL_HPM_COUNTERRVMODEL_MHPMEVENT_VALRVMODEL_MHPMEVENT_CODE(_R1, _R2)Complete examples are available for an example DUT (config/cores/cvw/cvw-rv64gc/rvmodel_macros.h) and for the RISC-V Sail reference model (config/sail/sail-RVA23S64/rvmodel_macros.h).
A linker script is needed to place the code and data regions in the appropriate place for the DUT's memory map. This can be customized as needed, but it must adhere to the following requirements:
ENTRY point must be rvtest_entry_point.
RVMODEL_BOOT macro, which rvtest_entry_point will jump to before anything else..text.init output section that starts at TEST_BASE, contains the .text.init input section (i.e. .text.init TEST_BASE : { *(.text.init) })..text.rvtest output section that contains the .text.rvtest input sections (i.e. .text.rvtest . : { *(.text.rvtest) *(.text.rvtest.*) } > ram). This must follow the .text.init section.MEMORY region for the RAM used by the test ELF and place all standard ACT sections in that region.
MEMORY region with > ram, sections that rely on a previous location-counter assignment, alignment, or gap must explicitly use the current location counter as their address (for example, .data . : { ... } > ram)..rodata, .data, and .bss output sections. The .bss section must define __bss_start and __bss_end for C test startup.__stack_bottom and __stack_top, using __stack_size * __num_harts bytes of stack space..text.rvmodel output section for DUT-specific (RVMODEL) code, with catch-all wildcards for any remaining text sections (i.e. .text.rvmodel . : { *(.text.rvmodel) *(.text.rvmodel.*) *(.text) *(.text.*) } > ram). This must follow the data and stack sections so that variable-size model-specific code does not affect the addresses of test data symbols (such as scratch and begin_signature). This ensures the DUT ELF and the reference-model ELF agree on data addresses.For an example linker script that should work for most basic implementations, see config/cores/cvw/cvw-rv64gc/link.ld. Most users should only need to modify the variables at the top of the sample linker script, before the /* Most users should not need to modify anything below this line. */ comment:
RAM_ORIGIN: starting address of the RAM region used by the ACT ELF.RAM_LENGTH: size of that RAM region.TEST_BASE: starting address of the ELF, usually the DUT reset vector. For most DUTs this is RAM_ORIGIN.NUM_HARTS: number of harts the test should initialize stacks for.STACK_SIZE is defined below that comment and defaults to 0x20000 bytes per hart. Users with special needs can customize the lower section layout, change STACK_SIZE, or start at their own boot code (leaving the RVMODEL_BOOT macro blank) and then jump to rvtest_entry_point.
[!NOTE]
If you modify
RAM_ORIGINorRAM_LENGTH, you also need to modify the RISC-V Sail model memory map under thememory.regionskey insail.json.
For a detailed description of the test memory layout (section ordering, contents of each section, etc.), see docs/memory_map.md.
The framework currently relies on three other config files. All three of these files will eventually be generated from the UDB config file, but that is still a work in progress, so they need to be handwritten for now. See config/cores/cvw/cvw-rv64gc for examples of these files.
sail.json RISC-V Sail model configurationrvtest_config.svh and rvtest_config.h SystemVerilog and C header files that define the supported extensions and parameter values.Once all dependencies are installed and the configuration files for your DUT have been created, you can generate the self-checking test ELFs.
Run the following command to generate test assembly files, compile them, and create self-checking ELFs:
CONFIG_FILES=<your_config_directory>/test_config.yaml make
This will create all of the ELFs that apply to your DUT (based on the provided UDB configuration) in the $WORKDIR/<config_name>/elfs directory. These ELFs have the expected results compiled into them and use the provided macros and linker script.
The following variables can be set on the command line to customize the build (e.g., DEBUG=True CONFIG_FILES=path/to/test_config.yaml make):
| Variable | Default | Description |
|---|---|---|
CONFIG_FILES | (required) | Space-separated list of test_config.yaml paths to build ELFs for. make coverage defaults to the Sail rv32/rv64 max configs when unset. |
WORKDIR | work | Directory where all build artifacts and ELFs are created. |
EXTENSIONS | (empty — all extensions) | Comma-separated list of extensions to generate tests for. When empty, generates tests for all extensions in the UDB config. |
EXCLUDE_EXTENSIONS | (see below) | Comma-separated list of extensions to exclude from test generation. Applied as a negative filter after EXTENSIONS. |
CERTIFICATE | (empty) | Certificate name. Only include tests that apply to the specified certificate. Skips M-mode tests and tests for implemented extensions that are not part of the profile. |
ENABLE_EXPERIMENTAL_EXTENSIONS | (empty) | Set to True to compile tests for unratified extensions. These tests are excluded by default. |
DEBUG | (empty) | Set to True to enable debug output (signature objdump, trace files, and trap report). Significantly slows down ELF generation. Mutually exclusive with FAST. |
VERBOSE | (empty) | Set to True to enable verbose output (prints all commands). Also implies debug mode and serializes all commands (JOBS=1). |
FAST | (empty) | Set to True to skip objdump generation for faster builds. Makes debugging mismatches harder. Mutually exclusive with DEBUG. |
CLEAN_INTERMEDIATES | (empty) | Set to True to delete each config's intermediate build/ directory (.sig.elf/.sig/.results/logs) after a successful build, keeping only the ELFs. Saves disk space (useful for CI caching). Mutually exclusive with DEBUG. |
JOBS | Auto-detected from make -j flag, or CPU count | Number of parallel build jobs for test compilation. Set to 1 for debugging test hangs. |
By default, both CONFIG_FILES and WORKDIR are relative to the riscv-arch-test directory. Use an absolute path if you need to specify a directory that is out-of-tree.
[!NOTE]
The default
EXCLUDE_EXTENSIONSlist excludes several privileged extensions that are still being stabilized or have known issues with the Sail reference model. See Makefile for the current list and reasons for each excluded extension.
The ACT framework first compiles signature-generating versions of the tests (with a .sig.elf suffix) in the $WORKDIR/<config_name>/build or $WORKDIR/common/build directory, then simulates these tests on the RISC-V Sail reference model and saves the signature into a .sig file. It then recompiles the tests with the correct results included to enable self-checking, placing the executable in the elfs directory mentioned above. The build directory contents are only of interest when troubleshooting during test development. See [LINK COMING SOON] for details.
[!NOTE]
To generate the assembly tests and coverpoints without compiling or running them, run
make tests. This only requiresmakeandmiseto be installed.
All ELFs produced in the $WORKDIR/<config_name>/elfs directory must be run on your DUT for certification. Depending on your DUT, you may need to convert these ELFs into a format that your testbench accepts (hex files are common). It is recommended to use a script or Makefile to run all ELFs in the directory on your DUT. Some examples for this are coming soon.
Each test will print one of the following to the console:
RVCP-SUMMARY: TEST PASSED - Test File "<test_name.S>"RVCP-SUMMARY: TEST FAILED - Test File "<test_name.S>"For any test that fails, additional debug information will be printed including:
Debugging a failing test typically involves examining the object dump (.elf.objdump) file to understand the failing test. Search for the failing PC and review the test. If the actual value appears to be wrong, it is likely a bug in the DUT. If the expected value appears to be wrong, it is likely due to a configuration mismatch (see below). If it is not a configuration mismatch, then it may be a bug in the ACTs themselves, such as testing a feature whose behavior should be UNSPECIFIED and thus legitimately different between the DUT and reference model. If you believe there is a bug in the ACTs themselves, please open an issue.
A common source of errors is configuration mismatches, so ensure that:
rvmodel_macros.h macros correctly implement the required functionalityAI is particularly helpful for troubleshooting configuration mismatches, but of course review that the configs it produces match your design intent.
Once the configuration files accurately reflect your design, remaining mismatches may come from:
Each of these repositories is maintained by volunteers. If you are seeking commercial support, many companies offer paid design verification services.
If the standard debug information is insufficient, use the DEBUG=True flag to generate additional artifacts alongside each test that aid in debugging:
.sig.log) — Instruction-by-instruction trace from the Sail reference model. Useful for understanding the expected execution flow..sig.trap_report) — Human-readable summary of every trap recorded in the trap signature region. Shows cause, mode, xepc, xtval, and status bits for each trap.These files are generated in the $WORKDIR/<config_name>/build directory alongside the .sig and .sig.elf files. Note that DEBUG=True significantly slows down ELF generation and is mutually exclusive with FAST. It is recommended to only enable DEBUG for an individual extension that is failing (use the EXTENSIONS variable).
Contributors are always welcome. There are several ways to contribute:
CONTRIBUTING.mdIn general:
BSD-3-Clause);Apache-2.0); whileCC-BY-4.0).The files COPYING.BSD, COPYING.APACHE and COPYING.CC in the top level directory contain the complete text of these licenses.
200 followers · starred Jun 2026
775 followers · starred Jun 2023
851 followers · starred Feb 2026
1,046 followers · starred Mar 2022
The RISC-V Architectural Certification Tests (ACTs) are a set of assembly language tests designed to certify that a design faithfully implements the RISC-V specification.
See the codeThe RISC-V Architectural Certification Tests (ACTs) are a set of assembly language tests intended to help test that a design faithfully implements the RISC-V specification. These are not verification tests and additional verification should be run on all processors.
The Architectural Certification Tests are used with the ACT4 Framework, a Makefile and Python based tool that replaces the deprecated riscof tool. The ACT4 Framework generates and compiles self-checking tests in Executable Linkable Format (ELF) for a device under test (DUT) and optionally collects coverage showing that the tests hit the coverpoints that check the normative rules. The user is then responsible for running all of the ELF files on the DUT with the user's own testbench. Each test reports success or failure, and if possible prints error messages to a console.
The ACT4 Framework requires a UDB configuration file specifying the extensions and parameters supported by the DUT; an rvmodel_macros.h file defining DUT-specific operations such as printing to a console, terminating a test with a success/failure code, and generating interrupts; and a linker script describing the DUT memory map.
RISC-V is highly configurable, such as whether misaligned accesses are allowed or how many PMP registers are implemented. Therefore, the expected results of the tests differ based on the configuration of the DUT. The ACT4 Framework selects the appropriate tests to compile based on the capabilities of the DUT. It then uses the RISC-V Sail reference model, configured to match the DUT, to compute the expected results of each test. These results are then compiled into the final self-checking ELFs.
The Architectural Certification Tests are described in full detail in the Certification Test Plan (CTP). The ACT4 Framework principles of operation are detailed in [LINK COMING SOON]. For details on adding more tests and coverpoints, see the ACT Developer's Guide. Learn more about RVA23 Certification Testing.
This section provides detailed step-by-step instructions to set up the ACT environment and generate ELFs for a Device Under Test (DUT).
The ACTs require several tools to generate and run correctly. Ensure all of the following tools are installed before proceeding.
The ACT4 framework uses make to run top-level commands. git is needed to clone the riscv-arch-test repository. Both of these packages are available in your system package manager.
To install system dependencies:
# On Ubuntu/Debian
sudo apt-get install make git
# On Fedora/CentOS/RHEL
sudo dnf install make git
mise (Tool Manager)The test generator and framework are written in Python. The recommended way of installing and running Python is using the uv project manager, which will handle Python versions, virtual environments, and dependencies transparently.
The framework also relies on the riscv-unified-db (UDB) gem, which requires Ruby and Bundler.
The recommended way of installing both of these tools (uv and Ruby) is using mise. mise handles tool versions and installation automatically — you don't need to install uv, Python, Ruby, or UDB manually.
To install mise:
curl https://mise.jdx.dev/install.sh | sh
After installation, verify mise is available:
mise --version
[!NOTE]
For more details on mise and alternate installation methods, see the mise getting started guide.
If you do not want to install mise, you can install
uvdirectly (see the uv installation guide) or use an existing Python environment as described in Installing without uv or mise.
[!NOTE]
See note on enabling trust in the
.mise.tomlfile below.
If you already have your own Python environment, you can install the
framework packages into it with pip instead of using mise/uv. You are
responsible for providing Python 3.10+, and Ruby/Bundler must be installed
separately (see the UDB repository).
Activate your venv, then from the cloned repository run:
pip install -e ./framework -e ./generators/testgen -e ./generators/coverage
With the venv active, make, make tests, make coverage, make spike-*,
and the other documented targets work as usual.
The ACT framework is compatible with GCC/Binutils or LLVM/Clang. Only the latest release of each is officially supported and tested in CI. Currently, that is GCC 15/Binutils 2.44 or LLVM/Clang 22.
This guide uses GCC, but if you prefer LLVM you just need to set the path for the compiler appropriately when creating your config file. See config/sail/sail-rv64-max-clang/test_config.yaml for an example.
[!NOTE]
The toolchain installation will take significant time (up to several hours depending on your system).
To install riscv64-unknown-elf-gcc:
# On Ubuntu/Debian: install dependencies
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip \
python3-tomli libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison \
flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build \
git cmake libglib2.0-dev libslirp-dev libncurses-dev
# On Fedora/CentOS/RHEL: install dependencies
sudo dnf install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel \
gawk bison flex texinfo patchutils gcc gcc-c++ zlib-devel expat-devel \
libslirp-devel ncurses-devel
# On all distros: clone and build the toolchain:
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=</path/to/install> --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
sudo make # sudo may be required depending on the selected `prefix`
[!NOTE] If you don't have sudo access, you can install the tools locally in your home directory. Simply replace
</path/to/install>with a local directory (e.g.,$HOME/riscv) and runmakewithoutsudo.
Important: Add the toolchain to your PATH by adding this line to your ~/.bashrc:
export PATH="/path/to/install/bin:$PATH"
Then verify the installation (from a new shell):
riscv64-unknown-elf-gcc --version
For more information or if you have issues installing the RISC-V toolchain, refer to the riscv-gnu-toolchain README.
The ACTs use the RISC-V Sail model to generate expected results. It is currently compatible with version 0.16 of the model.
To install the sail model:
curl --location https://github.com/riscv/sail-riscv/releases/download/0.16/sail-riscv-$(uname)-$(arch).tar.gz | sudo tar xvz --directory=/path/to/install --strip-components=1
[!NOTE] Replace
/path/to/installwith your desired directory location. This is simpler if it matches the directory used for theriscv-gnu-toolchainso both tools share the samebinfolder.
Add /path/to/install/bin to your PATH if you used a different directory than for the riscv-gnu-toolchain.
[!NOTE] If you don't have sudo access, you can extract the Sail model into your home directory by specifying a local path:
curl --location <url> | tar xvz --directory=$HOME/riscv/ --strip-components=1
Verify the installation:
sail_riscv_sim --version
For more details on the RISC-V Sail model and alternate installation methods, see the sail-riscv README.
Clone the riscv-arch-test repo:
git clone https://github.com/riscv/riscv-arch-test
On entering the top-level directory of the repository for the first
time, or on the first use of one of the build commands below, you may
see messages or a prompt from mise requiring enabling trust before
the .mise.toml configuration file can be used. This can be done by
selecting Yes in the prompt or with the following command in the
top-level directory of the repository:
mise trust .mise.toml
Several configuration files are needed to tell the ACT framework how to find your tools, what extensions and parameters are supported by your implementation, and how to perform implementation-specific functions.
Create a configuration directory for your DUT. If adding the configuration to the riscv-arch-test repo, it is recommended to place it under config/cores/<vendor>/<dut-config-name>/. For example: config/cores/cvw/cvw-rv64gc/. Configs can also be placed outside the repo. See Generate Tests and Compile ELFs for instructions on specifying the desired config file.
Your configuration directory should contain the following files:
test_config.yaml - ACT Framework configuration<dut-name>.yaml - UDB configuration filervmodel_macros.h - DUT-specific macro implementationslink.ld - Linker scriptsail.json, rvtest_config.svh, rvtest_config.h - Additional configs (will be auto-generated in the future)See config/cores/cvw/cvw-rv64gc for a complete example configuration directory.
The ACT Framework configuration YAML file contains all of the top-level configuration options. It specifies the compiler and reference model along with the paths to your UDB config file, linker script, and header directory.
It should contain the following fields:
name: Identifier for your DUT (used in output directories)compiler_exe: GCC or LLVM executable for compiling tests; absolute path or executable name on PATHobjdump_exe: Optional; absolute path or executable name on PATH; if not provided, objdump will be skippedref_model_exe: RISC-V Sail model executable (sail_riscv_sim); absolute path or executable name on PATHudb_config: Path to UDB YAML file; interpreted relative to framework config filelinker_script: Path to linker script; interpreted relative to framework config filedut_include_dir: Directory containing rvmodel_macros.h; interpreted relative to framework config file (use . for same directory as config file)harts: Optional; number of harts available for testing; defaults to 1include_priv_tests: Optional; defaults to True; if set to False, all tests that rely on privilege modes will be skippedSee test_config.yaml for an example framework config file.
A UDB configuration file is used to specify all of the implementation details for your DUT. This includes all of the supported extensions and the value of all relevant parameters.
See cvw-rv64gc.yaml for an example and the riscv-unified-db repo for more details.
rvmodel_macros.h DUT-Specific Macro ImplementationThe ACT Framework uses a selection of assembly macros to run DUT-specific code to boot the DUT, print to a console, terminate the test, and trigger interrupts. These macros are defined and explained in detail in the CTP.
Required Macros:
RVMODEL_HALT_PASSRVMODEL_HALT_FAILPrinting Macros: Can be left blank if no console is available
RVMODEL_IO_INIT(_R1, _R2, _R3) (can be omitted if not needed)RVMODEL_IO_WRITE_STR(_R1, _R2, _R3, _STR_PTR)DUT-Specific Functions: Can be left blank if not needed
RVMODEL_DATA_SECTIONRVMODEL_BOOT (can be omitted if not needed)RVMODEL_ACCESS_FAULT_ADDRESS (can be omitted if DUT does not generate some/all access faults)RVMODEL_INVISIBLE_TRAP_HANDLER(_PC_REG, _INSTRUCTION_REG, _ACTION_REG, _DEST_REG, _VALUE_REG) (can be omitted if the DUT does not trap and emulate instructions)Timer Macros: Can be left blank if machine mode is not supported.
RVMODEL_MTIME_ADDRESS (can be omitted if MTIME is not implemented)RVMODEL_MTIMECMP_ADDRESS (can be omitted if MTIMECMP is not implemented)RVMODEL_TIMER_INT_SOON_DELAYMSIP Macro: Required only for Sm version 1.13 and above. Can be omitted if machine software interrupts are not supported.
RVMODEL_MSIP_ADDRESS (can be omitted if MSIP is not memory-mapped or not tested)Interrupt Macros: Defined if a platform-specific interrupt controller is used to set or clear. MSW and SSW preferably use msip and mip.ssip rather than a platform-specific controller, but are available to be defined for designs that only support a controller. _M flavors run in machine mode and do not use T-SBI. Others may be invoked from any mode and may need T-SBI if they access memory-mapped I/O that requires machine permissions. If the _M flavor is identical to the regular flavor, it does not need to be defined.
RVMODEL_SET_MEXT_INT(_R1, _R2)RVMODEL_SET_MEXT_INT_M(_R1, _R2)RVMODEL_CLR_MEXT_INT(_R1, _R2)RVMODEL_CLR_MEXT_INT_M(_R1, _R2)RVMODEL_SET_MSW_INT(_R1, _R2)RVMODEL_CLR_MSW_INT(_R1, _R2)RVMODEL_CLR_MSW_INT_M(_R1, _R2)RVMODEL_SET_SEXT_INT(_R1, _R2)RVMODEL_SET_SEXT_INT_M(_R1, _R2)RVMODEL_CLR_SEXT_INT(_R1, _R2)RVMODEL_CLR_SEXT_INT_M(_R1, _R2)RVMODEL_SET_SSW_INT(_R1, _R2)RVMODEL_CLR_SSW_INT(_R1, _R2)RVMODEL_CLR_SSW_INT_M(_R1, _R2)RVMODEL_INTERRUPT_LATENCYSscofpmf Macros: Required if Sscofpmf is supported.
RVMODEL_HPM_COUNTERRVMODEL_MHPMEVENT_VALRVMODEL_MHPMEVENT_CODE(_R1, _R2)Complete examples are available for an example DUT (config/cores/cvw/cvw-rv64gc/rvmodel_macros.h) and for the RISC-V Sail reference model (config/sail/sail-RVA23S64/rvmodel_macros.h).
A linker script is needed to place the code and data regions in the appropriate place for the DUT's memory map. This can be customized as needed, but it must adhere to the following requirements:
ENTRY point must be rvtest_entry_point.
RVMODEL_BOOT macro, which rvtest_entry_point will jump to before anything else..text.init output section that starts at TEST_BASE, contains the .text.init input section (i.e. .text.init TEST_BASE : { *(.text.init) })..text.rvtest output section that contains the .text.rvtest input sections (i.e. .text.rvtest . : { *(.text.rvtest) *(.text.rvtest.*) } > ram). This must follow the .text.init section.MEMORY region for the RAM used by the test ELF and place all standard ACT sections in that region.
MEMORY region with > ram, sections that rely on a previous location-counter assignment, alignment, or gap must explicitly use the current location counter as their address (for example, .data . : { ... } > ram)..rodata, .data, and .bss output sections. The .bss section must define __bss_start and __bss_end for C test startup.__stack_bottom and __stack_top, using __stack_size * __num_harts bytes of stack space..text.rvmodel output section for DUT-specific (RVMODEL) code, with catch-all wildcards for any remaining text sections (i.e. .text.rvmodel . : { *(.text.rvmodel) *(.text.rvmodel.*) *(.text) *(.text.*) } > ram). This must follow the data and stack sections so that variable-size model-specific code does not affect the addresses of test data symbols (such as scratch and begin_signature). This ensures the DUT ELF and the reference-model ELF agree on data addresses.For an example linker script that should work for most basic implementations, see config/cores/cvw/cvw-rv64gc/link.ld. Most users should only need to modify the variables at the top of the sample linker script, before the /* Most users should not need to modify anything below this line. */ comment:
RAM_ORIGIN: starting address of the RAM region used by the ACT ELF.RAM_LENGTH: size of that RAM region.TEST_BASE: starting address of the ELF, usually the DUT reset vector. For most DUTs this is RAM_ORIGIN.NUM_HARTS: number of harts the test should initialize stacks for.STACK_SIZE is defined below that comment and defaults to 0x20000 bytes per hart. Users with special needs can customize the lower section layout, change STACK_SIZE, or start at their own boot code (leaving the RVMODEL_BOOT macro blank) and then jump to rvtest_entry_point.
[!NOTE]
If you modify
RAM_ORIGINorRAM_LENGTH, you also need to modify the RISC-V Sail model memory map under thememory.regionskey insail.json.
For a detailed description of the test memory layout (section ordering, contents of each section, etc.), see docs/memory_map.md.
The framework currently relies on three other config files. All three of these files will eventually be generated from the UDB config file, but that is still a work in progress, so they need to be handwritten for now. See config/cores/cvw/cvw-rv64gc for examples of these files.
sail.json RISC-V Sail model configurationrvtest_config.svh and rvtest_config.h SystemVerilog and C header files that define the supported extensions and parameter values.Once all dependencies are installed and the configuration files for your DUT have been created, you can generate the self-checking test ELFs.
Run the following command to generate test assembly files, compile them, and create self-checking ELFs:
CONFIG_FILES=<your_config_directory>/test_config.yaml make
This will create all of the ELFs that apply to your DUT (based on the provided UDB configuration) in the $WORKDIR/<config_name>/elfs directory. These ELFs have the expected results compiled into them and use the provided macros and linker script.
The following variables can be set on the command line to customize the build (e.g., DEBUG=True CONFIG_FILES=path/to/test_config.yaml make):
| Variable | Default | Description |
|---|---|---|
CONFIG_FILES | (required) | Space-separated list of test_config.yaml paths to build ELFs for. make coverage defaults to the Sail rv32/rv64 max configs when unset. |
WORKDIR | work | Directory where all build artifacts and ELFs are created. |
EXTENSIONS | (empty — all extensions) | Comma-separated list of extensions to generate tests for. When empty, generates tests for all extensions in the UDB config. |
EXCLUDE_EXTENSIONS | (see below) | Comma-separated list of extensions to exclude from test generation. Applied as a negative filter after EXTENSIONS. |
CERTIFICATE | (empty) | Certificate name. Only include tests that apply to the specified certificate. Skips M-mode tests and tests for implemented extensions that are not part of the profile. |
ENABLE_EXPERIMENTAL_EXTENSIONS | (empty) | Set to True to compile tests for unratified extensions. These tests are excluded by default. |
DEBUG | (empty) | Set to True to enable debug output (signature objdump, trace files, and trap report). Significantly slows down ELF generation. Mutually exclusive with FAST. |
VERBOSE | (empty) | Set to True to enable verbose output (prints all commands). Also implies debug mode and serializes all commands (JOBS=1). |
FAST | (empty) | Set to True to skip objdump generation for faster builds. Makes debugging mismatches harder. Mutually exclusive with DEBUG. |
CLEAN_INTERMEDIATES | (empty) | Set to True to delete each config's intermediate build/ directory (.sig.elf/.sig/.results/logs) after a successful build, keeping only the ELFs. Saves disk space (useful for CI caching). Mutually exclusive with DEBUG. |
JOBS | Auto-detected from make -j flag, or CPU count | Number of parallel build jobs for test compilation. Set to 1 for debugging test hangs. |
By default, both CONFIG_FILES and WORKDIR are relative to the riscv-arch-test directory. Use an absolute path if you need to specify a directory that is out-of-tree.
[!NOTE]
The default
EXCLUDE_EXTENSIONSlist excludes several privileged extensions that are still being stabilized or have known issues with the Sail reference model. See Makefile for the current list and reasons for each excluded extension.
The ACT framework first compiles signature-generating versions of the tests (with a .sig.elf suffix) in the $WORKDIR/<config_name>/build or $WORKDIR/common/build directory, then simulates these tests on the RISC-V Sail reference model and saves the signature into a .sig file. It then recompiles the tests with the correct results included to enable self-checking, placing the executable in the elfs directory mentioned above. The build directory contents are only of interest when troubleshooting during test development. See [LINK COMING SOON] for details.
[!NOTE]
To generate the assembly tests and coverpoints without compiling or running them, run
make tests. This only requiresmakeandmiseto be installed.
All ELFs produced in the $WORKDIR/<config_name>/elfs directory must be run on your DUT for certification. Depending on your DUT, you may need to convert these ELFs into a format that your testbench accepts (hex files are common). It is recommended to use a script or Makefile to run all ELFs in the directory on your DUT. Some examples for this are coming soon.
Each test will print one of the following to the console:
RVCP-SUMMARY: TEST PASSED - Test File "<test_name.S>"RVCP-SUMMARY: TEST FAILED - Test File "<test_name.S>"For any test that fails, additional debug information will be printed including:
Debugging a failing test typically involves examining the object dump (.elf.objdump) file to understand the failing test. Search for the failing PC and review the test. If the actual value appears to be wrong, it is likely a bug in the DUT. If the expected value appears to be wrong, it is likely due to a configuration mismatch (see below). If it is not a configuration mismatch, then it may be a bug in the ACTs themselves, such as testing a feature whose behavior should be UNSPECIFIED and thus legitimately different between the DUT and reference model. If you believe there is a bug in the ACTs themselves, please open an issue.
A common source of errors is configuration mismatches, so ensure that:
rvmodel_macros.h macros correctly implement the required functionalityAI is particularly helpful for troubleshooting configuration mismatches, but of course review that the configs it produces match your design intent.
Once the configuration files accurately reflect your design, remaining mismatches may come from:
Each of these repositories is maintained by volunteers. If you are seeking commercial support, many companies offer paid design verification services.
If the standard debug information is insufficient, use the DEBUG=True flag to generate additional artifacts alongside each test that aid in debugging:
.sig.log) — Instruction-by-instruction trace from the Sail reference model. Useful for understanding the expected execution flow..sig.trap_report) — Human-readable summary of every trap recorded in the trap signature region. Shows cause, mode, xepc, xtval, and status bits for each trap.These files are generated in the $WORKDIR/<config_name>/build directory alongside the .sig and .sig.elf files. Note that DEBUG=True significantly slows down ELF generation and is mutually exclusive with FAST. It is recommended to only enable DEBUG for an individual extension that is failing (use the EXTENSIONS variable).
Contributors are always welcome. There are several ways to contribute:
CONTRIBUTING.mdIn general:
BSD-3-Clause);Apache-2.0); whileCC-BY-4.0).The files COPYING.BSD, COPYING.APACHE and COPYING.CC in the top level directory contain the complete text of these licenses.
200 followers · starred Jun 2026
775 followers · starred Jun 2023
851 followers · starred Feb 2026
1,046 followers · starred Mar 2022