diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index 9db26bb..14d7d8a 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -2,11 +2,17 @@ module serv_csr ( input wire i_clk, - input wire i_en, input wire [4:0] i_cnt, input wire i_mtip, output wire o_timer_irq_en, - input wire [2:0] i_csr_sel, + input wire i_mstatus_en, + input wire i_mie_en, + input wire i_mtvec_en, + input wire i_mip_en, + input wire i_mscratch_en, + input wire i_mepc_en, + input wire i_mcause_en, + input wire i_mtval_en, input wire [1:0] i_csr_source, input wire i_trap, input wire i_pc, @@ -35,16 +41,11 @@ module serv_csr reg [31:0] mtvec = 32'h0; reg mip; - reg [31:0] mscratch = 32'h0; - reg [31:0] mepc = 32'h0; - reg [31:0] mcause = 32'h0; - reg [31:0] mtval = 32'h0; + reg [31:0] mscratch; + reg [31:0] mepc; + reg [31:0] mcause; + reg [31:0] mtval; - wire mtvec_en = i_en & (i_csr_sel == CSR_SEL_MTVEC); - wire mscratch_en = i_en & (i_csr_sel == CSR_SEL_MSCRATCH); - wire mepc_en = i_en & (i_trap | (i_csr_sel == CSR_SEL_MEPC)); - wire mcause_en = i_en & (i_csr_sel == CSR_SEL_MCAUSE); - wire mtval_en = i_en & (i_trap | (i_csr_sel == CSR_SEL_MTVAL)); wire csr_in; wire csr_out; @@ -55,24 +56,22 @@ module serv_csr (i_csr_source == CSR_SOURCE_CSR) ? csr_out : 1'bx; - assign csr_out = (i_csr_sel == CSR_SEL_MSTATUS) ? mstatus : - (i_csr_sel == CSR_SEL_MTVEC) ? mtvec[0] : - (i_csr_sel == CSR_SEL_MSCRATCH) ? mscratch[0] : - (i_csr_sel == CSR_SEL_MEPC) ? mepc[0] : - (i_csr_sel == CSR_SEL_MCAUSE) ? mcause[0] : - (i_csr_sel == CSR_SEL_MTVAL) ? mtval[0] : - 1'bx; - + assign csr_out = (i_mstatus_en & mstatus) | + (i_mtvec_en & mtvec[0]) | + (i_mscratch_en & mscratch[0]) | + (i_mepc_en & mepc[0]) | + (i_mcause_en & mcause[0]) | + (i_mtval_en & mtval[0]); assign o_q = csr_out; assign o_timer_irq_en = mstatus_mie & mie_mtie; always @(posedge i_clk) begin - if (i_en & (i_cnt == 3) & (i_csr_sel == CSR_SEL_MSTATUS)) + if (i_mstatus_en & (i_cnt == 3)) mstatus_mie <= csr_in; - if (i_en & (i_cnt == 7) & (i_csr_sel == CSR_SEL_MIE)) + if (i_mie_en & (i_cnt == 7)) mie_mtie <= csr_in; mstatus <= (i_cnt == 2) ? mstatus_mie : 1'b0; @@ -83,19 +82,19 @@ module serv_csr mcause[31] <= i_mtip & o_timer_irq_en; mcause[3:0] <= (i_mtip & o_timer_irq_en) ? 4'd7 : i_mcause[3:0]; end - if (mscratch_en) + if (i_mscratch_en) mscratch <= {csr_in, mscratch[31:1]}; - if (mtvec_en) + if (i_mtvec_en) mtvec <= {csr_in, mtvec[31:1]}; - if (mepc_en) + if (i_mepc_en | i_trap) mepc <= {i_trap ? i_pc : csr_in, mepc[31:1]}; - if (mcause_en) + if (i_mcause_en) mcause <= {csr_in, mcause[31:1]}; - if (mtval_en) + if (i_mtval_en | i_trap) mtval <= {i_trap ? i_mtval : csr_in, mtval[31:1]}; end diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index 93b62eb..226319a 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -41,8 +41,14 @@ module serv_decode output wire o_mem_init, output wire [1:0] o_mem_bytecnt, input wire i_mem_misalign, - output wire o_csr_en, - output reg [2:0] o_csr_sel, + output wire o_csr_mstatus_en, + output wire o_csr_mie_en, + output wire o_csr_mtvec_en, + output wire o_csr_mip_en, + output wire o_csr_mscratch_en, + output wire o_csr_mepc_en, + output wire o_csr_mcause_en, + output wire o_csr_mtval_en, output reg [1:0] o_csr_source, output reg [3:0] o_csr_mcause, output wire o_csr_imm, @@ -52,7 +58,6 @@ module serv_decode output wire o_op_b_source, output wire o_rd_ctrl_en, output wire o_rd_alu_en, - output wire o_rd_csr_en, output wire o_rd_mem_en); `include "serv_params.vh" @@ -109,7 +114,7 @@ module serv_decode assign branch_op = (opcode[4:2] == 3'b110) & !opcode[0]; - assign e_op = (opcode[4:2] == 3'b111) & !(|o_funct3); + assign e_op = (opcode[4:2] == 3'b111) & !op21 & !(|o_funct3); assign o_ctrl_pc_en = running | o_ctrl_trap; wire take_branch = (opcode[4:2] == 3'b110) & (opcode[0] | i_alu_cmp); @@ -145,13 +150,29 @@ module serv_decode assign o_alu_cmp_neg = branch_op & o_funct3[0]; + /* + 300 0_000 mstatus RWSC + 304 0_100 mie SCWi + 305 0_101 mtvec RW + 340 1_000 mscratch + 341 1_001 mepc RW + 342 1_010 mcause R + 343 1_011 mtval + 344 1_100 mip CWi + */ + assign o_csr_mstatus_en = csr_en & !op26 & !op22; + assign o_csr_mie_en = csr_en & !op26 & op22 & !op20; + assign o_csr_mtvec_en = ((!op26 & op20 & opcode[4] & opcode[2]) & state[1]) | (state == TRAP); + assign o_csr_mscratch_en = csr_en & op26 & !op22 & !op21 & !op20; + assign o_csr_mepc_en = csr_en & op26 & !op21 & op20 | (o_ctrl_mret & state[1]); + assign o_csr_mcause_en = csr_en & op21 & !op20; + assign o_csr_mtval_en = csr_en & op21 & op20; + assign o_csr_mip_en = csr_en & op26 & op22; - assign o_csr_en = ((((opcode[4] & opcode[2]) & (|o_funct3)) | - o_ctrl_mret) & running) | o_ctrl_trap; + wire csr_en = opcode[4] & opcode[2] & (|o_funct3) & running; - wire [3:0] csr_sel = {op26,op22, op21, op20}; - always @(o_funct3, csr_sel, o_rf_rs1_addr, o_ctrl_trap, o_ctrl_mret) begin + always @(o_funct3, o_rf_rs1_addr, o_ctrl_trap, o_ctrl_mret) begin casez (o_funct3) 3'b00? : o_alu_cmp_sel = ALU_CMP_EQ; 3'b01? : o_alu_cmp_sel = ALU_CMP_LT; @@ -177,27 +198,6 @@ module serv_decode if (((o_rf_rs1_addr == 5'd0) & o_funct3[1]) | o_ctrl_trap | o_ctrl_mret) o_csr_source = CSR_SOURCE_CSR; - casez(csr_sel) - 4'b0_000 : o_csr_sel = CSR_SEL_MSTATUS; - 4'b0_100 : o_csr_sel = CSR_SEL_MIE; - 4'b0_101 : o_csr_sel = CSR_SEL_MTVEC; - 4'b1_000 : o_csr_sel = CSR_SEL_MSCRATCH; - 4'b1_001 : o_csr_sel = CSR_SEL_MEPC; - 4'b1_010 : o_csr_sel = CSR_SEL_MCAUSE; - 4'b1_011 : o_csr_sel = CSR_SEL_MTVAL; - 4'b1_100 : o_csr_sel = CSR_SEL_MIP; - default : begin - o_csr_sel = 3'bxxx; - /*if (o_csr_en) begin - $display("%0t: CSR %03h not implemented", $time, op[31:20]); - //#100 $finish; - end*/ - end - endcase - if (o_ctrl_trap) - o_csr_sel = CSR_SEL_MTVEC; - if (o_ctrl_mret) - o_csr_sel = CSR_SEL_MEPC; end assign o_csr_imm = (cnt < 5) ? o_rf_rs1_addr[cnt[2:0]] : 1'b0; @@ -278,7 +278,6 @@ module serv_decode assign o_rd_ctrl_en = opcode[0]; assign o_rd_alu_en = !opcode[0] & opcode[2] & !opcode[4]; - assign o_rd_csr_en = opcode[2] & opcode[4]; assign o_rd_mem_en = !opcode[2] & !opcode[4]; wire cnt_en = (state != IDLE); diff --git a/rtl/serv_params.vh b/rtl/serv_params.vh index 08ae454..63d905b 100644 --- a/rtl/serv_params.vh +++ b/rtl/serv_params.vh @@ -26,27 +26,6 @@ localparam [0:0] AND */ - /* - 300 mstatus RWSC - 304 mie SCWi - 305 mtvec RW - 344 mip CWi - - 340 mscratch - 341 mepc RW - 342 mcause R - 343 mtval - */ -localparam [2:0] - CSR_SEL_MSTATUS = 3'd0, - CSR_SEL_MIE = 3'd1, - CSR_SEL_MTVEC = 3'd2, - CSR_SEL_MIP = 3'd3, - CSR_SEL_MSCRATCH = 3'd4, - CSR_SEL_MEPC = 3'd5, - CSR_SEL_MCAUSE = 3'd6, - CSR_SEL_MTVAL = 3'd7; - localparam [1:0] CSR_SOURCE_CSR = 2'b00, CSR_SOURCE_EXT = 2'b01, diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 76d7368..3179b79 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -53,7 +53,6 @@ module serv_top wire rd_ctrl_en; wire rd_alu_en; - wire rd_csr_en; wire rd_mem_en; wire ctrl_rd; wire alu_rd; @@ -109,8 +108,14 @@ module serv_top wire bad_pc; wire bad_adr; - wire csr_en; - wire [2:0] csr_sel; + wire csr_mstatus_en; + wire csr_mie_en; + wire csr_mtvec_en; + wire csr_mip_en; + wire csr_mscratch_en; + wire csr_mepc_en; + wire csr_mcause_en; + wire csr_mtval_en; wire [1:0] csr_source; wire csr_imm; wire csr_d_sel; @@ -166,8 +171,14 @@ module serv_top .o_mem_init (mem_init), .o_mem_bytecnt (mem_bytecnt), .i_mem_misalign (mem_misalign), - .o_csr_en (csr_en), - .o_csr_sel (csr_sel), + .o_csr_mstatus_en (csr_mstatus_en), + .o_csr_mie_en (csr_mie_en), + .o_csr_mtvec_en (csr_mtvec_en), + .o_csr_mip_en (csr_mip_en), + .o_csr_mscratch_en (csr_mscratch_en), + .o_csr_mepc_en (csr_mepc_en), + .o_csr_mcause_en (csr_mcause_en), + .o_csr_mtval_en (csr_mtval_en), .o_csr_source (csr_source), .o_csr_mcause (mcause), .o_csr_imm (csr_imm), @@ -176,7 +187,6 @@ module serv_top .o_op_b_source (op_b_source), .o_rd_ctrl_en (rd_ctrl_en), .o_rd_alu_en (rd_alu_en), - .o_rd_csr_en (rd_csr_en), .o_rd_mem_en (rd_mem_en)); serv_ctrl @@ -205,7 +215,7 @@ module serv_top assign rd = (rd_ctrl_en & ctrl_rd) | (rd_alu_en & alu_rd ) | - (rd_csr_en & csr_rd ) | + (csr_rd ) | (rd_mem_en & mem_rd); assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm : rs2; @@ -274,11 +284,17 @@ module serv_top serv_csr csr ( .i_clk (clk), - .i_en (csr_en), .i_cnt (cnt), .i_mtip (i_timer_irq), .o_timer_irq_en ( timer_irq_en), - .i_csr_sel (csr_sel), + .i_mstatus_en (csr_mstatus_en), + .i_mie_en (csr_mie_en ), + .i_mtvec_en (csr_mtvec_en ), + .i_mip_en (csr_mip_en ), + .i_mscratch_en (csr_mscratch_en), + .i_mepc_en (csr_mepc_en ), + .i_mcause_en (csr_mcause_en ), + .i_mtval_en (csr_mtval_en ), .i_csr_source (csr_source), .i_trap (trap), .i_pc (o_ibus_adr[0]),