-
Notifications
You must be signed in to change notification settings - Fork 67
Fix/false load-use stall by gating rs1 amd rs2 hazard check #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pull request adds uses_rs1_id and uses_rs2_id signals and wires them to Control, but Control.scala still has ? placeholders. The hazard detection logic is not modified to use these signals.
Looking at the author's full implementation in their fork, the intended fix is:
val hazard_ex_rs1 = io.uses_rs1_id && (io.rd_ex === io.rs1_id)
val hazard_ex_rs2 = io.uses_rs2_id && (io.rd_ex === io.rs2_id)
when(
((io.memory_read_enable_ex || io.jump_instruction_id) &&
(io.rd_ex =/= 0.U) &&
(hazard_ex_rs1 || hazard_ex_rs2))
||
(io.jump_instruction_id &&
io.memory_read_enable_mem &&
(io.rd_mem =/= 0.U) &&
((io.uses_rs1_id && (io.rd_mem === io.rs1_id)) ||
(io.uses_rs2_id && (io.rd_mem === io.rs2_id))))
) { ... }The PR needs to include this Control.scala change or the fix is non-functional.
3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala
Outdated
Show resolved
Hide resolved
|
Exercise 19 Intent: This is part of CA25 Exercise 19. The PR adds the usage signals which is good guidance, but should:
Since this PR is meant to be a complete fix, the Control.scala hazard logic needs updating. |
|
Consider to contribute test case demonstrating false stall is eliminated: lw x16, 16(x0) # imm[4:0] = 16 = x16
add x1, x2, x3 # rs2 = x3, should NOT stall despite x16 match |
|
So, in the requested change, I should put my full implementation of |
b7ace8c to
0b2c4ff
Compare
Yes, that is the purpose of review. |
d148958 to
bbd344d
Compare
a6d445e to
81839a6
Compare
3-pipeline/src/main/scala/riscv/core/fivestage_final/Control.scala
Outdated
Show resolved
Hide resolved
Normalize camelCase naming, add missing uses_rs1 edge cases, and fix ID-stage rs1/rs2 read-address assignment to match expected read logic.
Introduce a regression test to ensure the pipeline does not insert a stall when a load-use dependency is incorrectly detected in the EX stage.
Update forwarding/hazard detection in the five-stage pipeline Control module to correctly detect EX/MEM dependencies and handle stalls for load-use and jump instructions. This commit refactors condition expressions to: - Include memory-read enable and jump flags when checking for hazards. - Consolidate rs1/rs2 use checks against rd in EX and MEM stages. - Ensure that load-use hazards in MEM correctly contribute to stall conditions. - Simplify and make hazard conditions more readable and consistent.
81839a6 to
e49f798
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run 'git rebase -i' to squash commits and enforce the rules described in https://cbea.ms/git-commit/ .
Read the above carefully.


Fix false load-use hazards by gating rs1/rs2 usage in ID stage
Background
While analyzing control hazard waveforms, I discovered that the current load-use hazard detection logic can spuriously trigger stalls for certain instruction patterns.
Specifically, the control logic in
Control.scalacomparesrd_exagainst bothrs1_idandrs2_idunconditionally. However, for several instruction types, the bit positions corresponding tors1orrs2do not represent architectural source registers.Root Cause
For I-type load instructions (e.g.,
lw a0, 16(a5)), onlyrs1is architecturally used.rs2_idis still wired directly from instruction bits[24:20], which encodeimm[4:0]for I-type instructions.When the immediate value coincidentally equals a register index (e.g.,
imm = 16→x16), the conditionmay incorrectly evaluate to true.
This causes
io_pc_stall,io_if_stall, andio_id_flushto assert, inserting an unnecessary bubble even though no real data dependency exists.This behavior is technically consistent with the existing implementation but reflects a decode-level limitation: the hazard unit does not know whether the ID-stage instruction actually uses
rs1orrs2.Fixes in this PR
Explicit rs1 / rs2 usage signals
rs1and/orrs2jal,auipc, andluido not users1(the same bit positions encode immediates)rs2is only considered for instruction classes that architecturally use a second source register, including:add,sub,and,or)sw)beq,bne)Result
You can check the whole implementation logic in the Control.scala on my Github repo