aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/rtl/core/hazard_unit.sv
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-04-01 00:58:22 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-04-01 00:58:22 +0800
commitcf0476e565c74082f011a6c428095e60a743b822 (patch)
treea5b5feaa2228d4eb1e90213d07e709bd4f12bf97 /rv64cpu/rtl/core/hazard_unit.sv
parentab6a21ae1099bff120111b8a9dcfa50c9fcad5a1 (diff)
downloadrcc-project-cf0476e565c74082f011a6c428095e60a743b822.tar.gz
rcc-project-cf0476e565c74082f011a6c428095e60a743b822.tar.xz
feat: Complete CSR/privileged/exception interrupt path and fill in strict acceptance tests
- Refactor trap/CSR data path in the Core, unified with trap_ctrl interface to drive CSR update and return process - Improve critical paths for exception/interrupt handling: ecall, illegal, load fault, external interrupt, mret/sret return - Adjust pipeline stage registers with flush/stall coordination, fix residual control signal issues in trap scenarios - Enhance decode and related pipeline module behavior consistency, fill in missing control signal propagation across registers - Expand core integration testing, add trap/interrupt scenarios and CLI dispatch that can be executed per case - Extend CSR unit test coverage: read/write semantics, privilege switching, delegation and nested returns, illegal access protection, etc. - Register new core scenario cases in CTest to form a regression-capable P2 strict acceptance suite Verification: - Build passed - Full CTest passed (22/22)
Diffstat (limited to 'rv64cpu/rtl/core/hazard_unit.sv')
-rw-r--r--rv64cpu/rtl/core/hazard_unit.sv92
1 files changed, 65 insertions, 27 deletions
diff --git a/rv64cpu/rtl/core/hazard_unit.sv b/rv64cpu/rtl/core/hazard_unit.sv
index 2798116..aef550c 100644
--- a/rv64cpu/rtl/core/hazard_unit.sv
+++ b/rv64cpu/rtl/core/hazard_unit.sv
@@ -37,6 +37,7 @@ module hazard_unit
input logic ex_reg_write_en,
input logic ex_is_load,
input logic ex_branch_taken,
+ input logic [XLEN-1:0] ex_branch_target,
// -----------------------
// Inputs from MEM Stage (EX/MEM register outputs)
@@ -46,6 +47,13 @@ module hazard_unit
input logic mem_stall_req, // D-Cache miss or memory busy
// -----------------------
+ // Trap Controller Inputs
+ // -----------------------
+ input logic trap_flush_req,
+ input logic trap_pc_sel,
+ input logic [XLEN-1:0] trap_target_pc,
+
+ // -----------------------
// Inputs from WB Stage (MEM/WB register outputs)
// -----------------------
input logic [4:0] wb_rd_addr,
@@ -66,7 +74,14 @@ module hazard_unit
output logic id_ex_stall_en,
output logic ex_mem_stall_en,
output logic if_id_flush_en,
- output logic id_ex_flush_en
+ output logic id_ex_flush_en,
+
+ // -----------------------
+ // Outputs: IF-stage PC redirect controls
+ // -----------------------
+ output logic pc_redirect_sel,
+ output logic [XLEN-1:0] pc_redirect_target,
+ output logic pc_redirect_is_trap
);
// -----------------------
@@ -112,40 +127,63 @@ module hazard_unit
((ex_rd_addr == id_rs1_addr) || (ex_rd_addr == id_rs2_addr));
// -----------------------
+ // PC Redirect Selection (Trap has top priority)
+ // -----------------------
+ always_comb begin
+ pc_redirect_sel = 1'b0;
+ pc_redirect_target = '0;
+ pc_redirect_is_trap = 1'b0;
+
+ if (trap_pc_sel) begin
+ pc_redirect_sel = 1'b1;
+ pc_redirect_target = trap_target_pc;
+ pc_redirect_is_trap = 1'b1;
+ end else if (ex_branch_taken) begin
+ pc_redirect_sel = 1'b1;
+ pc_redirect_target = ex_branch_target;
+ end
+ end
+
+ // -----------------------
// Stall and Flush Signal Generation
// -----------------------
always_comb begin
// Defaults: no stalls, no flushes
- if_stall_en = 1'b0;
- if_id_stall_en = 1'b0;
- id_ex_stall_en = 1'b0;
+ if_stall_en = 1'b0;
+ if_id_stall_en = 1'b0;
+ id_ex_stall_en = 1'b0;
ex_mem_stall_en = 1'b0;
- if_id_flush_en = 1'b0;
- id_ex_flush_en = 1'b0;
-
- // (1) Memory stall (D-Cache miss): freeze the entire pipeline
- if (mem_stall_req) begin
- if_stall_en = 1'b1;
- if_id_stall_en = 1'b1;
- id_ex_stall_en = 1'b1;
- ex_mem_stall_en = 1'b1;
- end
+ if_id_flush_en = 1'b0;
+ id_ex_flush_en = 1'b0;
- // (2) Load-Use stall: freeze IF and IF/ID, insert bubble into ID/EX
- if (load_use_stall && !mem_stall_req) begin
- if_stall_en = 1'b1;
- if_id_stall_en = 1'b1;
- id_ex_flush_en = 1'b1;
- end
-
- // (3) Branch/jump misprediction: flush IF/ID and ID/EX
- // Branch flush overrides load-use stall (the stalled instruction is invalid anyway)
- if (ex_branch_taken) begin
+ if (trap_flush_req) begin
if_id_flush_en = 1'b1;
id_ex_flush_en = 1'b1;
- // Cancel load-use stall if branch is also taken
- if_stall_en = 1'b0;
- if_id_stall_en = 1'b0;
+ end else begin
+ // (1) Memory stall (D-Cache miss): freeze the entire pipeline
+ if (mem_stall_req) begin
+ if_stall_en = 1'b1;
+ if_id_stall_en = 1'b1;
+ id_ex_stall_en = 1'b1;
+ 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
+ if_stall_en = 1'b1;
+ if_id_stall_en = 1'b1;
+ id_ex_flush_en = 1'b1;
+ end
+
+ // (3) Branch/jump misprediction: flush IF/ID and ID/EX
+ // Branch flush overrides load-use stall (the stalled instruction is invalid anyway)
+ if (ex_branch_taken) begin
+ if_id_flush_en = 1'b1;
+ id_ex_flush_en = 1'b1;
+ // Cancel load-use stall if branch is also taken
+ if_stall_en = 1'b0;
+ if_id_stall_en = 1'b0;
+ end
end
end