Skip to content

Commit

Permalink
Optimize csr address handling
Browse files Browse the repository at this point in the history
  • Loading branch information
olofk committed Jan 23, 2021
1 parent e8bc87f commit 8d5dd77
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 26 deletions.
35 changes: 15 additions & 20 deletions rtl/serv_decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -147,28 +147,27 @@ module serv_decode
/*
Bits 26, 22, 21 and 20 are enough to uniquely identify the eight supported CSR regs
mtvec, mscratch, mepc and mtval are stored externally (normally in the RF) and are
treated differently from mstatus, mie, mcause and mip which are stored in serv_csr.
treated differently from mstatus, mie and mcause which are stored in serv_csr.
The former get a 2-bit address (as found in serv_params.vh) while the latter get a
The former get a 2-bit address as seen below while the latter get a
one-hot enable signal each.
Hex|2 222|Reg
adr|6 210|name
---|-----|-------
300|0_000|mstatus
304|0_100|mie
305|0_101|mtvec
340|1_000|mscratch
341|1_001|mepc
342|1_010|mcause
343|1_011|mtval
344|1_100|mip
Hex|2 222|Reg |csr
adr|6 210|name |addr
---|-----|--------|----
300|0_000|mstatus | xx
304|0_100|mie | xx
305|0_101|mtvec | 01
340|1_000|mscratch| 00
341|1_001|mepc | 10
342|1_010|mcause | xx
343|1_011|mtval | 11
*/

//true for mtvec,mscratch,mepc and mtval
//false for mstatus, mie, mcause, mip
wire csr_valid = op20 | (op26 & !op22 & !op21);
//false for mstatus, mie, mcause
wire csr_valid = op20 | (op26 & !op21);

assign o_rd_csr_en = csr_op;

Expand All @@ -180,11 +179,7 @@ module serv_decode
assign o_csr_source = funct3[1:0];
assign o_csr_d_sel = funct3[2];
assign o_csr_imm_en = opcode[4] & opcode[2] & funct3[2];

assign o_csr_addr = (op26 & !op20) ? CSR_MSCRATCH :
(op26 & !op21) ? CSR_MEPC :
(op26) ? CSR_MTVAL :
CSR_MTVEC;
assign o_csr_addr = {op26 & op20, !op26 | op21};

assign o_alu_cmp_eq = funct3[2:1] == 2'b00;

Expand Down
30 changes: 24 additions & 6 deletions rtl/serv_rf_if.v
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,31 @@ module serv_rf_if
//0 : RS1
//1 : RS2 / CSR


assign o_rreg0 = {1'b0, i_rs1_raddr};
assign o_rreg1 =
i_trap ? {4'b1000, CSR_MTVEC} :
i_mret ? {4'b1000, CSR_MEPC} :
i_csr_en ? {4'b1000, i_csr_addr} :
{1'b0,i_rs2_raddr};

/*
The address of the second read port (o_rreg1) can get assigned from four
different sources
Normal operations : i_rs2_raddr
CSR access : i_csr_addr
trap : MTVEC
mret : MEPC
Address 0-31 in the RF are assigned to the GPRs. After that follows the four
CSRs on addresses 32-35
32 MSCRATCH
33 MTVEC
34 MEPC
35 MTVAL
The expression below is an optimized version of this logic
*/
wire sel_rs2 = !(i_trap | i_mret | i_csr_en);
assign o_rreg1 = {~sel_rs2,
i_rs2_raddr[4:2] & {3{sel_rs2}},
{1'b0,i_trap} | {i_mret,1'b0} | ({2{i_csr_en}} & i_csr_addr) | ({2{sel_rs2}} & i_rs2_raddr[1:0])};

assign o_rs1 = i_rdata0;
assign o_rs2 = i_rdata1;
Expand Down

0 comments on commit 8d5dd77

Please sign in to comment.