diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index c18b3c7..998acd6 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -13,40 +13,22 @@ module serv_csr output wire o_timer_irq_en, input wire i_mstatus_en, input wire i_mie_en, - input wire i_mip_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, - input wire i_mtval, input wire [3:0] i_mcause, input wire i_d, output wire o_q); `include "serv_params.vh" - /* - 300 mstatus RWSC - 304 mie SCWi - 305 mtvec RW - 344 mip CWi - - 340 mscratch - 341 mepc RW - 342 mcause R - 343 mtval - */ reg mstatus; reg mstatus_mie; reg mie_mtie; - reg [31:0] mepc; reg mcause31; reg [3:0] mcause3_0; wire mcause; - reg [31:0] mtval; wire csr_in; wire csr_out; @@ -59,9 +41,7 @@ module serv_csr assign csr_out = (i_mstatus_en & mstatus) | i_rf_csr_out | - (i_mepc_en & mepc[0]) | - (i_mcause_en & mcause) | - (i_mtval_en & mtval[0]); + (i_mcause_en & mcause); assign o_q = csr_out; @@ -87,18 +67,12 @@ module serv_csr mcause3_0 <= (i_mtip & o_timer_irq_en) ? 4'd7 : i_mcause[3:0]; end - if (i_mepc_en | i_trap) - mepc <= {i_trap ? i_pc : csr_in, mepc[31:1]}; - if (i_mcause_en) begin if (i_cnt[4:2] == 3'd0) mcause3_0 <= {csr_in, mcause3_0[3:1]}; if ((i_cnt[4:2] == 3'd7) & i_cnt_r[3]) mcause31 <= csr_in; end - - if (i_mtval_en | i_trap) - mtval <= {i_trap ? i_mtval : csr_in, mtval[31:1]}; end endmodule diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index d3b2bc7..ef6c4a4 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -22,7 +22,7 @@ module serv_decode output wire o_ctrl_utype, output wire o_ctrl_lui, output wire o_ctrl_trap, - output wire o_ctrl_mret, + output reg o_ctrl_mret, input wire i_ctrl_misalign, output wire o_rf_rs_en, output wire o_rf_rd_en, @@ -47,14 +47,11 @@ 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 [1:0] o_csr_addr, 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, @@ -117,7 +114,8 @@ module serv_decode assign o_ctrl_utype = !opcode[4] & opcode[2] & opcode[0]; assign o_ctrl_jal_or_jalr = opcode[4] & opcode[0]; - assign o_ctrl_mret = (opcode[4] & opcode[2]) & op21 & !(|o_funct3); + + wire mret = (i_wb_rdt[6] & i_wb_rdt[4] & i_wb_rdt[21] & !(|i_wb_rdt[14:12])); assign o_rf_rd_en = running & (opcode[2] | (!opcode[2] & opcode[4] & opcode[0]) | @@ -148,17 +146,17 @@ module serv_decode 343 1_011 mtval 344 1_100 mip CWi */ + + //true for mtvec,mscratch,mepc and mtval + //false for mstatus, mie, mcause, mip + wire csr_valid = op20 | (op26 & !op22 & !op21); + + assign o_csr_en = (o_ctrl_mret & state[1]) | o_ctrl_trap | (csr_en & csr_valid); wire csr_en = opcode[4] & opcode[2] & (|o_funct3) & running; 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; - always @(o_funct3, o_rf_rs1_addr, o_ctrl_trap, o_ctrl_mret) begin @@ -239,6 +237,13 @@ module serv_decode op22 <= i_wb_rdt[22]; op26 <= i_wb_rdt[26]; + //Default to mtvec to have the correct CSR address loaded in case of trap + o_csr_addr <= mret ? 2'b10 : //mepc + (i_wb_rdt[26] & !i_wb_rdt[20]) ? 2'b00 : //mscratch + (i_wb_rdt[26] & !i_wb_rdt[21]) ? 2'b10 : //mepc + (i_wb_rdt[26]) ? 2'b11 : //mtval + 2'b01; //mtvec + o_ctrl_mret <= mret; imm[31] <= sign_bit; imm[30:20] <= utype ? i_wb_rdt[30:20] : {11{sign_bit}}; imm[19:12] <= (utype | jtype) ? i_wb_rdt[19:12] : {8{sign_bit}}; diff --git a/rtl/serv_mpram.v b/rtl/serv_mpram.v index 40e5192..2ed9a3b 100644 --- a/rtl/serv_mpram.v +++ b/rtl/serv_mpram.v @@ -3,15 +3,13 @@ module serv_mpram ( input wire i_clk, input wire i_rst, - //MEPC write port - input wire i_mepc_wen, + //Trap interface + input wire i_trap, input wire i_mepc, - //MTVAL write port - input wire i_mtval_wen, input wire i_mtval, //CSR interface - input wire i_csr_mscratch_en, - input wire i_csr_mtvec_en, + input wire i_csr_en, + input wire [1:0] i_csr_addr, input wire i_csr, output wire o_csr, //RD write port @@ -28,10 +26,6 @@ module serv_mpram input wire [4:0] i_rs2_raddr, output wire o_rs2); - reg [1:0] csr_addr; - wire csr_en = i_csr_mscratch_en|i_csr_mtvec_en; - - wire [8:0] waddr; reg [4:0] wdata0; @@ -55,24 +49,24 @@ module serv_mpram assign wen = !wgo_r & |(wen_r & wcnt_lo); reg [4:0] rd_waddr; - //mepc 100000 + //mepc 100010 //mtval 100011 //csr 1000xx //rd 0xxxxx assign waddr[8] = !wcnt_lo[3]; assign waddr[7:5] = wcnt_lo[3] ? rd_waddr[4:2] : 3'b000; assign waddr[4:3] = wcnt_lo[3] ? rd_waddr[1:0] : - wcnt_lo[2] ? csr_addr : - wcnt_lo[1] ? 2'b11 : 2'b00; + wcnt_lo[2] ? i_csr_addr : + wcnt_lo[1] ? 2'b11 : 2'b10; assign waddr[2:0] = wcnt_hi; - wire wgo = !(|wcnt_lo) & |({i_rd_wen,csr_en,i_mtval_wen,i_mepc_wen}); + wire wgo = !(|wcnt_lo) & |({i_rd_wen,i_csr_en,i_trap, i_trap}); always @(posedge i_clk) begin if (wgo) begin wgo_r <= 1'b1; - wen_r <= {i_rd_wen,csr_en,i_mtval_wen,i_mepc_wen}; + wen_r <= {i_rd_wen,i_csr_en,i_trap,i_trap}; rd_waddr <= i_rd_waddr; end wdata0 <= {i_mepc,wdata0[4:1]}; @@ -120,11 +114,9 @@ module serv_mpram if (i_rreq) begin rcnt_lo <= 4'd1; rcnt_hi <= 3'd0; - csr_addr <= {1'b0,i_csr_mtvec_en}; end else rcnt_lo <= {rcnt_lo[2:0],rcnt_lo[3]}; - rdata0[4:0] <= rdata0[5:1]; rdata1[3:0] <= rdata1[4:1]; rdata2[2:0] <= rdata2[3:1]; @@ -145,12 +137,12 @@ module serv_mpram assign raddr[7:5] = rcnt_lo[0] ? i_rs1_raddr[4:2] : rcnt_lo[1] ? i_rs2_raddr[4:2] : 3'd0; assign raddr[4:3] = rcnt_lo[0] ? i_rs1_raddr[1:0] : - rcnt_lo[1] ? i_rs2_raddr[1:0] : csr_addr; + rcnt_lo[1] ? i_rs2_raddr[1:0] : i_csr_addr; assign raddr[2:0] = rcnt_hi; assign o_rs1 = rdata0[0]; assign o_rs2 = rdata1[0]; - assign o_csr = rdata2[0] & csr_en; + assign o_csr = rdata2[0] & i_csr_en; reg [3:0] memory [0:511]; diff --git a/rtl/serv_top.v b/rtl/serv_top.v index da4c29e..3229fbd 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -117,15 +117,12 @@ module serv_top 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; + wire csr_en; + wire [1:0] csr_addr; wire [3:0] mcause; @@ -184,14 +181,11 @@ 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_addr (csr_addr), .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), @@ -300,15 +294,13 @@ module serv_top ( .i_clk (clk), .i_rst (i_rst), - //MEPC write port - .i_mepc_wen (1'b0), - .i_mepc (1'b0), - //MTVAL write port - .i_mtval_wen (1'b0), - .i_mtval (1'b0), + //Trap interface + .i_trap (trap), + .i_mepc (o_ibus_adr[0]), + .i_mtval (mem_misalign ? bad_adr : bad_pc), //CSR write port - .i_csr_mscratch_en (csr_mscratch_en), - .i_csr_mtvec_en (csr_mtvec_en), + .i_csr_en (csr_en), + .i_csr_addr (csr_addr), .i_csr (csr_in), //RD write port .i_rd_wen (rd_en & (|rd_addr)), @@ -359,14 +351,9 @@ module serv_top .o_timer_irq_en ( timer_irq_en), .i_mstatus_en (csr_mstatus_en), .i_mie_en (csr_mie_en ), - .i_mip_en (csr_mip_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]), - .i_mtval (mem_misalign ? bad_adr : bad_pc), .i_mcause (mcause), .i_d (csr_d_sel ? csr_imm : rs1), .o_q (csr_rd)); @@ -376,7 +363,7 @@ module serv_top always @(posedge clk) begin rvfi_valid <= cnt_done & ctrl_pc_en; - rvfi_order <= rvfi_order + rvfi_valid; + rvfi_order <= rvfi_order + {63'd0,rvfi_valid}; if (o_ibus_cyc & i_ibus_ack) rvfi_insn <= i_ibus_rdt; if (rd_en) @@ -420,8 +407,10 @@ module serv_top rvfi_mem_wmask <= 4'b0000; end end + /* verilator lint_off COMBDLY */ always @(o_ibus_adr) rvfi_pc_wdata <= o_ibus_adr; + /* verilator lint_on COMBDLY */ `endif