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

Đang mở Phù hợp với người mới
#2,556 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 2 ngày

@h-filali đang làm issue này rồi.

Từ ngày 6/11/2026.

  • #2572 của @h-filali — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
68/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Lĩnh vực
embedded-iot, testing-qa

Hướng nghiên cứu

Cờ đánh dấu được đặt trong rtl/ibex_core.sv quanh các dòng 2409-2421, và điều kiện ở dòng 2417 chỉ chấp nhận EXC_PC_IRQ, nên các mục vào ngoại lệ đồng bộ bị bỏ qua. Hãy bắt đầu bằng việc đọc khối đó cùng các phép gán rvfi_intr_d và rvfi_set_trap_pc_q, sau đó chạy run.sh với chương trình ecall để xem các dòng mà nó so sánh. Hoàn thành khi dòng vào ngoại lệ được retire với rvfi_intr=1, các mục debug vẫn bị loại trừ, và script báo cáo kết luận mong đợi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Type:Bug

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

Ngôn ngữ chính
SystemVerilog
Star
2.2k
Fork
836
Merge trung bình
5 ngày 8 giờ
Pull request đã merge (30 ngày)
22

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của lowRISC/ibex

Tất cả issue của lowRISC/ibex

Issue tương tự

Thêm issue về Embedded & IoT

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.