lowRISC / lowRISC/ibex

Trap Return with activated Branch Prediction results in an unintended instruction retire

Open
#2,165 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Type:Bug
Dominant language
SystemVerilog
Stars
2.1k
Forks
810
Avg merge
5d 23h
Merged PRs (30d)
9

Description

## Observed Behavior

Just by simply executing the simple system with hello world I found this issue. Enable the WritebackStage as well as the BranchPredictor. Then execute the program with any simulator.
In the instruction logfile, something odd appears:
```
5368 2680 00100338 6161 c.addi16sp x2,80 x2:0x00137f90 x2=0x00137fe0
5370 2681 0010033a 30200073 mret
5378 2685 0010033e ea1ff06f jal x0,100462 x0=0x00000000
5380 2686 00100462 84ca c.mv x9,x18 x0:0x00000000 x18:0x00000000 x9=0x00000000
```

It seems that after `mret` the next consecutive instruction is loaded into the pipeline before the execution is continued at the `epc` value. This can also be seen in the waveform:
![image](https://github.com/lowRISC/ibex/assets/42815353/c7edab06-05e4-45db-95c3-b8818f8744e6)
The issue seems to be that the signal `instr_skid_en` is set since there is no special case implemented to detect that this is a trap return.

Is this a bug or is this behavior intended?

## Expected Behavior

The intended behavior would result in the following instruction trace:
```
5368 2680 00100338 6161 c.addi16sp x2,80 x2:0x00137f90 x2=0x00137fe0
5370 2681 0010033a 30200073 mret
5380 2686 00100462 84ca c.mv x9,x18 x0:0x00000000 x18:0x00000000 x9=0x00000000
```

## Steps to reproduce the issue

First I modified the config file and added a new config:
```
irq_test:
RV32E : 0
RV32M : "ibex_pkg::RV32MFast"
RV32B : "ibex_pkg::RV32BNone"
RegFile : "ibex_pkg::RegFileFF"
BranchTargetALU : 0
WritebackStage : 1
ICache : 0
ICacheECC : 0
ICacheScramble : 0
BranchPredictor : 1
DbgTriggerEn : 0
SecureIbex : 0
PMPEnable : 0
PMPGranularity : 0
PMPNumRegions : 4
MHPMCounterNum : 0
MHPMCounterWidth : 40
```

I executed the following sequence:
```
make -C examples/sw/simple_system/hello_test
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system $(util/ibex_config.py irq_test fusesoc_opts)
./build/lowrisc_ibex_ibex_simple_system_0/sim-verilator/Vibex_simple_system -t --meminit=ram,examples/sw/simple_system/hello_test/hello_test.vmem
```

Then I observed the logfile `trace_core_00000000.log`

## My Environment

**EDA tool and version:**

Verilator 5.020 2024-01-01 rev v5.020

**Operating system:**

Ubuntu Linux 22.04

**Version of the Ibex source code:**

eea2bf0c1c62bbd676edf69cc60a56041d53b669

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the irq_test configuration and the hello_test program using the listed FuseSoC and Verilator commands. Start by tracing instr_skid_en around mret and the branch-prediction pipeline, then compare trace_core_00000000.log and the waveform with the expected trace. Done means mret does not cause the unintended consecutive instruction to retire.

Written by the indexing model from the issue text.

Assessment

Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.