Move mepc and mtval into RF memory

This commit is contained in:
Olof Kindgren 2019-07-07 23:08:26 +02:00
parent 93f7b582bb
commit 16c93a58ee
4 changed files with 43 additions and 83 deletions

View file

@ -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

View file

@ -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}};

View file

@ -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];

View file

@ -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