Skip to content

[Bug Report] rvfi_intr is not set on the first instruction of an exception handler #2556

Open

Description

@qinkejiu

Observed Behavior

On lowRISC Ibex f451552 built with +define+RVFI, every synchronous exception handler entry (ecall, ebreak, illegal instruction, load/store/fetch access fault) retires with rvfi_intr=0, while every interrupt or NMI handler entry retires with rvfi_intr=1: 37/37 exception handler entries have rvfi_intr=0 and 27/27 interrupt/NMI entries have rvfi_intr=1 across 72 archived traces, with no spurious entry in either direction. Severity P2: trace-only, no architectural state corruption.

rvfi_intr marks the first instruction of a trap handler, for synchronous exceptions and asynchronous interrupts alike. It is not the same signal as rvfi_trap: the faulting instruction retires with rvfi_trap=1, and the first handler instruction retires with rvfi_intr=1, on different rows.

In rtl/ibex_core.sv:2409-2421 the condition at :2417 accepts only EXC_PC_IRQ, so the trap-PC assignment it guards at :2419 never runs for EXC_PC_EXC:

// rtl/ibex_core.sv:2409-2421
// rvfi_intr must be set for first instruction that is part of a trap handler.
assign rvfi_intr_d = instr_first_cycle_id ? rvfi_set_trap_pc_q : rvfi_intr_q;
...
if (pc_set && pc_mux_id == PC_EXC && (exc_pc_mux_id == EXC_PC_IRQ)) begin
  rvfi_set_trap_pc_d = 1'b1;

EXC_PC_DBD and EXC_PC_DBG_EXC are debug entries, not trap handlers, and correctly stay out. PR #191 (merged 2019-07-26, "RVFI: re-add accidentally removed rvfi_intr signal") introduced the marker with both terms, so the exception case was implemented upstream and later dropped:

PR #191: if (pc_set && pc_mux_id == PC_EXC &&
              (exc_pc_mux_id == EXC_PC_EXC || exc_pc_mux_id == EXC_PC_IRQ)) begin
now:     if (pc_set && pc_mux_id == PC_EXC && (exc_pc_mux_id == EXC_PC_IRQ)) begin

No upstream issue covers the exception-entry case; #2231 is about rvfi_pc_wdata for mret/dret, a different field.

Expected Behavior

riscv-formal/docs/rvfi.md:35, the interface Ibex names in doc/03_reference/rvfi.rst, requires: "rvfi_intr must be set for the first instruction that is part of a trap handler, i.e. an instruction that has a rvfi_pc_rdata that does not match the rvfi_pc_wdata of the previous instruction."

A synchronous exception vector entry qualifies: mtvec is the trap-vector base for exceptions and interrupts alike, so the first instruction fetched from mtvec, or from mtvec + 4*cause for a vectored interrupt, should retire with rvfi_intr=1, while the faulting instruction should still retire with rvfi_trap=1.

The minimal fix adds the synchronous-exception term at rtl/ibex_core.sv:2417 and keeps the debug-entry exclusion:

if (pc_set && pc_mux_id == PC_EXC &&
    (exc_pc_mux_id == EXC_PC_EXC || exc_pc_mux_id == EXC_PC_IRQ)) begin

EXC_PC_DBD and EXC_PC_DBG_EXC remain excluded because they are debug entries, not trap handlers.

Steps to reproduce the issue

From the directory holding run.sh, tb_rvfi.sv, prog_ecall.hex and prog_timer.hex:

IBEX=/path/to/ibex ./run.sh

run.sh builds ibex_core with Verilator twice (WB=0,BTALU=0 and WB=1,BTALU=1), runs both images in each configuration with +MAXCYC=900, and compares one RVFI dump row per program: ecall at 0x1080 vectors to 0x1000, and the timer IRQ asserted from reset (+IRQ0=2 +IRQ0LEN=60) is enabled by mie.MTIE/mstatus.MIE and vectors to 0x101c.

Expected output line, with exit 0:

VERDICT: BUG_CONFIRMED IBEX-RVFI-INTR-01

A build failure prints VERDICT: BUILD_FAILED and exits 2; a check failure prints VERDICT: CHECK_FAILED and exits 1.

My Environment

| EDA tool and version | Verilator 5.051 (rev vUNKNOWN, built 2026-08-06) |
| Operating system | Ubuntu 24.04.5 LTS, Linux 6.18.33.2-microsoft-standard-WSL2 x86_64 |
| Version of the Ibex source code | f451552, rtl/ibex_core.sv sha256 843a0d57aff3b43473d3fd2d2148d48b44f16b7b006da4e778def107a6dab0a5 |

IBEX-RVFI-INTR-01.tar.gz

Activity

  1. added a commit that references this issue on Nov 6, 2026
    7d9a143
  2. h-filali commented on Nov 6, 2026

    @h-filali
    Contributor

    Thanks @qinkejiu I created #2572 to address this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions