1
0
mirror of https://github.com/olofk/serv.git synced 2026-05-02 22:42:41 +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 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 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. one-hot enable signal each.
Hex|2 222|Reg Hex|2 222|Reg |csr
adr|6 210|name adr|6 210|name |addr
---|-----|------- ---|-----|--------|----
300|0_000|mstatus 300|0_000|mstatus | xx
304|0_100|mie 304|0_100|mie | xx
305|0_101|mtvec 305|0_101|mtvec | 01
340|1_000|mscratch 340|1_000|mscratch| 00
341|1_001|mepc 341|1_001|mepc | 10
342|1_010|mcause 342|1_010|mcause | xx
343|1_011|mtval 343|1_011|mtval | 11
344|1_100|mip
*/ */
//true for mtvec,mscratch,mepc and mtval //true for mtvec,mscratch,mepc and mtval
//false for mstatus, mie, mcause, mip //false for mstatus, mie, mcause
wire csr_valid = op20 | (op26 & !op22 & !op21); wire csr_valid = op20 | (op26 & !op21);
assign o_rd_csr_en = csr_op; assign o_rd_csr_en = csr_op;
@@ -180,11 +179,7 @@ module serv_decode
assign o_csr_source = funct3[1:0]; assign o_csr_source = funct3[1:0];
assign o_csr_d_sel = funct3[2]; assign o_csr_d_sel = funct3[2];
assign o_csr_imm_en = opcode[4] & opcode[2] & funct3[2]; assign o_csr_imm_en = opcode[4] & opcode[2] & funct3[2];
assign o_csr_addr = {op26 & op20, !op26 | op21};
assign o_csr_addr = (op26 & !op20) ? CSR_MSCRATCH :
(op26 & !op21) ? CSR_MEPC :
(op26) ? CSR_MTVAL :
CSR_MTVEC;
assign o_alu_cmp_eq = funct3[2:1] == 2'b00; assign o_alu_cmp_eq = funct3[2:1] == 2'b00;

View File

@@ -83,13 +83,31 @@ module serv_rf_if
//0 : RS1 //0 : RS1
//1 : RS2 / CSR //1 : RS2 / CSR
assign o_rreg0 = {1'b0, i_rs1_raddr}; assign o_rreg0 = {1'b0, i_rs1_raddr};
assign o_rreg1 =
i_trap ? {4'b1000, CSR_MTVEC} : /*
i_mret ? {4'b1000, CSR_MEPC} : The address of the second read port (o_rreg1) can get assigned from four
i_csr_en ? {4'b1000, i_csr_addr} : different sources
{1'b0,i_rs2_raddr};
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_rs1 = i_rdata0;
assign o_rs2 = i_rdata1; assign o_rs2 = i_rdata1;