commit 9ac7b30411ff32d47929d3a33f070f2c46696589
parent bc62a1834a9e97d3efbab4ac384379738544b6d9
Author: Vineet Kumar <git@vineetk.net>
Date: Fri, 24 Jul 2026 13:47:51 +0530
remove zicsr extension for now due to issues
1. It was interfering with the pipelining of the hart like hazards.
2. CSRs take up lots of BRAM that I could've put towards more
I-cache/D-cache.
3. I wasn't planning on using an existing OS/EEI like Linux/FreeRTOS,
instead wanting to make my own.
4. Parts of it was initially LLM slop.
I'd rather revisit this once I got most of the other more important
major extensions completed as I see those to be much more useful.
Diffstat:
7 files changed, 11 insertions(+), 432 deletions(-)
diff --git a/Makefile b/Makefile
@@ -3,7 +3,7 @@ OBJDIR := obj_dir
PKG_SRC := ${SRCDIR}/rv32g_pkg.sv
TB_SRC := ${SRCDIR}/tb_rv32g.sv
-SV_SRCS := ${SRCDIR}/rv32g_hart.sv ${SRCDIR}/csr_regfile.sv ${wildcard ${SRCDIR}/stage_*.sv} ${SRCDIR}/unified_memory.sv
+SV_SRCS := ${SRCDIR}/rv32g_hart.sv ${wildcard ${SRCDIR}/stage_*.sv} ${SRCDIR}/unified_memory.sv
TOP_SRC := ${SRCDIR}/rv32g_hart_top.sv
CST_SRC := ${SRCDIR}/rv32g_hart_top.cst
diff --git a/rtl/csr_regfile.sv b/rtl/csr_regfile.sv
@@ -1,145 +0,0 @@
-module csr_regfile
- import rv32g_pkg::*;
- (input logic clk,
- input logic rstN,
- input logic [11:0] addr,
- output logic illegal,
- // read port
- input logic rden,
- output reg_t rdata,
- // write port
- input logic wren,
- input reg_t wdata,
- input logic [4:0] rs1_num,
- // xEPC shadows for xRET
- output reg_t mepc_shadow);
-
- reg_t regfile [0:CSR_SIZE-1];
- logic [$clog2(CSR_SIZE)-1:0] idx;
- logic illegal_rd, illegal_wr;
- logic [1:0] csr_rw_mask;
- logic [1:0] priv_level;
- logic [7:0] csr_low_addr;
-
- // xEPC
- reg_t mepc_reg;
-
- assign csr_rw_mask = addr[11:10];
- assign priv_level = addr[9:8];
- assign csr_low_addr = addr[7:0];
-
- always_comb begin
- illegal_rd = 1'b0;
- illegal_wr = csr_rw_mask == 2'b11 && rs1_num != '0;
- idx = '0;
-
- // numbers for csr_rw_mask and priv_level from privileged spec 2.1
- // register numbers from privileged spec 2.2
- unique case ({csr_rw_mask, priv_level})
- // unprivileged ro
- 4'b1100: begin
- unique case (csr_low_addr)
- // unprivileged counter/timer
- 8'h00: idx = CSR_REG_CYCLE;
- default: illegal_rd = 1'b1;
- endcase
- end
- // supervisor rw
- 4'b0001: begin
- unique case (csr_low_addr)
- // supervisor trap setup
- 8'h00: idx = CSR_REG_SSTATUS;
- 8'h04: idx = CSR_REG_SIE;
- 8'h05: idx = CSR_REG_STVEC;
- 8'h06: idx = CSR_REG_SCOUNTEREN;
- // supervisor trap handling
- 8'h40: idx = CSR_REG_SSCRATCH;
- 8'h41: idx = CSR_REG_SEPC;
- 8'h42: idx = CSR_REG_SCAUSE;
- 8'h43: idx = CSR_REG_STVAL;
- 8'h44: idx = CSR_REG_SIP;
- 8'h80: idx = CSR_REG_SATP;
- default: illegal_rd = 1'b1;
- endcase
- end
- // supervisor ro
- 4'b1101: begin
- unique case (csr_low_addr)
- // supervisor trap handling
- 8'hA0: idx = CSR_REG_SCOUNTOVF;
- default: illegal_rd = 1'b1;
- endcase
- end
- // machine rw
- 4'b0011: begin
- unique case (csr_low_addr)
- // machine trap setup
- 8'h00: idx = CSR_REG_MSTATUS;
- 8'h01: idx = CSR_REG_MISA;
- 8'h02: idx = CSR_REG_MEDELEG;
- 8'h03: idx = CSR_REG_MIDELEG;
- 8'h04: idx = CSR_REG_MIE;
- 8'h05: idx = CSR_REG_MTVEC;
- 8'h06: idx = CSR_REG_MCOUNTEREN;
- 8'h10: idx = CSR_REG_MSTATUSH;
- 8'h12: idx = CSR_REG_MEDELEGH;
- // machine trap handling
- 8'h40: idx = CSR_REG_MSCRATCH;
- 8'h41: idx = CSR_REG_MEPC;
- 8'h42: idx = CSR_REG_MCAUSE;
- 8'h43: idx = CSR_REG_MTVAL;
- 8'h44: idx = CSR_REG_MIP;
- 8'h4A: idx = CSR_REG_MTINST;
- 8'h4B: idx = CSR_REG_MTVAL2;
- // machine memory protection (subset)
- 8'hA0: idx = CSR_REG_PMPCFG0;
- 8'hB0: idx = CSR_REG_PMPADDR0;
- default: illegal_rd = 1'b1;
- endcase
- end
- 4'b0111: begin
- unique case (csr_low_addr)
- // machine non-maskable interrupt handling
- 8'h40: idx = CSR_REG_MNSCRATCH;
- 8'h41: idx = CSR_REG_MNEPC;
- 8'h42: idx = CSR_REG_MNCAUSE;
- 8'h44: idx = CSR_REG_MNSTATUS;
- default: illegal_rd = 1'b1;
- endcase
- end
- // machine ro
- 4'b1111: begin
- unique case (csr_low_addr)
- // machine information registers
- 8'h11: idx = CSR_REG_MVENDORID;
- 8'h12: idx = CSR_REG_MARCHID;
- 8'h13: idx = CSR_REG_MIMPID;
- 8'h14: idx = CSR_REG_MHARTID;
- 8'h15: idx = CSR_REG_MCONFIGPTR;
- default: illegal_rd = 1'b1;
- endcase
- end
- default: begin
- illegal_rd = 1'b1;
- illegal_wr = 1'b1;
- end
- endcase
- end
-
- always_ff @(posedge clk) begin
- // perform sequential read when rden
- if (rden && !illegal_rd) rdata <= regfile[idx];
- else rdata <= '0;
-
- // perform sequential write when wren and not read-only
- if (wren && !illegal_wr && rs1_num != '0) begin
- regfile[idx] <= wdata;
- if (idx == CSR_REG_MEPC) mepc_reg <= wdata;
- end
- end
-
- assign mepc_shadow = mepc_reg;
-
- assign illegal = (rden && illegal_rd) || (wren && illegal_wr);
-
-endmodule: csr_regfile
diff --git a/rtl/rv32g_hart.sv b/rtl/rv32g_hart.sv
@@ -22,13 +22,6 @@ module rv32g_hart
reg_t regfile [0:31];
reg_t next_pc;
- // Zicsr
- reg_t csr_rdata;
- logic csr_illegal;
-
- // CSR has xEPC registers for use with xRET instructions
- reg_t csr_mepc;
-
// pipeline registers
ifid_reg_t ifid_reg, ifid_next;
idex_reg_t idex_reg;
@@ -43,10 +36,9 @@ module rv32g_hart
ctrl_t dec_ctrl;
reg_t dec_pc, dec_imm, dec_rs1_val, dec_rs2_val;
logic [4:0] dec_rs1_num, dec_rs2_num, dec_rd_num;
- logic [11:0] dec_csr_addr;
// temporary execute signals
- reg_t ex_alu_out, ex_csr_out;
+ reg_t ex_alu_out;
logic ex_branch_taken;
// temporary memory signals
@@ -57,12 +49,6 @@ module rv32g_hart
assign if_stall = !imem_valid;
- // TODO move in between decode and execute for better organization?
- csr_regfile u_csr(.clk, .rstN, .addr(idex_reg.csr_addr), .rs1_num(idex_reg.rs1_num),
- .mepc_shadow(csr_mepc), .illegal(csr_illegal),
- .rden(idex_reg.ctrl.csr_rden), .rdata(csr_rdata),
- .wren(idex_reg.ctrl.csr_wren), .wdata(exmem_reg.csr_out));
-
// =============
// === FETCH ===
// =============
@@ -97,7 +83,7 @@ module rv32g_hart
.ctrl(dec_ctrl), .imm(dec_imm),
.rs1_num(dec_rs1_num), .rs2_num(dec_rs2_num),
.rs1_val(dec_rs1_val), .rs2_val(dec_rs2_val),
- .rd_num(dec_rd_num), .csr_addr(dec_csr_addr));
+ .rd_num(dec_rd_num));
// ID/EX pipeline register
always_ff @(posedge clk or negedge rstN) begin
if (!rstN) begin
@@ -118,8 +104,6 @@ module rv32g_hart
idex_reg.rs1_num <= dec_rs1_num;
idex_reg.rs2_num <= dec_rs2_num;
idex_reg.rd_num <= dec_rd_num;
- idex_reg.csr_addr <= dec_csr_addr;
- idex_reg.csr_rdata <= csr_rdata;
end
end
@@ -143,16 +127,8 @@ module rv32g_hart
.op1src(idex_reg.ctrl.aluop1src),
.op2src(idex_reg.ctrl.aluop2src),
.branchop(idex_reg.ctrl.branchop),
- .csrop(idex_reg.ctrl.csrop),
- .csr_rden(idex_reg.ctrl.csr_rden),
- .csr_wren(idex_reg.ctrl.csr_wren),
- .csr_immen(idex_reg.ctrl.csr_immen),
- .csr_imm(idex_reg.ctrl.csr_imm),
- .csr_rdata(idex_reg.csr_rdata),
- .is_mret(idex_reg.ctrl.is_mret),
.out(ex_alu_out),
- .branch_taken(ex_branch_taken),
- .csr_out(ex_csr_out));
+ .branch_taken(ex_branch_taken));
// EX/MEM pipeline register
always_ff @(posedge clk or negedge rstN) begin
if (!rstN) begin
@@ -160,7 +136,6 @@ module rv32g_hart
exmem_reg.pc = idex_reg.pc;
end else begin
exmem_reg.alu_out = ex_alu_out;
- exmem_reg.csr_out = ex_csr_out;
exmem_reg.rs2_val = idex_reg.rs2_val;
exmem_reg.pc = idex_reg.pc;
exmem_reg.imm = idex_reg.imm;
@@ -193,7 +168,6 @@ module rv32g_hart
end else begin
memwb_reg.alu_out = exmem_reg.alu_out;
memwb_reg.mem_out = mem_mem_out;
- memwb_reg.csr_out = exmem_reg.csr_out;
memwb_reg.pc = exmem_reg.pc;
memwb_reg.imm = exmem_reg.imm;
memwb_reg.rd_num = exmem_reg.rd_num;
@@ -227,12 +201,9 @@ module rv32g_hart
end
// jalr
PC_ALU: next_pc = memwb_reg.alu_out & ~32'b1; // spec says to clear LSB and /may/ raise an exception
- // CSR xRET
- PC_MRET: next_pc = csr_mepc & ~32'b11; // bit 0 always cleared for alignment, bit 1 when no C-extension
endcase
end
- assign exception = (idex_reg.ctrl.exception != EXC_NONE) ? idex_reg.ctrl.exception :
- (idex_reg.ctrl.csrop != CSR_NONE && csr_illegal) ? EXC_ILL_CSR : EXC_NONE;
+ assign exception = (idex_reg.ctrl.exception != EXC_NONE) ? idex_reg.ctrl.exception : EXC_NONE;
endmodule: rv32g_hart
diff --git a/rtl/rv32g_pkg.sv b/rtl/rv32g_pkg.sv
@@ -58,16 +58,7 @@ package rv32g_pkg;
FENCE_TSO,
PAUSE,
ECALL,
- EBREAK,
- // Zicsr
- CSRRW,
- CSRRS,
- CSRRC,
- CSRRWI,
- CSRRSI,
- CSRRCI,
- // privileged spec machine-mode (subset)
- MRET}
+ EBREAK}
inst_name_t;
// based off of Unprivileged ISA Chapter 36 Table 72 (no reserved)
@@ -157,9 +148,7 @@ package rv32g_pkg;
typedef enum logic [1:0] {PC_SEQ, // PC = PC + 4 (regular)
PC_IMM, // PC = PC + imm (branch and jal)
- PC_ALU, // PC = rs1 + imm (jalr)
- // for xRET instructions
- PC_MRET // PC = mepc (mret)
+ PC_ALU // PC = rs1 + imm (jalr)
} pcsrc_t;
typedef enum logic [2:0] {WB_NONE, // no register writeback
@@ -169,118 +158,10 @@ package rv32g_pkg;
WB_IMM // LUI writes back an immediate value
} wbsrc_t;
- localparam CSR_SIZE = 64;
- typedef enum logic [2:0] {CSR_NONE,
- CSR_RW,
- CSR_RS,
- CSR_RC
- } csrop_t;
-
- // numbers from privileged spec 2.2
- typedef enum logic [11:0] {// unprivileged counter/timers
- CSR_CYCLE = 'hC00,
- // supervisor trap setup
- CSR_SSTATUS = 'h100,
- CSR_SIE = 'h104,
- CSR_STVEC = 'h105,
- CSR_SCOUNTEREN = 'h106,
- // supervisor trap handling
- CSR_SSCRATCH = 'h140,
- CSR_SEPC = 'h141,
- CSR_SCAUSE = 'h142,
- CSR_STVAL = 'h143,
- CSR_SIP = 'h144,
- CSR_SCOUNTOVF = 'hDA0,
- // supervisor protection and translation
- CSR_SATP = 'h180,
- // machine information registers
- CSR_MVENDORID = 'hF11,
- CSR_MARCHID = 'hF12,
- CSR_MIMPID = 'hF13,
- CSR_MHARTID = 'hF14,
- CSR_MCONFIGPTR = 'hF15,
- // machine trap setup
- CSR_MSTATUS = 'h300,
- CSR_MISA = 'h301,
- CSR_MEDELEG = 'h302,
- CSR_MIDELEG = 'h303,
- CSR_MIE = 'h304,
- CSR_MTVEC = 'h305,
- CSR_MCOUNTEREN = 'h306,
- CSR_MSTATUSH = 'h310,
- CSR_MEDELEGH = 'h312,
- // machine trap handling
- CSR_MSCRATCH = 'h340,
- CSR_MEPC = 'h341,
- CSR_MCAUSE = 'h342,
- CSR_MTVAL = 'h343,
- CSR_MIP = 'h344,
- CSR_MTINST = 'h34A,
- CSR_MTVAL2 = 'h34B,
- // machine memory protection (subset)
- CSR_PMPCFG0 = 'h3A0,
- CSR_PMPADDR0 = 'h3B0,
- // machine non-maskable interrupt handling
- CSR_MNSCRATCH = 'h740,
- CSR_MNEPC = 'h741,
- CSR_MNCAUSE = 'h742,
- CSR_MNSTATUS = 'h744
- } csr_t;
- typedef enum logic [$clog2(CSR_SIZE)-1:0] {// unprivileged counter/timers
- CSR_REG_CYCLE,
- // supervisor trap setup
- CSR_REG_SSTATUS,
- CSR_REG_SIE,
- CSR_REG_STVEC,
- CSR_REG_SCOUNTEREN,
- // supervisor trap handling
- CSR_REG_SSCRATCH,
- CSR_REG_SEPC,
- CSR_REG_SCAUSE,
- CSR_REG_STVAL,
- CSR_REG_SIP,
- CSR_REG_SCOUNTOVF,
- // supervisor protection and translation
- CSR_REG_SATP,
- // machine information registers
- CSR_REG_MVENDORID,
- CSR_REG_MARCHID,
- CSR_REG_MIMPID,
- CSR_REG_MHARTID,
- CSR_REG_MCONFIGPTR,
- // machine trap setup
- CSR_REG_MSTATUS,
- CSR_REG_MISA,
- CSR_REG_MEDELEG,
- CSR_REG_MIDELEG,
- CSR_REG_MIE,
- CSR_REG_MTVEC,
- CSR_REG_MCOUNTEREN,
- CSR_REG_MSTATUSH,
- CSR_REG_MEDELEGH,
- // machine trap handling
- CSR_REG_MSCRATCH,
- CSR_REG_MEPC,
- CSR_REG_MCAUSE,
- CSR_REG_MTVAL,
- CSR_REG_MIP,
- CSR_REG_MTINST,
- CSR_REG_MTVAL2,
- // machine memory protection (subset)
- CSR_REG_PMPCFG0,
- CSR_REG_PMPADDR0,
- // machine non-maskable interrupt handling
- CSR_REG_MNSCRATCH,
- CSR_REG_MNEPC,
- CSR_REG_MNCAUSE,
- CSR_REG_MNSTATUS
- } csrreg_t;
-
// very rudimentary. privileged spec (chapter 3) defines this formally, but left to implementation
// on unprivileged spec.
- typedef enum logic [2:0] {EXC_NONE,
+ typedef enum logic [1:0] {EXC_NONE,
EXC_ILL_INST, // illegal instruction
- EXC_ILL_CSR, // illegal csr
EXC_CALL, // ECALL
EXC_BKPT // EBREAK
} exception_t;
@@ -293,14 +174,8 @@ package rv32g_pkg;
pcsrc_t pcsrc;
branchop_t branchop;
wbsrc_t wbsrc;
- csrop_t csrop;
- logic csr_rden;
- logic csr_wren;
- logic csr_immen;
- logic [4:0] csr_imm;
exception_t exception;
logic fence_flush;
- logic is_mret;
} ctrl_t;
// pipeline registers
@@ -318,13 +193,10 @@ package rv32g_pkg;
logic [4:0] rs1_num;
logic [4:0] rs2_num;
logic [4:0] rd_num;
- reg_t csr_rdata;
- logic [11:0] csr_addr;
} idex_reg_t;
typedef struct packed {
reg_t alu_out;
- reg_t csr_out;
reg_t rs2_val;
reg_t pc;
reg_t imm;
@@ -339,7 +211,6 @@ package rv32g_pkg;
typedef struct packed {
reg_t alu_out;
reg_t mem_out;
- reg_t csr_out;
reg_t pc;
reg_t imm;
logic [4:0] rd_num;
diff --git a/rtl/stage_decode.sv b/rtl/stage_decode.sv
@@ -11,7 +11,6 @@ module stage_decode
output logic [4:0] rs1_num,
output logic [4:0] rs2_num,
output logic [4:0] rd_num,
- output logic [11:0] csr_addr,
// passthrough
input reg_t pc_in,
output reg_t pc_out);
@@ -126,18 +125,6 @@ module stage_decode
if (rs1_num == '0 && rd_num == '0 && inst[31:20] == '0) name = FENCE_I;
else name = NAME_INVALID;
end
- // Zicsr
- {7'b???????, 3'b001, OPCODE_SYSTEM}: name = CSRRW;
- {7'b???????, 3'b010, OPCODE_SYSTEM}: name = CSRRS;
- {7'b???????, 3'b011, OPCODE_SYSTEM}: name = CSRRC;
- {7'b???????, 3'b101, OPCODE_SYSTEM}: name = CSRRWI;
- {7'b???????, 3'b110, OPCODE_SYSTEM}: name = CSRRSI;
- {7'b???????, 3'b111, OPCODE_SYSTEM}: name = CSRRCI;
- // privileged machine-mode (subset)
- {7'b0011000, 3'b000, OPCODE_SYSTEM}: begin
- if (rs1_num == '0 && rd_num == '0 && rs2_num == 5'b00010) name = MRET;
- else name = NAME_INVALID;
- end
default: name = NAME_INVALID;
endcase
end
@@ -151,15 +138,8 @@ module stage_decode
pcsrc: PC_SEQ,
branchop: BRANCH_NONE,
wbsrc: WB_NONE,
- csrop: CSR_NONE,
- csr_rden: 1'b0,
- csr_wren: 1'b0,
- csr_immen: 1'b0,
- csr_imm: inst[19:15],
exception: EXC_NONE,
- fence_flush: 1'b0,
- is_mret: 1'b0};
- csr_addr = '0;
+ fence_flush: 1'b0};
// the major opcodes share the same signals, just operation varies based on funct
unique case (opcode)
@@ -288,62 +268,6 @@ module stage_decode
// Zifencei
FENCE_I: ctrl.fence_flush = 1'b1;
default: ctrl.exception = EXC_ILL_INST;
- // Zicsr
- CSRRW: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RW;
- ctrl.csr_rden = rd_num != 0;
- ctrl.csr_wren = 1;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- CSRRS: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RS;
- ctrl.csr_rden = 1;
- ctrl.csr_wren = rs1_num != 0;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- CSRRC: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RC;
- ctrl.csr_rden = 1;
- ctrl.csr_wren = rs1_num != 0;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- CSRRWI: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RW;
- ctrl.csr_rden = rd_num != 0;
- ctrl.csr_wren = 1;
- ctrl.csr_immen = 1;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- CSRRSI: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RS;
- ctrl.csr_rden = 1;
- ctrl.csr_wren = ctrl.csr_imm != 0;
- ctrl.csr_immen = 1;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- CSRRCI: begin
- csr_addr = inst[31:20];
- ctrl.csrop = CSR_RC;
- ctrl.csr_rden = 1;
- ctrl.csr_wren = ctrl.csr_imm != 0;
- ctrl.csr_immen = 1;
- ctrl.wbsrc = (rd_num != 0) ? WB_ALU : WB_NONE;
- end
- // privileged machine-mode (subset)
- MRET: begin
- csr_addr = CSR_MSTATUS;
- ctrl.is_mret = 1;
- ctrl.csrop = CSR_NONE;
- ctrl.csr_rden = 1;
- ctrl.csr_wren = 1;
- ctrl.csr_immen = 0;
- ctrl.pcsrc = PC_MRET;
- end
endcase
end
diff --git a/rtl/stage_execute.sv b/rtl/stage_execute.sv
@@ -10,27 +10,10 @@ module stage_execute
input reg_t rs1_val,
input reg_t rs2_val,
output logic [31:0] out,
- output logic branch_taken,
- // Zicsr
- input csrop_t csrop,
- input logic csr_rden,
- input logic csr_wren,
- input logic csr_immen,
- input logic [4:0] csr_imm,
- input reg_t csr_rdata,
- output reg_t csr_out,
- // privileged machine-mode (subset)
- input logic is_mret);
+ output logic branch_taken);
reg_t a, b;
logic [4:0] shamt;
- logic [31:0] csr_wdata;
-
- // privileged machine-mode (subset)
- reg_t mstatus_q, mstatus_d;
- always_ff @(posedge clk) begin
- if (csr_wren) mstatus_q <= mstatus_d;
- end
always_comb begin
// assign inputs
@@ -49,11 +32,7 @@ module stage_execute
// perform computation
unique case (op)
- ALU_NONE: begin
- // Zicsr handled inside ALU_NONE to avoid multiple drivers of out
- if (csrop != CSR_NONE && csr_rden) out = csr_rdata;
- else out = '0;
- end
+ ALU_NONE: out = '0;
ALU_ADD: out = a + b;
ALU_SUB: out = $signed(a) - $signed(b);
ALU_XOR: out = a ^ b;
@@ -76,26 +55,6 @@ module stage_execute
BRANCH_BLTU: branch_taken = (out[0] == 1'b1) ? 1 : 0;
BRANCH_BGEU: branch_taken = (out[0] != 1'b1) ? 1 : 0;
endcase
-
- // Zicsr
- csr_wdata = (csr_immen) ? {{27{1'b0}}, csr_imm} : rs1_val;
- unique case (csrop)
- CSR_NONE: csr_out = 0;
- CSR_RW: csr_out = csr_wdata;
- CSR_RS: csr_out = csr_rdata | csr_wdata;
- CSR_RC: csr_out = csr_rdata & ~csr_wdata;
- endcase
-
- // privileged machine-mode (subset)
- mstatus_d = mstatus_q;
- if (is_mret) begin
- // MIE bit 3, MPIE bit 7, MPP bits 12-11
- mstatus_d[3] = mstatus_q[7]; // set MIE to MPIE
- mstatus_d[7] = 1'b1; // enable MPIE 1
- mstatus_d[12:11] = 2'b11; // set MPP to M-mode
- // with only M-mode, don't need to clear MPRV (bit 17)
- csr_out = mstatus_d;
- end
end
endmodule: stage_execute
diff --git a/rtl/tb_rv32g.sv b/rtl/tb_rv32g.sv
@@ -100,7 +100,6 @@ module tb_rv32g
unique case (dut.idex_reg.ctrl.exception)
EXC_NONE: ;
EXC_ILL_INST: $display("Exception: illegal instruction, inst: %h", dut.ifid_reg.inst);
- EXC_ILL_CSR: $display("Exception: illegal csr, inst: %h, csrop: %d, csr_addr: %h", dut.ifid_reg.inst, dut.idex_reg.ctrl.csrop, dut.idex_reg.csr_addr);
EXC_CALL: $display("Exception: ECALL");
EXC_BKPT: $display("Exception: BREAK");
endcase