From 0b2c4ffa0ceb31fdcabffcd8c4c07fe8dae1a840 Mon Sep 17 00:00:00 2001 From: jgw0915 Date: Fri, 19 Dec 2025 00:52:50 +0800 Subject: [PATCH] Fix/false load-use stall by gating rs1 amd rs2 harzard check --- .../main/scala/riscv/core/fivestage_final/CPU.scala | 2 ++ .../scala/riscv/core/fivestage_final/Control.scala | 5 +++++ .../core/fivestage_final/InstructionDecode.scala | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/3-pipeline/src/main/scala/riscv/core/fivestage_final/CPU.scala b/3-pipeline/src/main/scala/riscv/core/fivestage_final/CPU.scala index e878f410..3de0a641 100644 --- a/3-pipeline/src/main/scala/riscv/core/fivestage_final/CPU.scala +++ b/3-pipeline/src/main/scala/riscv/core/fivestage_final/CPU.scala @@ -137,6 +137,8 @@ class CPU extends Module { ctrl.io.rd_ex := id2ex.io.output_regs_write_address ctrl.io.memory_read_enable_mem := ex2mem.io.output_memory_read_enable ctrl.io.rd_mem := ex2mem.io.output_regs_write_address + ctrl.io.uses_rs2_id := id.io.uses_rs2_id + ctrl.io.uses_rs1_id := id.io.uses_rs1_id regs.io.write_enable := mem2wb.io.output_regs_write_enable regs.io.write_address := mem2wb.io.output_regs_write_address diff --git a/3-pipeline/src/main/scala/riscv/core/fivestage_final/Control.scala b/3-pipeline/src/main/scala/riscv/core/fivestage_final/Control.scala index 91903c67..43b2a192 100644 --- a/3-pipeline/src/main/scala/riscv/core/fivestage_final/Control.scala +++ b/3-pipeline/src/main/scala/riscv/core/fivestage_final/Control.scala @@ -61,6 +61,8 @@ class Control extends Module { val rd_ex = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // id2ex.io.output_regs_write_address val memory_read_enable_mem = Input(Bool()) // ex2mem.io.output_memory_read_enable // val rd_mem = Input(UInt(Parameters.PhysicalRegisterAddrWidth)) // ex2mem.io.output_regs_write_address // + val uses_rs1_id = Input(Bool()) // true only if current ID instruction really reads rs1 + val uses_rs2_id = Input(Bool()) // true only if current ID instruction really reads rs2 val if_flush = Output(Bool()) val id_flush = Output(Bool()) @@ -84,6 +86,9 @@ class Control extends Module { // 1. Load-use hazard: Load result used immediately by next instruction // 2. Jump-related hazard: Jump instruction needs register value not ready // 3. Control hazard: Branch/jump instruction changes PC + // Use the decoded `uses_rs1_id` / `uses_rs2_id` flags to test whether the + // current ID-stage instruction actually reads rs1/rs2; only then should a + // register-number match be considered a true RAW dependency. // // Control signals: // - pc_stall: Freeze PC (don't fetch next instruction) diff --git a/3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala b/3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala index 3809c0f7..16102fa4 100644 --- a/3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala +++ b/3-pipeline/src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala @@ -152,6 +152,8 @@ class InstructionDecode extends Module { val clint_jump_address = Output(UInt(Parameters.AddrWidth)) // clint.io.jump_address val if_jump_flag = Output(Bool()) // ctrl.io.jump_flag , inst_fetch.io.jump_flag_id val if_jump_address = Output(UInt(Parameters.AddrWidth)) // inst_fetch.io.jump_address_id + val uses_rs1_id = Output(Bool()) // tells Control/Forwarding whether rs1 is valid for this instruction + val uses_rs2_id = Output(Bool()) // tells Control/Forwarding whether rs2 is valid for this instruction }) val opcode = io.instruction(6, 0) val funct3 = io.instruction(14, 12) @@ -159,6 +161,16 @@ class InstructionDecode extends Module { val rd = io.instruction(11, 7) val rs1 = io.instruction(19, 15) val rs2 = io.instruction(24, 20) + val usesRs2 = (opcode === InstructionTypes.RM) || + (opcode === InstructionTypes.S) || + (opcode === InstructionTypes.B) + + val usesRs1 = !(opcode === Instructions.jal) && + !(opcode === Instructions.lui) && + !(opcode === Instructions.auipc) + + io.uses_rs2_id := usesRs2 + io.uses_rs1_id := usesRs1 io.regs_reg1_read_address := Mux(opcode === Instructions.lui, 0.U(Parameters.PhysicalRegisterAddrWidth), rs1) io.regs_reg2_read_address := rs2