Skip to content
21 changes: 16 additions & 5 deletions rtl/cve2_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module cve2_controller #(
input logic illegal_insn_i, // decoder has an invalid instr
input logic ecall_insn_i, // decoder has ECALL instr
input logic mret_insn_i, // decoder has MRET instr
input logic mnret_insn_i, // decoder has MNRET instr
input logic dret_insn_i, // decoder has DRET instr
input logic wfi_insn_i, // decoder has WFI instr
input logic ebrk_insn_i, // decoder has EBREAK instr
Expand Down Expand Up @@ -81,6 +82,7 @@ module cve2_controller #(
output logic csr_save_if_o,
output logic csr_save_id_o,
output logic csr_restore_mret_id_o,
output logic csr_restore_mnret_id_o,
output logic csr_restore_dret_id_o,
output logic csr_save_cause_o,
output logic [31:0] csr_mtval_o,
Expand Down Expand Up @@ -146,6 +148,7 @@ module cve2_controller #(

logic ecall_insn;
logic mret_insn;
logic mnret_insn;
logic dret_insn;
logic wfi_insn;
logic ebrk_insn;
Expand Down Expand Up @@ -176,6 +179,7 @@ module cve2_controller #(
// Decoder doesn't take instr_valid into account, factor it in here.
assign ecall_insn = ecall_insn_i & instr_valid_i;
assign mret_insn = mret_insn_i & instr_valid_i;
assign mnret_insn = mnret_insn_i & instr_valid_i;
assign dret_insn = dret_insn_i & instr_valid_i;
assign wfi_insn = wfi_insn_i & instr_valid_i;
assign ebrk_insn = ebrk_insn_i & instr_valid_i;
Expand All @@ -189,7 +193,7 @@ module cve2_controller #(
// Some instructions can only be executed in M-Mode
assign illegal_umode = (priv_mode_i != PRIV_LVL_M) &
// MRET must be in M-Mode. TW means trap WFI to M-Mode.
(mret_insn | (csr_mstatus_tw_i & wfi_insn));
(mret_insn | mnret_insn | (csr_mstatus_tw_i & wfi_insn));

// This is recorded in the illegal_insn_q flop to help timing. Specifically
// it is needed to break the path from cve2_cs_registers/illegal_csr_insn_o
Expand Down Expand Up @@ -218,7 +222,7 @@ module cve2_controller #(
assign special_req_flush_only = wfi_insn | csr_pipe_flush;

// These special requests cause a change in PC
assign special_req_pc_change = mret_insn | dret_insn | exc_req_d | exc_req_lsu;
assign special_req_pc_change = mret_insn | mnret_insn | dret_insn | exc_req_d | exc_req_lsu;

// generic special request signal, applies to all instructions
assign special_req = special_req_pc_change | special_req_flush_only;
Expand Down Expand Up @@ -323,6 +327,7 @@ module cve2_controller #(
csr_save_if_o = 1'b0;
csr_save_id_o = 1'b0;
csr_restore_mret_id_o = 1'b0;
csr_restore_mnret_id_o = 1'b0;
csr_restore_dret_id_o = 1'b0;
csr_save_cause_o = 1'b0;
csr_mtval_o = '0;
Expand Down Expand Up @@ -657,10 +662,16 @@ module cve2_controller #(
endcase
end else begin
// special instructions and pipeline flushes
if (mret_insn) begin
pc_mux_o = PC_ERET;
if (mret_insn | mnret_insn) begin
pc_set_o = 1'b1;
csr_restore_mret_id_o = 1'b1;
if(mret_insn) begin
csr_restore_mret_id_o = 1'b1;
pc_mux_o = PC_ERET;
end
if(mnret_insn) begin
csr_restore_mnret_id_o = 1'b1;
pc_mux_o = PC_NRET;
end
if (nmi_mode_q) begin
nmi_mode_d = 1'b0; // exit NMI mode
end
Expand Down
7 changes: 6 additions & 1 deletion rtl/cve2_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ module cve2_core import cve2_pkg::*; #(
logic nmi_mode;
irqs_t irqs;
logic csr_mstatus_mie;
logic [31:0] csr_mepc, csr_depc;
logic [31:0] csr_mepc, csr_mnepc, csr_depc;

// PMP signals
logic [33:0] csr_pmp_addr [PMPNumRegions];
Expand All @@ -235,6 +235,7 @@ module cve2_core import cve2_pkg::*; #(
logic csr_save_if;
logic csr_save_id;
logic csr_restore_mret_id;
logic csr_restore_mnret_id;
logic csr_restore_dret_id;
logic csr_save_cause;
logic csr_mtvec_init;
Expand Down Expand Up @@ -329,6 +330,7 @@ module cve2_core import cve2_pkg::*; #(

// CSRs
.csr_mepc_i (csr_mepc), // exception return address
.csr_mnepc_i (csr_mnepc), // NMI return address
.csr_depc_i (csr_depc), // debug return address
.csr_mtvec_i (csr_mtvec), // trap-vector base address
.csr_mtvec_init_o(csr_mtvec_init),
Expand Down Expand Up @@ -417,6 +419,7 @@ module cve2_core import cve2_pkg::*; #(
.csr_save_if_o (csr_save_if), // control signal to save PC
.csr_save_id_o (csr_save_id), // control signal to save PC
.csr_restore_mret_id_o(csr_restore_mret_id), // restore mstatus upon MRET
.csr_restore_mnret_id_o(csr_restore_mnret_id), // restore mstatus upon MNRET
.csr_restore_dret_id_o(csr_restore_dret_id), // restore mstatus upon MRET
.csr_save_cause_o (csr_save_cause),
.csr_mtval_o (csr_mtval),
Expand Down Expand Up @@ -712,6 +715,7 @@ module cve2_core import cve2_pkg::*; #(
.csr_mstatus_mie_o(csr_mstatus_mie),
.csr_mstatus_tw_o (csr_mstatus_tw),
.csr_mepc_o (csr_mepc),
.csr_mnepc_o (csr_mnepc),

// PMP
.csr_pmp_cfg_o (csr_pmp_cfg),
Expand All @@ -734,6 +738,7 @@ module cve2_core import cve2_pkg::*; #(
.csr_save_if_i (csr_save_if),
.csr_save_id_i (csr_save_id),
.csr_restore_mret_i(csr_restore_mret_id),
.csr_restore_mnret_i(csr_restore_mnret_id),
.csr_restore_dret_i(csr_restore_dret_id),
.csr_save_cause_i (csr_save_cause),
.csr_mcause_i (exc_cause),
Expand Down
Loading