Open-source project
riscv/riscv-arch-test avatar
riscv/riscv-arch-test

riscv-arch-test turns the Sail model into self-checking ELFs

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.

802 stars378 forksAssemblyApache-2.0

At a glance

What is it?
The RISC-V Architectural Certification Tests are assembly tests generated by the ACT4 framework, which uses the Sail reference model to compute expected results and compiles them into self-checking ELF binaries for a device under test. It proves conformance to the specification, not functional correctness, and the hardware run stays with you.
Who is it for?
Adopt riscv-arch-test when you need certification evidence that a RISC-V design implements the architecture as written, and when your team owns a testbench that can run the generated ELF files on real hardware. Do not adopt it as a substitute for functional verification, since the project states plainly that these are not verification tests.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Assembly, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Certification is not verification, and the project says so first

The repository opens with the distinction that matters most for anyone budgeting this work: the RISC-V Architectural Certification Tests are assembly language tests intended to help test that a design faithfully implements the RISC-V specification, and they are explicitly not verification tests, with additional verification still expected on all processors. That framing sets a firm boundary around what the tool can prove. A certified design has been shown to behave as the architecture manual says in the areas the tests cover. It has not been shown to be free of functional bugs in application code. The audience is therefore a specific group: processor architects and implementation teams who need a certification package for a customer or a compliance milestone, and who already have a way of running code on the device under test. Engineers looking for a bug-finding test suite are the wrong audience, and the first line of the project description is there to stop them early.

Expected results come from the Sail reference model, not from you

The mechanism behind the tests is the part that distinguishes this from a hand written test suite. The ACT4 framework selects the appropriate tests to compile based on the capabilities of the device under test, then uses the RISC-V Sail reference model, configured to match the same device, to compute the expected result of each selected test. Those computed expectations are compiled into the final self-checking ELFs, so each binary carries its own pass and fail logic and does not need an external oracle at run time. This matters because RISC-V is highly configurable, and the project gives two examples: whether misaligned accesses are allowed, and how many PMP registers are implemented. The same architectural rule produces a different expected outcome on two different chips, so a suite with hardcoded expectations would be wrong for one of them. Deriving the answers from the model means the expectations follow the configuration rather than fight it.

Three files describe the device under test

The framework cannot know your chip, so three inputs describe it. The first is a UDB configuration file specifying the extensions and parameters supported by the device under test, which comes from the riscv-unified-db project and therefore needs Ruby and Bundler on the machine. The second is an rvmodel_macros.h file defining device specific operations, and the project names three of them: printing to a console, terminating a test with a success or failure code, and generating interrupts. That header is the seam between the generated test code and your hardware, so it is where your testbench hooks in. The third is a linker script describing the device memory map. Everything else in the framework is generic. A team taking this on should expect to write these three files per design, and should expect the linker script and the console print path to be where the first integration problems appear, since a test that cannot report failure to the console is not a useful test.

Getting the toolchain in place is the slowest part of the setup

The framework itself is a Makefile and Python based tool, but the prerequisites around it are heavy. The system dependencies are make and git, and the documentation gives both package manager forms:

bash
# On Ubuntu/Debian
sudo apt-get install make git

# On Fedora/CentOS/RHEL
sudo dnf install make git

Python is handled through the uv project manager, and Ruby with Bundler is needed for the UDB gem. The recommended way to get both is mise, which installs tool versions automatically:

bash
curl https://mise.jdx.dev/install.sh | sh

If you already have a Python environment, the documented alternative is to install the framework packages into it with pip, with Python 3.10+ and Ruby provided separately:

bash
pip install -e ./framework -e ./generators/testgen -e ./generators/coverage

The heavier dependency is the compiler. The framework works with GCC/Binutils or LLVM/Clang, but only the latest release of each is supported and tested in CI, which the documentation states is GCC 15/Binutils 2.44 or LLVM/Clang 22. The toolchain is built from the riscv-gnu-toolchain repository, and the note about it warns that the build takes significant time, up to several hours depending on your system. That warning is the practical reason to plan the environment early rather than treat it as a setup step.

Generating the ELFs means pointing make at a config file

Generation is driven from the top level Makefile, where CONFIG_FILES is a required variable and the output lands in the work/<config-name>/elfs directory. The Dockerfile in the repository shows the invocation used in the container image, with the config path spelled out:

bash
CONFIG_FILES=config/cores/<vendor>/<dut>/test_config.yaml make

The same Makefile exposes the knobs that decide what gets built. EXTENSIONS is a comma separated list of extensions to generate tests for, blank meaning all tests. EXCLUDE_EXTENSIONS overrides that list as a negative filter. CERTIFICATE limits the selection to tests relevant to a named certificate. ENABLE_EXPERIMENTAL_EXTENSIONS pulls in tests for extensions that are not ratified, which is a deliberate way to opt into unstable ground rather than discover it by accident. Output control is separate: DEBUG enables signature objdump, trace files and a trap report and slows generation significantly, FAST skips objdump generation for speed at the cost of harder mismatch debugging, VERBOSE implies DEBUG and serialises the build with JOBS=1 while printing each command, and CLEAN_INTERMEDIATES removes a config's intermediate build directory after success.

The repository ships a Dockerfile whose purpose is stated in its own header comments: it is the riscv-arch-test ACT4 build environment, and it includes the riscv-gnu-toolchain built from source and statically linked, mise, and the sail-riscv reference model. The usage comments in the file show the intended sequence, starting with the build:

bash
docker build -t riscv-act4 .

