1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-17 16:33:40 +00:00

Simplify csr stuff

This commit is contained in:
Olof Kindgren 2019-07-16 23:45:43 +02:00
parent 7425128dd8
commit a0ba84096a
4 changed files with 35 additions and 23 deletions

View File

@ -45,12 +45,13 @@ module serv_decode
output wire o_mem_init,
output wire [1:0] o_mem_bytecnt,
input wire i_mem_misalign,
output wire o_rd_csr_en,
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_mcause_en,
output reg [1:0] o_csr_source,
output wire [1:0] o_csr_source,
output reg [3:0] o_csr_mcause,
output wire o_csr_imm,
output wire o_csr_d_sel,
@ -98,7 +99,9 @@ module serv_decode
assign shift_op = op_or_opimm & (o_funct3[1:0] == 2'b01);
assign slt_op = op_or_opimm & (o_funct3[2:1] == 2'b01);
assign e_op = (opcode[4:2] == 3'b111) & !op21 & !(|o_funct3);
//Matches system opcodes except CSR accesses (o_funct3 == 0)
//No idea anymore why the !op21 condition is needed here
assign e_op = opcode[4] & opcode[2] & !op21 & !(|o_funct3);
//jal,branch = imm
//jalr = rs1+imm
@ -160,9 +163,11 @@ module serv_decode
//false for mstatus, mie, mcause, mip
wire csr_valid = op20 | (op26 & !op22 & !op21);
//Matches system ops except eceall/ebreak
wire csr_op = opcode[4] & opcode[2] & (|o_funct3);
assign o_rd_csr_en = csr_op;
assign o_csr_en = state[1] & (o_ctrl_mret | state[0] | (csr_op & csr_valid));
assign o_csr_en = csr_op & (state == RUN) & csr_valid;
assign o_csr_mstatus_en = csr_op & (state == RUN) & !op26 & !op22;
assign o_csr_mie_en = csr_op & (state == RUN) & !op26 & op22 & !op20;
assign o_csr_mcause_en = csr_op & (state == RUN) & op21 & !op20;
@ -170,7 +175,7 @@ module serv_decode
assign o_alu_cmp_eq = o_funct3[2:1] == 2'b00;
always @(o_funct3, o_rf_rs1_addr, o_ctrl_trap, o_ctrl_mret) begin
always @(o_funct3) begin
casez (o_funct3)
3'b00? : o_alu_cmp_uns = 1'b0;
3'b010 : o_alu_cmp_uns = 1'b0;
@ -179,18 +184,9 @@ module serv_decode
3'b11? : o_alu_cmp_uns = 1'b1;
default : o_alu_cmp_uns = 1'bx;
endcase
casez(o_funct3[1:0])
2'b01 : o_csr_source = CSR_SOURCE_EXT; //Check for x0
2'b10 : o_csr_source = CSR_SOURCE_SET;
2'b11 : o_csr_source = CSR_SOURCE_CLR;
default : o_csr_source = 2'bxx;
endcase
if (((o_rf_rs1_addr == 5'd0) & o_funct3[1]) | o_ctrl_trap | o_ctrl_mret)
o_csr_source = CSR_SOURCE_CSR;
end
assign o_csr_source = o_funct3[1:0];
assign o_csr_imm = (o_cnt < 5) ? o_rf_rs1_addr[o_cnt[2:0]] : 1'b0;
assign o_csr_d_sel = o_funct3[2];
@ -242,11 +238,11 @@ module serv_decode
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_csr_addr <= mret ? CSR_MEPC :
(i_wb_rdt[26] & !i_wb_rdt[20]) ? CSR_MSCRATCH :
(i_wb_rdt[26] & !i_wb_rdt[21]) ? CSR_MEPC :
(i_wb_rdt[26]) ? CSR_MTVAL :
CSR_MTVEC;
o_ctrl_mret <= mret;
imm[31] <= sign_bit;
imm[30:20] <= utype ? i_wb_rdt[30:20] : {11{sign_bit}};

View File

@ -7,6 +7,7 @@ module serv_mpram
input wire i_trap,
input wire i_mepc,
input wire i_mtval,
output wire o_csr_pc,
//CSR interface
input wire i_csr_en,
input wire [1:0] i_csr_addr,
@ -26,6 +27,8 @@ module serv_mpram
input wire [4:0] i_rs2_raddr,
output wire o_rs2);
`include "serv_params.vh"
wire [8:0] waddr;
reg [4:0] wdata0;
@ -57,7 +60,7 @@ module serv_mpram
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] ? i_csr_addr :
wcnt_lo[1] ? 2'b11 : 2'b10;
wcnt_lo[1] ? CSR_MTVAL : CSR_MEPC;
assign waddr[2:0] = wcnt_hi;
wire wgo = !(|wcnt_lo) & |({i_rd_wen,i_csr_en,i_trap, i_trap});
@ -137,12 +140,14 @@ 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] : i_csr_addr;
rcnt_lo[1] ? i_rs2_raddr[1:0] :
i_trap ? CSR_MTVEC : i_csr_addr;
assign raddr[2:0] = rcnt_hi;
assign o_rs1 = rdata0[0];
assign o_rs2 = rdata1[0];
assign o_csr = rdata2[0] & i_csr_en;
assign o_csr_pc = rdata2[0];
reg [3:0] memory [0:511];

View File

@ -13,3 +13,9 @@ localparam [1:0]
CSR_SOURCE_EXT = 2'b01,
CSR_SOURCE_SET = 2'b10,
CSR_SOURCE_CLR = 2'b11;
localparam [1:0]
CSR_MSCRATCH = 2'b00,
CSR_MTVEC = 2'b01,
CSR_MEPC = 2'b10,
CSR_MTVAL = 2'b11;

View File

@ -48,6 +48,7 @@ module serv_top
wire rd_alu_en;
wire rd_mem_en;
wire rd_csr_en;
wire ctrl_rd;
wire alu_rd;
wire mem_rd;
@ -116,6 +117,8 @@ module serv_top
wire csr_d_sel;
wire csr_en;
wire [1:0] csr_addr;
wire csr_pc;
wire [3:0] mcause;
@ -170,6 +173,7 @@ module serv_top
.o_mem_init (mem_init),
.o_mem_bytecnt (mem_bytecnt),
.i_mem_misalign (mem_misalign),
.o_rd_csr_en (rd_csr_en),
.o_csr_en (csr_en),
.o_csr_addr (csr_addr),
.o_csr_mstatus_en (csr_mstatus_en),
@ -225,7 +229,7 @@ module serv_top
//Data
.i_imm (imm),
.i_buf (bufreg_q),
.i_csr_pc (csr_rd),
.i_csr_pc (csr_pc),
.o_rd (ctrl_rd),
.o_bad_pc (bad_pc),
//External
@ -235,7 +239,7 @@ module serv_top
assign rd = (ctrl_rd ) |
(rd_alu_en & alu_rd ) |
(csr_rd ) |
(csr_rd & rd_csr_en) |
(rd_mem_en & mem_rd);
assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm : rs2;
@ -287,6 +291,7 @@ module serv_top
.i_trap (trap),
.i_mepc (o_ibus_adr[0]),
.i_mtval (mem_misalign ? bufreg_q : bad_pc),
.o_csr_pc (csr_pc),
//CSR write port
.i_csr_en (csr_en),
.i_csr_addr (csr_addr),