Blogs

Accelerating RISC-V Processor Verification: A Co-Simulation Strategy

September 17, 2024

The NOEL-V is a synthesizable VHDL model of a processor that implements the RISC-V architecture. The NOEL-V is designed for space applications, targeting high-performance and fault-tolerance. The processor model offers many customization options and its advanced design required advanced verification strategies.

The Challenge of Processor Verification

Traditional processor verification methodologies often rely on a combination of simulation, formal methods, and emulation. Simulation-based approaches entail executing test vectors on a model of the processor to validate its behavior against the expected outcomes. While effective, simulation is time-consuming and may not capture all corner cases. Formal methods, on the other hand, provide mathematical proofs of correctness but are often limited in scalability and practicality. Emulation offers a middle ground, but it is costly and complex to set up.

The RISC-V ecosystem’s flexibility allows us to tailor verification approaches to better suit various implementations and configurations.

Our Approach: Comparative Analysis with SPIKE

Our verification strategy for the NOEL-V processor revolves around comparing execution flows between two models: the behavioural simulation of NOEL-V’s VHDL implementation and the SPIKE RISC-V ISA simulator. This method is based on:

  • Maintaining consistent states between the two processor models. Any deviations are pinpointed with accuracy, indicating discrepancies between the implementation and the reference model.
  • Introduction of implementation-specific behaviours into SPIKE with minimal alterations: certain hardware components, like specific I/O devices, may require state overwriting in SPIKE to ensure a consistent state.

Leveraging Verilator and VHDL Integration

Verilator, an open-source tool, converts Verilog designs into cycle-accurate behavioral models in C++. This conversion speeds up simulation and integrates with SPIKE, which is also C++-based. For our VHDL-based NOEL-V design, we use GHDL to convert VHDL code into a Verilog netlist, which then is fed to Verilator. This allows us also to reduce considerably the simulation time, comparing to other HDL simulators.

Enhancing SPIKE with a custom API

To facilitate effective co-simulation, we turned SPIKE into a shared library and developed a comprehensive API to interact with it. This allows for interaction through Direct Programming Interface (DPI) calls within traditional RTL testbenches. Moreover, it can integrate with Verilator C++ testbenches, offering native interaction capabilities.

This API supports various functionalities essential for efficient processor verification and debugging, such as:

  • Per hart interaction
  • Instruction stepping
  • CSR write/read
  • Register write/read
  • Get current PC and next PC
  • Get current Privilege mode
  • Atomics: Store conditional cancelation
  • Interrupt: NMI + Normal IRQ
  • Memory transactions (virtual & physical address)
  • Page walk
  • Disassembly (for convenience)

Optimizing Debugging with Snapshots

Despite Verilator’s high speed as a simulator, it doesn’t match the performance of physical hardware. To address this, we implemented snapshot capabilities using the SMRNMI RISC-V extension. This allows us to capture the entire machine state and resume execution from any point, dramatically speeding up testing and debugging processes.

Conclusion

Our co-simulation strategy for NOEL-V, which combines behavioural simulation with SPIKE and utilizes advanced tools like Verilator and GHDL, facilitates verification using a very large number of test vectors, without requiring an unreasonably long simulation time. By integrating SPIKE with a custom API and implementing snapshot capabilities, we enhance the efficiency of our testing procedures and accelerate the whole design process.