1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-11 23:42:50 +00:00

Optimize csr address handling

This commit is contained in:
Olof Kindgren 2021-01-21 13:16:48 +01:00
parent e8bc87fd0e
commit 8d5dd77a26
2 changed files with 39 additions and 26 deletions

View File

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

View File

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