and then running the container with your vendor configuration directory mounted read only and a work directory mounted for outputs, with the note that the work directory must be created first or it will not be owned by the current user. The container can also be run with your own user id when your account is not 1000:1000, which the comments cover with a second variant of the same run command. The image is built on a pinned ubuntu:26.04 digest and takes build arguments for the toolchain prefix, the toolchain version and the SAIL_VERSION. This is the practical escape hatch for teams who cannot or will not spend hours on a toolchain build.

Running the tests on hardware is your testbench's job

The framework generates and compiles the ELF files and can optionally collect coverage showing that the tests hit the coverpoints that check the normative rules. It then stops. The documentation is explicit that the user is responsible for running all of the ELF files on the device under test with their own testbench, and that each test reports success or failure and, if possible, prints error messages to a console. Two practical points follow. First, the optional coverage collection tells you whether a rule was actually exercised, which is the difference between a run that passed and a run that checked something. Second, the word optional attaches to printing error messages, so a design with no console path will produce binaries that report status some other way, or none. The repository also ships a testplans directory and a run_tests.py script at the top level, and the framework has a testbench directory of its own, which suggests the separation between generation and execution is deliberate rather than a gap. The alternative to a hardware testbench is the simulator path the Makefile exposes, where make, make tests, make coverage and the make spike-* targets are documented as working targets once the Python environment is active. Running the same self-checking ELFs on a Spike style simulator changes who provides the execution environment rather than what is tested, which is a different trade-off. A simulator gives you a repeatable machine you do not have to instrument and a uniform memory map, and it will find configuration mismatches in your configuration files quickly. It cannot tell you that your real silicon misbehaves in a way the model does not, so it validates the generated expectations rather than the device. The practical pattern is to use the simulator while iterating on configuration, then move the same ELFs onto hardware for the run that counts.

Where this approach leaves gaps

Several limits are worth stating plainly. The first is the one the project states itself: these are certification tests, not verification tests, so a clean run leaves functional bugs untouched. The second is documentation maturity. The Certification Test Plan at riscv.github.io/riscv-arch-test/ctp.html is described as the full description of the tests, and there is a Developer Guide for adding tests and coverpoints, but the principles of operation for the ACT4 Framework are linked as coming soon, so the authoritative narrative for how the framework behaves is the Makefile and the source. Third, the toolchain constraint is narrow: only the latest GCC or LLVM release is supported and tested in CI, so a team stuck on an older cross compiler is outside the tested path. Fourth, the framework needs a working Ruby and Bundler setup for the UDB gem in addition to Python, and the trusted configuration mechanism in .mise.toml requires attention, which the documentation flags as a note. Fifth, and most practically for hardware teams, the toolchain build cost is measured in hours, so on a shared build machine the container image is the version to standardise on.

Release cadence and what a fork inherits

The repository is not archived and the last push was on 2026-10-20, with the default branch named act4. The recent release names are certification document bundles rather than versioned library releases, for example cert-docs-2026-10-20-06-39-e82b786 and cert-docs-2026-10-19-23-35-38652ee, which tells you the artifact people consume is the certification document set. The top level carries the expected project furniture: a CHANGELOG.md, CONTRIBUTING.md, AGENTS.md and CLAUDE.md, a COPYING.APACHE alongside COPYING.BSD and COPYING.CC, a pre-commit config and a renovate configuration. Licensing is Apache-2.0, which is worth noting for a specification conformance suite because adopters embed or modify the generated tests in their own regression flows. Anyone forking this should watch the act4 branch rather than master, since that is where the framework named in the documentation actually lives, and should read the Developer Guide before adding coverpoints, because the coverage numbers are only meaningful if the coverpoints and the tests stay in step.

Editorial conclusion

Adopt riscv-arch-test when you need certification evidence that a RISC-V design implements the architecture as written, and when your team owns a testbench that can run the generated ELF files on real hardware. Do not adopt it as a substitute for functional verification, since the project states plainly that these are not verification tests. Before starting, confirm that a riscv64-unknown-elf toolchain is built or reachable, that Ruby and Bundler are available for the UDB gem, and that your DUT configuration file names the extensions and parameters it actually implements.

Frequently asked questions

Do the RISC-V Architectural Certification Tests replace verification testing?

No. The project states that the ACTs are not verification tests and that additional verification should be run on all processors, so a certification pass only covers conformance to the RISC-V specification.

How does riscv-arch-test decide what a passing test looks like?

The ACT4 Framework configures the RISC-V Sail reference model to match the device under test and uses it to compute the expected result of each test, then compiles those expectations into the self-checking ELF files.

What files do I have to provide to run riscv-arch-test on my own design?

A UDB configuration file listing the extensions and parameters the device supports, an rvmodel_macros.h defining device specific operations such as console printing, test termination and interrupt generation, and a linker script describing the memory map.

Which compiler does the ACT4 framework support?

It is compatible with GCC/Binutils or LLVM/Clang, and only the latest release of each is supported and tested in CI, which the documentation gives as GCC 15/Binutils 2.44 or LLVM/Clang 22. Building that toolchain from source can take several hours.

Who runs the generated ELF files on the hardware?

You do. The framework generates and compiles the self-checking ELFs and can optionally collect coverage, but the documentation states the user is responsible for running all of the ELF files on the device under test with their own testbench.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. riscv/riscv-arch-test on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/riscv-riscv-arch-test.svg)](https://hysenlabs.com/projects/riscv-riscv-arch-test)

Was this useful?