aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/rtl/core/richard_core.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rv64cpu/rtl/core/richard_core.sv')
-rw-r--r--rv64cpu/rtl/core/richard_core.sv161
1 files changed, 141 insertions, 20 deletions
diff --git a/rv64cpu/rtl/core/richard_core.sv b/rv64cpu/rtl/core/richard_core.sv
index ae73e77..ad75cc8 100644
--- a/rv64cpu/rtl/core/richard_core.sv
+++ b/rv64cpu/rtl/core/richard_core.sv
@@ -34,8 +34,15 @@ module richard_core
output logic [63:0] dmem_addr,
output logic [63:0] dmem_wdata,
output logic [2:0] dmem_size,
- input logic [63:0] dmem_rdata
+ input logic [63:0] dmem_rdata,
+
+ // Interface 3: External Interrupt Sources
+ input logic ext_timer_int,
+ input logic ext_software_int,
+ input logic ext_external_int
);
+ localparam int CSR_MSTATUS_MIE_BIT = 3;
+
// -----------------------
// Internal Wire Declarations
// -----------------------
@@ -44,6 +51,8 @@ module richard_core
logic [1:0] hu_forward_a_sel, hu_forward_b_sel;
logic hu_if_stall_en, hu_if_id_stall_en, hu_id_ex_stall_en, hu_ex_mem_stall_en;
logic hu_if_id_flush_en, hu_id_ex_flush_en;
+ logic hu_pc_redirect_sel, hu_pc_redirect_is_trap;
+ logic [XLEN-1:0] hu_pc_redirect_target;
// (2) IF Stage Outputs
logic [XLEN-1:0] if_pc_out;
@@ -74,6 +83,7 @@ module richard_core
// (5) ID/EX Pipeline Register Outputs
logic [XLEN-1:0] ex_pc_in;
+ logic [INST_WIDTH-1:0] ex_instr_in;
logic [XLEN-1:0] ex_rs1_rdata_in, ex_rs2_rdata_in;
logic [4:0] ex_rs1_addr_in, ex_rs2_addr_in;
logic [XLEN-1:0] ex_imm_in;
@@ -99,6 +109,7 @@ module richard_core
// (7) EX/MEM Pipeline Register Outputs
logic [XLEN-1:0] mem_pc_in;
+ logic [INST_WIDTH-1:0] mem_instr_in;
logic [XLEN-1:0] mem_alu_result_in;
logic mem_branch_taken_in;
logic [XLEN-1:0] mem_branch_target_in;
@@ -119,6 +130,7 @@ module richard_core
logic [XLEN-1:0] mw_reg_alu_result_in;
logic [XLEN-1:0] mw_reg_mem_rdata_in;
logic [XLEN-1:0] mw_reg_pc_in;
+ logic [INST_WIDTH-1:0] mw_reg_instr_in;
logic [7:0] mw_reg_dmem_wstrb_in;
logic mw_reg_reg_write_en_in;
logic [4:0] mw_reg_rd_addr_in;
@@ -129,12 +141,15 @@ module richard_core
logic [4:0] mw_reg_rs1_addr_in;
logic [XLEN-1:0] mw_reg_imm_in;
logic mw_reg_illegal_instr_in, mw_reg_is_ecall_in, mw_reg_is_ebreak_in, mw_reg_is_mret_in, mw_reg_is_sret_in;
+ logic mw_reg_load_fault_in, mw_reg_store_fault_in;
+ logic [XLEN-1:0] mw_reg_fault_addr_in;
logic mem_stall_req;
// (9) MEM/WB Pipeline Register Outputs
logic [XLEN-1:0] wb_pc_in;
logic [XLEN-1:0] wb_alu_result_in;
logic [XLEN-1:0] wb_mem_rdata_in;
+ logic [INST_WIDTH-1:0] wb_instr_in;
logic wb_reg_write_en_in;
logic [4:0] wb_rd_addr_in;
logic [1:0] wb_wb_sel_in;
@@ -144,6 +159,8 @@ module richard_core
logic [4:0] wb_rs1_addr_in;
logic [XLEN-1:0] wb_imm_in;
logic wb_illegal_instr_in, wb_is_ecall_in, wb_is_ebreak_in, wb_is_mret_in, wb_is_sret_in;
+ logic wb_load_fault_flag, wb_store_fault_flag;
+ logic [XLEN-1:0] wb_fault_addr_in;
// (10) WB Stage Outputs (to RegFile & CSR Unit)
logic [XLEN-1:0] wb_rd_wdata;
@@ -172,6 +189,32 @@ module richard_core
logic trap_illegal_instr, trap_is_ecall, trap_is_ebreak, trap_is_mret, trap_is_sret;
logic [XLEN-1:0] trap_epc;
+ // (12) Trap Controller + interrupt wiring
+ logic trap_load_fault, trap_store_fault;
+ logic trap_instr_page_fault, trap_load_page_fault, trap_store_page_fault;
+ logic [XLEN-1:0] trap_bad_addr;
+ logic [INST_WIDTH-1:0] trap_bad_instr;
+ logic trap_flush_req;
+ logic trap_pc_sel;
+ logic [XLEN-1:0] trap_next_pc;
+ logic trap_pc_sel_raw;
+ logic [XLEN-1:0] trap_next_pc_raw;
+ logic trap_ctrl_trigger;
+ logic [XLEN-1:0] trap_ctrl_mepc;
+ logic [XLEN-1:0] trap_ctrl_mcause;
+ logic [XLEN-1:0] trap_ctrl_mtval;
+ logic trap_ctrl_to_s_mode_flag;
+ logic trap_ctrl_mret_en;
+ logic trap_ctrl_sret_en;
+ logic csr_mstatus_mie;
+
+ // Page-fault paths remain stubbed until the MMU surfaces violations.
+ assign trap_instr_page_fault = 1'b0;
+ assign trap_load_page_fault = 1'b0;
+ assign trap_store_page_fault = 1'b0;
+
+ assign csr_mstatus_mie = csr_mstatus_value[CSR_MSTATUS_MIE_BIT];
+
// ---------------------------------------------------------
// (A) Hazard Unit Implementation
// ---------------------------------------------------------
@@ -184,9 +227,13 @@ module richard_core
.ex_reg_write_en (ex_reg_write_en_in),
.ex_is_load (ex_is_load_in),
.ex_branch_taken (ex_branch_taken_out),
+ .ex_branch_target (ex_branch_target_out),
.mem_rd_addr (mem_rd_addr_in),
.mem_reg_write_en (mem_reg_write_en_in),
.mem_stall_req (mem_stall_req),
+ .trap_flush_req (trap_flush_req),
+ .trap_pc_sel (trap_pc_sel),
+ .trap_target_pc (trap_next_pc),
.wb_rd_addr (wb_rd_addr_in),
.wb_reg_write_en (wb_reg_write_en_out),
.forward_a_sel (hu_forward_a_sel),
@@ -196,7 +243,10 @@ module richard_core
.id_ex_stall_en (hu_id_ex_stall_en),
.ex_mem_stall_en (hu_ex_mem_stall_en),
.if_id_flush_en (hu_if_id_flush_en),
- .id_ex_flush_en (hu_id_ex_flush_en)
+ .id_ex_flush_en (hu_id_ex_flush_en),
+ .pc_redirect_sel (hu_pc_redirect_sel),
+ .pc_redirect_target (hu_pc_redirect_target),
+ .pc_redirect_is_trap(hu_pc_redirect_is_trap)
);
// ---------------------------------------------------------
@@ -206,8 +256,9 @@ module richard_core
.clk (clk),
.rst (rst),
.stall_en (hu_if_stall_en),
- .ex_branch_taken (ex_branch_taken_out),
- .ex_branch_target (ex_branch_target_out),
+ .pc_redirect_sel (hu_pc_redirect_sel),
+ .pc_redirect_target (hu_pc_redirect_target),
+ .pc_redirect_is_trap(hu_pc_redirect_is_trap),
.if_pc (if_pc_out)
);
@@ -232,6 +283,7 @@ module richard_core
.rst (rst),
.if_pc (if_id_pc),
.if_instr (if_id_instr),
+ .csr_priv_mode (csr_priv_mode_cur),
.wb_reg_write_en (wb_reg_write_en_out),
.wb_rd_addr (wb_rd_addr),
.wb_rd_wdata (wb_rd_wdata),
@@ -272,6 +324,7 @@ module richard_core
.rst (rst),
.stall_en (hu_id_ex_stall_en),
.flush_en (hu_id_ex_flush_en),
+ .id_instr (if_id_instr),
.id_pc (id_pc_out),
.id_rs1_rdata (id_rs1_rdata),
.id_rs2_rdata (id_rs2_rdata),
@@ -303,6 +356,7 @@ module richard_core
.id_is_fence (id_is_fence),
.id_is_fence_i (id_is_fence_i),
.ex_pc (ex_pc_in),
+ .ex_instr (ex_instr_in),
.ex_rs1_rdata (ex_rs1_rdata_in),
.ex_rs2_rdata (ex_rs2_rdata_in),
.ex_rs1_addr (ex_rs1_addr_in),
@@ -386,6 +440,7 @@ module richard_core
.ex_rs1_addr (ex_rs1_addr_in),
.ex_pc (ex_pc_in),
.ex_imm (ex_imm_in),
+ .ex_instr (ex_instr_in),
.ex_is_load (ex_is_load_in),
.ex_is_store (ex_is_store_in),
.ex_mem_size (ex_mem_size_in),
@@ -411,6 +466,7 @@ module richard_core
.mem_rs1_addr (mem_rs1_addr_in),
.mem_pc (mem_pc_in),
.mem_imm (mem_imm_in),
+ .mem_instr (mem_instr_in),
.mem_is_load (mem_is_load_in),
.mem_is_store (mem_is_store_in),
.mem_mem_size (mem_mem_size_in),
@@ -442,6 +498,7 @@ module richard_core
.mem_rs1_addr (mem_rs1_addr_in),
.mem_pc (mem_pc_in),
.mem_imm (mem_imm_in),
+ .mem_instr (mem_instr_in),
.mem_is_load (mem_is_load_in),
.mem_is_store (mem_is_store_in),
.mem_mem_size (mem_mem_size_in),
@@ -470,6 +527,7 @@ module richard_core
.mem_wb_alu_result (mw_reg_alu_result_in),
.mem_wb_mem_rdata (mw_reg_mem_rdata_in),
.mem_wb_pc (mw_reg_pc_in),
+ .mem_wb_instr (mw_reg_instr_in),
.mem_wb_reg_write_en (mw_reg_reg_write_en_in),
.mem_wb_rd_addr (mw_reg_rd_addr_in),
.mem_wb_wb_sel (mw_reg_wb_sel_in),
@@ -483,19 +541,23 @@ module richard_core
.mem_wb_is_ebreak (mw_reg_is_ebreak_in),
.mem_wb_is_mret (mw_reg_is_mret_in),
.mem_wb_is_sret (mw_reg_is_sret_in),
+ .mem_wb_load_fault (mw_reg_load_fault_in),
+ .mem_wb_store_fault (mw_reg_store_fault_in),
+ .mem_wb_fault_addr (mw_reg_fault_addr_in),
.mem_stall_req (mem_stall_req)
);
assign dmem_size = mem_mem_size_in;
mem_wb_reg u_mem_wb_reg (
- .clk (clk),
- .rst (rst),
- .stall_en (1'b0),
- .flush_en (1'b0),
+ .clk (clk),
+ .rst (rst),
+ .stall_en (1'b0),
+ .flush_en (trap_flush_req),
.mem_pc (mw_reg_pc_in),
.mem_alu_result (mw_reg_alu_result_in),
.mem_mem_rdata (mw_reg_mem_rdata_in),
+ .mem_instr (mw_reg_instr_in),
.mem_reg_write_en (mw_reg_reg_write_en_in),
.mem_rd_addr (mw_reg_rd_addr_in),
.mem_wb_sel (mw_reg_wb_sel_in),
@@ -509,9 +571,13 @@ module richard_core
.mem_is_ebreak (mw_reg_is_ebreak_in),
.mem_is_mret (mw_reg_is_mret_in),
.mem_is_sret (mw_reg_is_sret_in),
+ .mem_load_fault (mw_reg_load_fault_in),
+ .mem_store_fault (mw_reg_store_fault_in),
+ .mem_fault_addr (mw_reg_fault_addr_in),
.wb_pc (wb_pc_in),
.wb_alu_result (wb_alu_result_in),
.wb_mem_rdata (wb_mem_rdata_in),
+ .wb_instr (wb_instr_in),
.wb_reg_write_en (wb_reg_write_en_in),
.wb_rd_addr (wb_rd_addr_in),
.wb_wb_sel (wb_wb_sel_in),
@@ -524,7 +590,10 @@ module richard_core
.wb_is_ecall (wb_is_ecall_in),
.wb_is_ebreak (wb_is_ebreak_in),
.wb_is_mret (wb_is_mret_in),
- .wb_is_sret (wb_is_sret_in)
+ .wb_is_sret (wb_is_sret_in),
+ .wb_load_fault (wb_load_fault_flag),
+ .wb_store_fault (wb_store_fault_flag),
+ .wb_fault_addr (wb_fault_addr_in)
);
// ---------------------------------------------------------
@@ -543,12 +612,17 @@ module richard_core
.mem_wb_rs1_rdata (wb_rs1_rdata_in),
.mem_wb_rs1_addr (wb_rs1_addr_in),
.mem_wb_imm (wb_imm_in),
+ .mem_wb_instr (wb_instr_in),
.mem_wb_illegal_instr(wb_illegal_instr_in),
.mem_wb_is_ecall (wb_is_ecall_in),
.mem_wb_is_ebreak (wb_is_ebreak_in),
.mem_wb_is_mret (wb_is_mret_in),
.mem_wb_is_sret (wb_is_sret_in),
+ .mem_wb_load_fault (wb_load_fault_flag),
+ .mem_wb_store_fault (wb_store_fault_flag),
+ .mem_wb_fault_addr (wb_fault_addr_in),
.csr_rdata (csr_rdata),
+ .csr_illegal_access (csr_illegal_access_flag),
.wb_rd_wdata (wb_rd_wdata),
.wb_rd_addr (wb_rd_addr),
.wb_reg_write_en (wb_reg_write_en_out),
@@ -561,7 +635,11 @@ module richard_core
.trap_is_ebreak (trap_is_ebreak),
.trap_is_mret (trap_is_mret),
.trap_is_sret (trap_is_sret),
- .trap_epc (trap_epc)
+ .trap_epc (trap_epc),
+ .trap_load_fault (trap_load_fault),
+ .trap_store_fault (trap_store_fault),
+ .trap_bad_addr (trap_bad_addr),
+ .trap_bad_instr (trap_bad_instr)
);
csr_unit u_csr_unit (
@@ -571,12 +649,13 @@ module richard_core
.csr_op (csr_op),
.csr_addr (csr_addr),
.csr_rs1_data (csr_rs1_data),
- .trap_illegal_instr (trap_illegal_instr),
- .trap_is_ecall (trap_is_ecall),
- .trap_is_ebreak (trap_is_ebreak),
- .trap_is_mret (trap_is_mret),
- .trap_is_sret (trap_is_sret),
- .trap_epc (trap_epc),
+ .trap_ctrl_trigger (trap_ctrl_trigger),
+ .trap_ctrl_to_s_mode(trap_ctrl_to_s_mode_flag),
+ .trap_ctrl_mepc (trap_ctrl_mepc),
+ .trap_ctrl_mcause (trap_ctrl_mcause),
+ .trap_ctrl_mtval (trap_ctrl_mtval),
+ .trap_ctrl_mret_en (trap_ctrl_mret_en),
+ .trap_ctrl_sret_en (trap_ctrl_sret_en),
.csr_rdata (csr_rdata),
.csr_mstatus (csr_mstatus_value),
.csr_sstatus (csr_sstatus_value),
@@ -587,10 +666,52 @@ module richard_core
.csr_mepc (csr_mepc_value),
.csr_sepc (csr_sepc_value),
.csr_satp (csr_satp_value),
- .csr_priv_mode (csr_priv_mode_cur),
- .csr_trap_vector (csr_trap_vector_value),
- .csr_trap_to_s_mode (csr_trap_to_s_mode_flag),
- .csr_illegal_access (csr_illegal_access_flag)
+ .csr_priv_mode (csr_priv_mode_cur),
+ .csr_trap_vector (),
+ .csr_trap_to_s_mode (),
+ .csr_trap_vector_next (csr_trap_vector_value),
+ .csr_trap_to_s_mode_next(csr_trap_to_s_mode_flag),
+ .csr_illegal_access (csr_illegal_access_flag)
);
+ trap_ctrl u_trap_ctrl (
+ .wb_pc (wb_pc_in),
+ .trap_illegal_instr (trap_illegal_instr),
+ .trap_is_ecall (trap_is_ecall),
+ .trap_is_ebreak (trap_is_ebreak),
+ .trap_is_mret (trap_is_mret),
+ .trap_is_sret (trap_is_sret),
+ .trap_load_fault (trap_load_fault),
+ .trap_store_fault (trap_store_fault),
+ .trap_instr_page_fault(trap_instr_page_fault),
+ .trap_load_page_fault(trap_load_page_fault),
+ .trap_store_page_fault(trap_store_page_fault),
+ .trap_bad_addr (trap_bad_addr),
+ .trap_bad_instr (trap_bad_instr),
+ .ext_timer_int (ext_timer_int),
+ .ext_software_int (ext_software_int),
+ .ext_external_int (ext_external_int),
+ .csr_mstatus_mie (csr_mstatus_mie),
+ .csr_mtvec (csr_mtvec_base),
+ .csr_stvec (csr_stvec_base),
+ .csr_mepc (csr_mepc_value),
+ .csr_sepc (csr_sepc_value),
+ .csr_medeleg (csr_medeleg_value),
+ .csr_mideleg (csr_mideleg_value),
+ .csr_priv_mode (csr_priv_mode_cur),
+ .trap_trigger (trap_ctrl_trigger),
+ .trap_mepc (trap_ctrl_mepc),
+ .trap_mcause (trap_ctrl_mcause),
+ .trap_mtval (trap_ctrl_mtval),
+ .trap_to_s_mode (trap_ctrl_to_s_mode_flag),
+ .mret_en (trap_ctrl_mret_en),
+ .sret_en (trap_ctrl_sret_en),
+ .trap_flush_req (trap_flush_req),
+ .trap_pc_sel (trap_pc_sel_raw),
+ .trap_next_pc (trap_next_pc_raw)
+ );
+
+ assign trap_pc_sel = trap_pc_sel_raw;
+ assign trap_next_pc = trap_next_pc_raw;
+
endmodule