aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/rtl/core/hazard_unit.sv
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-07 02:59:33 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-07 02:59:33 +0800
commitbc3ec25107314be3cd816c0b669d82338e892806 (patch)
treeff3e69ce6be1218be8bd0dd04e0c75760776d7dc /rv64cpu/rtl/core/hazard_unit.sv
parentc67ba709482821f37d63601b001ac07e6db867b6 (diff)
downloadrcc-project-bc3ec25107314be3cd816c0b669d82338e892806.tar.gz
rcc-project-bc3ec25107314be3cd816c0b669d82338e892806.tar.xz
checkpoint: preserve current RV64 CPU development state
Diffstat (limited to 'rv64cpu/rtl/core/hazard_unit.sv')
-rw-r--r--rv64cpu/rtl/core/hazard_unit.sv18
1 files changed, 14 insertions, 4 deletions
diff --git a/rv64cpu/rtl/core/hazard_unit.sv b/rv64cpu/rtl/core/hazard_unit.sv
index aef550c..ee90356 100644
--- a/rv64cpu/rtl/core/hazard_unit.sv
+++ b/rv64cpu/rtl/core/hazard_unit.sv
@@ -36,6 +36,7 @@ module hazard_unit
input logic [4:0] ex_rd_addr,
input logic ex_reg_write_en,
input logic ex_is_load,
+ input logic ex_is_csr,
input logic ex_branch_taken,
input logic [XLEN-1:0] ex_branch_target,
@@ -44,6 +45,8 @@ module hazard_unit
// -----------------------
input logic [4:0] mem_rd_addr,
input logic mem_reg_write_en,
+ input logic mem_result_late,
+ input logic mem_is_csr,
input logic mem_stall_req, // D-Cache miss or memory busy
// -----------------------
@@ -96,7 +99,7 @@ module hazard_unit
// Operand A (ex_rs1_addr)
always_comb begin
- if (mem_reg_write_en && (mem_rd_addr != 5'b0) && (mem_rd_addr == ex_rs1_addr)) begin
+ if (mem_reg_write_en && !mem_result_late && (mem_rd_addr != 5'b0) && (mem_rd_addr == ex_rs1_addr)) begin
forward_a_sel = 2'b01; // Forward from MEM stage
end else if (wb_reg_write_en && (wb_rd_addr != 5'b0) && (wb_rd_addr == ex_rs1_addr)) begin
forward_a_sel = 2'b10; // Forward from WB stage
@@ -107,7 +110,7 @@ module hazard_unit
// Operand B (ex_rs2_addr)
always_comb begin
- if (mem_reg_write_en && (mem_rd_addr != 5'b0) && (mem_rd_addr == ex_rs2_addr)) begin
+ if (mem_reg_write_en && !mem_result_late && (mem_rd_addr != 5'b0) && (mem_rd_addr == ex_rs2_addr)) begin
forward_b_sel = 2'b01; // Forward from MEM stage
end else if (wb_reg_write_en && (wb_rd_addr != 5'b0) && (wb_rd_addr == ex_rs2_addr)) begin
forward_b_sel = 2'b10; // Forward from WB stage
@@ -126,6 +129,12 @@ module hazard_unit
assign load_use_stall = ex_is_load && (ex_rd_addr != 5'b0) &&
((ex_rd_addr == id_rs1_addr) || (ex_rd_addr == id_rs2_addr));
+ logic csr_use_stall;
+ assign csr_use_stall = ((ex_is_csr && ex_reg_write_en && (ex_rd_addr != 5'b0) &&
+ ((ex_rd_addr == id_rs1_addr) || (ex_rd_addr == id_rs2_addr))) ||
+ (mem_is_csr && mem_reg_write_en && (mem_rd_addr != 5'b0) &&
+ ((mem_rd_addr == id_rs1_addr) || (mem_rd_addr == id_rs2_addr))));
+
// -----------------------
// PC Redirect Selection (Trap has top priority)
// -----------------------
@@ -168,8 +177,9 @@ module hazard_unit
ex_mem_stall_en = 1'b1;
end
- // (2) Load-Use stall: freeze IF and IF/ID, insert bubble into ID/EX
- if (load_use_stall && !mem_stall_req) begin
+ // (2) Value-use stall: freeze IF and IF/ID, insert bubble into ID/EX.
+ // Loads and CSR reads both produce their register result after EX.
+ if ((load_use_stall || csr_use_stall) && !mem_stall_req) begin
if_stall_en = 1'b1;
if_id_stall_en = 1'b1;
id_ex_flush_en = 1'b1;