Overview
In the Ibex core verification flow, Debug Mode is a privileged execution state entered by the core when it receives an external debug request. Verifying correct entry into Debug Mode, and verifying that the appropriate Control and Status Registers (CSRs) are updated, is a distinct concern from normal instruction-level correctness checking.
Verification Challenge
The standard RTL/ISS co-simulation flow compares every register writeback produced by the core against a trace log produced by a golden-model ISS. This works well for ordinary execution, but it breaks down for situations driven by external stimulus such as interrupts and debug requests.
ISS models can simulate traps that arise from architectural exceptions, but they cannot model traps that arise from external stimulus. This means there is no reference trace to compare against once the core enters Debug Mode or an interrupt handler, and the ISS trace log will not contain any execution information for code that runs in the debug ROM or in any interrupt handler.
Verification Approach
To provide support for these scenarios and verify that the core has:
- entered the proper interrupt handler,
- entered Debug Mode properly, and
- updated any CSRs correctly,
the handshaking mechanism provided by the RISCV-DV instruction generator is heavily used. This mechanism effectively allows the core to send status information to the testbench during program execution, enabling any analysis required to increase verification effectiveness. The signature address used by the Ibex testbench for this handshaking is 0x8ffffffc.
A small set of API tasks provided in dv/uvm/core_ibex/tests/core_ibex_base_test.sv enable easy and efficient integration of this mechanism into the test environment, and real-simulation usage can be inspected in dv/uvm/core_ibex/tests/core_ibex_test_lib.sv. The mechanism is extensively used to provide runtime verification for situations involving external debug requests, interrupt assertions, and memory faults.
Adapted Trace Comparison
Because the handshake mechanism already provides a correctness check for these external-stimulus scenarios, the trace log comparison is adjusted rather than abandoned. A naive per-writeback comparison would produce incorrect results, since the ISS trace log will not contain any execution information for code running in the debug ROM or in any interrupt handler code.
As a result, only the final values contained in every register at the end of the test are compared against each other. Code executed in the debug ROM and trap handlers is not expected to corrupt register state in the rest of the program, so this end-of-test comparison remains a valid correctness signal.
Driving the Flow
The full end-to-end RTL/ISS co-simulation flow that exercises Debug Mode scenarios is driven by the Makefile in dv/uvm/core_ibex/Makefile. Common invocations include:
make— run a full regressionmake OUT=xxx— run a full regression, redirect the output directorymake TEST=riscv_machine_mode_rand_test ITERATIONS=1— run a single testmake TEST=riscv_machine_mode_rand_test ITERATIONS=1 SEED=123 WAVES=1— run a test with a specific seed and dump waveformsmake ... VERBOSE=1— verbose loggingmake ... LSF_CMD="bsub -Is"— run multiple tests in parallel through LSFmake TEST=xxx compile,rtl_sim— compile and run RTL simulation onlymake COV=1— run a full regression with coverage