This is work in progress. The interfaces described here are likely to change as the project matures.
riscv-formal
is a framework for formal verification of RISC-V processors.
It consists of the following components:
- A processor-independent formal description of the RISC-V ISA
- A set of formal testbenches for each processor supported by the framework
- The specification for the RISC-V Formal Interface (RVFI) that must be implemented by a processor core to interface with
riscv-formal
. - Some auxiliary proofs and scripts, for example to prove correctness of the ISA spec agains riscv-isa-sim.
See cores/picorv32/ for example bindings for the PicoRV32 processor core.
A processor core usually will implement RVFI as an optional feature that is only enabled for verification. Sequential equivalence check can be used to prove equivalence of the processor versions with and without RVFI.
The current focus is on implementing formal models of all instructions from the RISC-V RV32I and RV64I ISAs, and formally verifying those models against the models used in the RISC-V "Spike" ISA simulator.
riscv-formal
uses the FOSS SymbiYosys formal verification flow. All properties are expressed using immediate assertions/assumptions for maximal compatibility with other tools.
- Quickstart Guide
- The RVFI Interface Specification
- RISC-V Formal CSR Sematics
- Configuration macros used by riscv-formal
- The riscv-formal Verification Procedure
- Examples of bugs found with riscv-formal
- References and related work
- Create a
riscv-formal/cores/<core-name>/
directory - Write a wrapper module that instantiates the core under test and abstracts models of necessary
peripherals (usually just memory)
- Use the RVFI helper macros
RVFI_OUTPUTS
andRVFI_CONN
for quickly defining wrapper connections - See picorv32/wrapper.sv for a simple example wrapper
- Use the RVFI helper macros
- Write a
checks.cfg
config file for the new core- See nerv/checks.cfg for an example utilising most of the checks
- Refer to The riscv-formal Verification Procedure for a complete guide on
available checks, and a more detailed view of using
genchecks.py
- Generate checks with
python3 ../../checks/genchecks.py
from the<core-name>
directory- Checks are generated in
riscv-formal/cores/<core-name>/checks
- Checks are generated in
- Run checks with
make -C checks j$(nproc)
- The quickstart guide goes through the process of running riscv-formal with some of the included cores. It is recommended to follow this guide before adding a new core.
- See picorv32/Makefile for an example makefile to manage generation and execution of checks.
- Out of tree generation with
genchecks.py
is not currently supported. - Refer to docs/config.md and docs/procedure.md for a
breakdown of how to use riscv-formal checks without using
genchecks.py
. - The cover check can be used to help determine the depth needed for the core to reach certain states as needed for other checks.