chipsalliance / chipsalliance/rocket-chip
[BUG] `divw` instruction writeback is incorrectly attributed to a trapping instruction's PC in the Commit Log
- Dominant language
- Scala
- Stars
- 3.9k
- Forks
- 1.3k
- Avg merge
- 5d 13m
- Merged PRs (30d)
- 1
Description
**Description**
I have observed an issue in the Rocket Chip Commit Log (Tracer) where the register writeback of a long-latency instruction (e.g., divw) is incorrectly attributed to a subsequent instruction that triggers an exception (e.g., flw causing a load address misaligned trap).
While the hardware logic appears to execute correctly (the register is updated with the correct value), the generated commit log combines the writeback event and the exception event into a single log entry under the exception's PC. This behavior breaks compatibility with standard ISA simulators (like Spike) during differential testing.
**Steps to Reproduce**
The issue occurs when a long-latency instruction is followed by an instruction that causes a trap, and the writeback of the former coincides with the exception handling of the latter.
**Assembly Snippet:**
```assembly
divw x19, x14, x15 // PC: 0x2e4. Long latency operation. Expected result: -1 (0xff...ff)
flw f19, 16(x6) // PC: 0x2f2. Triggers Load Address Misaligned Exception (cause=4)
```
**Observed Behavior (Rocket Chip Log)**
In the log below, the writeback to x19 (which comes from the divw at 0x2e4) is logged under the PC 0x2f2 (the flw instruction).
```assembly
3 0x000800002f2 (0x01032987) EXCEPTION cause=0x0000000000000004 tval=...
3 0x000800002f2 (0x01032987) x19 0xffffffffffffffff
```
**Expected Behavior (Golden Model / Spike)**
The log should reflect the atomic execution of instructions. The writeback of divw should be associated with its own PC (0x2e4), even if it completes out-of-order or during a trap handling cycle. The exception log entry at 0x2f2 should not imply a modification to x19 caused by the flw instruction.
**Analysis**
It appears that the Tracer logic prioritizes the "current committing PC" (which is the exception PC in this cycle) and greedily attributes any register file write-enable signals active in that cycle to this PC.
1. Normal Case: When divw completes asynchronously without a concurrent trap, the tracer correctly "replays" the log with the original PC (e.g., 0x2e4).
2. Trap Case: When a trap occurs, the tracer logs the trap PC (0x2f2). However, if the divw result just happens to be writing back to the Register File in the exact same cycle, the tracer incorrectly attaches this rd update to the trap log entry.
This makes it impossible to automatically diff the Rocket log against a Golden Model log without manual intervention.
Environment
Rocket Chip Version: (Please fill in your version/commit hash here if known, otherwise leave blank or specify "Recent checkout")
Simulation: (e.g., Verilator / VCS)
**Additional Files**
I have attached the program.s, progrom.dump, and stderr.log in [program.zip](https://github.com/user-attachments/files/23831747/program.zip) from Rocket for reproducing the issue.
Contributor guide
Research direction
Start by reproducing the issue with the attached program.zip and the divw/flw sequence, then inspect the Rocket Chip Tracer commit-log path that handles asynchronous register writeback and trap cycles. Compare the generated entries with the expected Spike-style sequence. Done means the divw writeback is logged with PC 0x2e4 and the flw exception at 0x2f2 does not claim the x19 update.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- embedded-iot, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100