Skip to content
STIMSMITH

Debug Mode

Concept WIKI v2 · 8/4/2026

Debug Mode is a special execution state entered by a RISC-V core (such as Ibex) in response to external debug requests. Because instruction-set simulator (ISS) golden models cannot model traps caused by external stimulus, verifying Debug Mode entry and associated CSR updates in the Ibex end-to-end RTL/ISS co-simulation flow relies on a runtime handshaking mechanism provided by the RISCV-DV instruction generator. The handshake lets the running core report status information to the testbench during execution, with the Ibex testbench using the signature address `0x8ffffffc`. Trace comparison is adapted so that only the final register values at end of test are compared, since the ISS trace log does not contain execution information for code that runs in the debug ROM or interrupt handlers.

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.

The RISC-V Debug Specification exists precisely because hardware debug needs a common architecture across diverse implementations, and Debug Mode is the architectural vehicle by which a RISC-V core transitions into that debug-specific execution context.

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. Both the core trace log and the ISS trace log are parsed to collect information about every register writeback, and the two sets of writeback data are compared to verify that the core writes the correct data to the correct registers in the correct order.

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.

Projects frequently bring up lockstep comparison, trace hooks, and Debug Mode validation too late, after they have already focused on instruction execution. By that point, missing retirement comparators, poor trace visibility, or incomplete debug-state checking can turn what would have been a one-day bug into a one-week investigation. Effective lockstep co-simulation therefore depends not only on comparison logic but also on a well-defined debug and trace strategy that provides sufficient visibility into internal state, control flow, and exception-handling paths, so that the project knows early on how Debug Mode will be entered and observed and which CSRs and memory accesses must be checked.

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.

RISCV-DV Debug Support

The RISCV-DV instruction generator provides first-class support for Debug Mode. Among its supported features it lists "Debug mode support, with fully randomized debug ROM", which provides a source of randomized Debug Mode stimulus for verifying Debug Mode entry, debug ROM execution, and CSR updates. RISCV-DV also supports handshake communication with the testbench and co-simulation with multiple ISSes (spike, riscv-ovpsim, whisper, sail-riscv), all of which underpin the Ibex Debug Mode verification approach.

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 regression
  • make OUT=xxx — run a full regression, redirect the output directory
  • make TEST=riscv_machine_mode_rand_test ITERATIONS=1 — run a single test
  • make TEST=riscv_machine_mode_rand_test ITERATIONS=1 SEED=123 WAVES=1 — run a test with a specific seed and dump waveforms
  • make ... VERBOSE=1 — verbose logging
  • make ... LSF_CMD="bsub -Is" — run multiple tests in parallel through LSF
  • python3 sim.py --help — get the command reference of the simulation script
  • make gen — generate the assembly tests only
  • make TEST=xxx compile,rtl_sim — compile and run RTL simulation only
  • make COV=1 — run a full regression with coverage

LINKED ENTITIES

1 links

CITATIONS

8 sources
8 citations
[1] Debug Mode is a special execution state of the Ibex core entered in response to external debug requests. Verification — Ibex Documentation
[2] ISS models can simulate traps due to exceptions but cannot model traps due to external stimulus, so the ISS trace log will not contain execution information for code in the debug ROM or interrupt handlers. Verification — Ibex Documentation
[3] The handshaking mechanism from the RISCV-DV instruction generator is used to verify Debug Mode entry and correct CSR updates, with the Ibex testbench using signature address 0x8ffffffc. Verification — Ibex Documentation
[4] API tasks in dv/uvm/core_ibex/tests/core_ibex_base_test.sv integrate the handshake into the Ibex test environment, and usage examples are in dv/uvm/core_ibex/tests/core_ibex_test_lib.sv. Verification — Ibex Documentation
[5] Only the final register values at the end of the test are compared between the core and ISS trace logs, because debug ROM and trap-handler code do not appear in the ISS trace log. Verification — Ibex Documentation
[6] The Makefile dv/uvm/core_ibex/Makefile drives the end-to-end RTL/ISS co-simulation flow that exercises Debug Mode, and provides commands such as make, make OUT=, make TEST=, make VERBOSE=, make LSF_CMD=, make gen, make compile,rtl_sim, and make COV=1. Verification — Ibex Documentation
[7] RISCV-DV provides Debug Mode support with a fully randomized debug ROM. RISCV-DV Processor Verification
[8] The RISC-V Debug Specification exists because hardware debug needs a common architecture across diverse implementations, and many projects delay lockstep, trace, and Debug Mode validation until late in the schedule. RISC-V Verification: Five Places Projects Lose Weeks

VERSION HISTORY

v2 · 8/4/2026 · minimax/minimax-m3 (current)
v1 · 6/6/2026 · minimax/minimax-m3