Skip to content

Commit

Permalink
Increase max num PMPs to 64 (#2279)
Browse files Browse the repository at this point in the history
  • Loading branch information
Moschn authored Jul 4, 2024
1 parent d98ac14 commit 246961b
Show file tree
Hide file tree
Showing 30 changed files with 307 additions and 129 deletions.
4 changes: 2 additions & 2 deletions config/gen_from_riscv_config/cv32a65x/csr/csr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ MIP
PMPCFG[0-3]
~~~~~~~~~~~

:Address: 0x3a0-0x3a3
:Address: 0x3a0-0x3af
:Reset Value: 0x00000000
:Privilege: MRW
:Description: PMP configuration register
Expand All @@ -428,7 +428,7 @@ PMPCFG[0-3]
PMPADDR[0-15]
~~~~~~~~~~~~~

:Address: 0x3b0-0x3bf
:Address: 0x3b0-0x3ef
:Reset Value: 0x00000000
:Privilege: MRW
:Description: Physical memory protection address register
Expand Down
4 changes: 2 additions & 2 deletions core/acc_dispatcher.sv
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ module acc_dispatcher
// Interface with the CSRs
input priv_lvl_t ld_st_priv_lvl_i,
input logic sum_i,
input pmpcfg_t [15:0] pmpcfg_i,
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input logic [2:0] fcsr_frm_i,
output logic dirty_v_state_o,
// Interface with the issue stage
Expand Down
206 changes: 161 additions & 45 deletions core/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ module csr_regfile
input logic [CVA6Cfg.XLEN-1:0] perf_data_i,
// TO_BE_COMPLETED - PERF_COUNTERS
output logic perf_we_o,
// PMP configuration containing pmpcfg for max 16 PMPs - ACC_DISPATCHER
output riscv::pmpcfg_t [15:0] pmpcfg_o,
// PMP configuration containing pmpcfg for max 64 PMPs - ACC_DISPATCHER
output riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_o,
// PMP addresses - ACC_DISPATCHER
output logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_o,
output logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_o,
// TO_BE_COMPLETED - PERF_COUNTERS
output logic [31:0] mcountinhibit_o,
// RVFI
Expand Down Expand Up @@ -274,10 +274,9 @@ module csr_regfile
logic [63:0] cycle_q, cycle_d;
logic [63:0] instret_q, instret_d;

riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d, pmpcfg_next;
logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_q, pmpaddr_d, pmpaddr_next;
riscv::pmpcfg_t [63:0] pmpcfg_q, pmpcfg_d, pmpcfg_next;
logic [63:0][CVA6Cfg.PLEN-3:0] pmpaddr_q, pmpaddr_d, pmpaddr_next;
logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q;
logic [3:0] index;

localparam logic [CVA6Cfg.XLEN-1:0] IsaCode = (CVA6Cfg.XLEN'(CVA6Cfg.RVA) << 0) // A - Atomic Instructions extension
| (CVA6Cfg.XLEN'(CVA6Cfg.RVB) << 1) // B - Bitmanip extension
Expand All @@ -294,8 +293,8 @@ module csr_regfile
| (CVA6Cfg.XLEN'(CVA6Cfg.NSX) << 23) // X - Non-standard extensions present
| ((CVA6Cfg.XLEN == 64 ? 2 : 1) << CVA6Cfg.XLEN - 2); // MXL

assign pmpcfg_o = pmpcfg_q[15:0];
assign pmpaddr_o = pmpaddr_q;
assign pmpcfg_o = pmpcfg_q[CVA6Cfg.NrPMPEntries:0];
assign pmpaddr_o = pmpaddr_q[CVA6Cfg.NrPMPEntries:0];

riscv::fcsr_t fcsr_q, fcsr_d;
// ----------------
Expand Down Expand Up @@ -329,7 +328,6 @@ module csr_regfile
virtual_read_access_exception = 1'b0;
csr_rdata = '0;
perf_addr_o = csr_addr.address[11:0];
index = '0;

if (csr_read) begin
unique case (conv_csr_addr.address)
Expand Down Expand Up @@ -762,14 +760,31 @@ module csr_regfile
end
end
// PMPs
riscv::CSR_PMPCFG0: csr_rdata = pmpcfg_q[CVA6Cfg.XLEN/8-1:0];
riscv::CSR_PMPCFG1:
if (CVA6Cfg.XLEN == 32) csr_rdata = pmpcfg_q[7:4];
else read_access_exception = 1'b1;
riscv::CSR_PMPCFG2: csr_rdata = pmpcfg_q[8+:CVA6Cfg.XLEN/8];
riscv::CSR_PMPCFG3:
if (CVA6Cfg.XLEN == 32) csr_rdata = pmpcfg_q[15:12];
else read_access_exception = 1'b1;
riscv::CSR_PMPCFG0,
riscv::CSR_PMPCFG1,
riscv::CSR_PMPCFG2,
riscv::CSR_PMPCFG3,
riscv::CSR_PMPCFG4,
riscv::CSR_PMPCFG5,
riscv::CSR_PMPCFG6,
riscv::CSR_PMPCFG7,
riscv::CSR_PMPCFG8,
riscv::CSR_PMPCFG9,
riscv::CSR_PMPCFG10,
riscv::CSR_PMPCFG11,
riscv::CSR_PMPCFG12,
riscv::CSR_PMPCFG13,
riscv::CSR_PMPCFG14,
riscv::CSR_PMPCFG15: begin
// index is calculated using PMPCFG0 as the offset
automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0;

// if index is not even and XLEN==64, raise exception
if (CVA6Cfg.XLEN == 64 && index[0] == 1'b1) read_access_exception = 1'b1;
else begin
csr_rdata = pmpcfg_q[index*4+:CVA6Cfg.XLEN/8];
end
end
// PMPADDR
riscv::CSR_PMPADDR0,
riscv::CSR_PMPADDR1,
Expand All @@ -786,9 +801,57 @@ module csr_regfile
riscv::CSR_PMPADDR12,
riscv::CSR_PMPADDR13,
riscv::CSR_PMPADDR14,
riscv::CSR_PMPADDR15: begin
// index is specified by the last byte in the address
index = csr_addr.csr_decode.address[3:0];
riscv::CSR_PMPADDR15,
riscv::CSR_PMPADDR16,
riscv::CSR_PMPADDR17,
riscv::CSR_PMPADDR18,
riscv::CSR_PMPADDR19,
riscv::CSR_PMPADDR20,
riscv::CSR_PMPADDR21,
riscv::CSR_PMPADDR22,
riscv::CSR_PMPADDR23,
riscv::CSR_PMPADDR24,
riscv::CSR_PMPADDR25,
riscv::CSR_PMPADDR26,
riscv::CSR_PMPADDR27,
riscv::CSR_PMPADDR28,
riscv::CSR_PMPADDR29,
riscv::CSR_PMPADDR30,
riscv::CSR_PMPADDR31,
riscv::CSR_PMPADDR32,
riscv::CSR_PMPADDR33,
riscv::CSR_PMPADDR34,
riscv::CSR_PMPADDR35,
riscv::CSR_PMPADDR36,
riscv::CSR_PMPADDR37,
riscv::CSR_PMPADDR38,
riscv::CSR_PMPADDR39,
riscv::CSR_PMPADDR40,
riscv::CSR_PMPADDR41,
riscv::CSR_PMPADDR42,
riscv::CSR_PMPADDR43,
riscv::CSR_PMPADDR44,
riscv::CSR_PMPADDR45,
riscv::CSR_PMPADDR46,
riscv::CSR_PMPADDR47,
riscv::CSR_PMPADDR48,
riscv::CSR_PMPADDR49,
riscv::CSR_PMPADDR50,
riscv::CSR_PMPADDR51,
riscv::CSR_PMPADDR52,
riscv::CSR_PMPADDR53,
riscv::CSR_PMPADDR54,
riscv::CSR_PMPADDR55,
riscv::CSR_PMPADDR56,
riscv::CSR_PMPADDR57,
riscv::CSR_PMPADDR58,
riscv::CSR_PMPADDR59,
riscv::CSR_PMPADDR60,
riscv::CSR_PMPADDR61,
riscv::CSR_PMPADDR62,
riscv::CSR_PMPADDR63: begin
// index is calculated using PMPADDR0 as the offset
automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPADDR0;
// Important: we only support granularity 8 bytes (G=1)
// -> last bit of pmpaddr must be set 0/1 based on the mode:
// NA4, NAPOT: 1
Expand Down Expand Up @@ -1555,26 +1618,31 @@ module csr_regfile
// 1. refuse to update any locked entry
// 2. also refuse to update the entry below a locked TOR entry
// Note that writes to pmpcfg below a locked TOR entry are valid
riscv::CSR_PMPCFG0:
for (int i = 0; i < (CVA6Cfg.XLEN / 8); i++)
if (!pmpcfg_q[i].locked) pmpcfg_d[i] = csr_wdata[i*8+:8];
riscv::CSR_PMPCFG1: begin
if (CVA6Cfg.XLEN == 32) begin
for (int i = 0; i < 4; i++)
if (!pmpcfg_q[i+4].locked) pmpcfg_d[i+4] = csr_wdata[i*8+:8];
end else begin
update_access_exception = 1'b1;
end
end
riscv::CSR_PMPCFG2:
for (int i = 0; i < (CVA6Cfg.XLEN / 8); i++)
if (!pmpcfg_q[i+8].locked) pmpcfg_d[i+8] = csr_wdata[i*8+:8];
riscv::CSR_PMPCFG3: begin
if (CVA6Cfg.XLEN == 32) begin
for (int i = 0; i < 4; i++)
if (!pmpcfg_q[i+12].locked) pmpcfg_d[i+12] = csr_wdata[i*8+:8];
end else begin
update_access_exception = 1'b1;
riscv::CSR_PMPCFG0,
riscv::CSR_PMPCFG1,
riscv::CSR_PMPCFG2,
riscv::CSR_PMPCFG3,
riscv::CSR_PMPCFG4,
riscv::CSR_PMPCFG5,
riscv::CSR_PMPCFG6,
riscv::CSR_PMPCFG7,
riscv::CSR_PMPCFG8,
riscv::CSR_PMPCFG9,
riscv::CSR_PMPCFG10,
riscv::CSR_PMPCFG11,
riscv::CSR_PMPCFG12,
riscv::CSR_PMPCFG13,
riscv::CSR_PMPCFG14,
riscv::CSR_PMPCFG15: begin
// index is calculated using PMPCFG0 as the offset
automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0;

// if index is not even and XLEN==64, raise exception
if (CVA6Cfg.XLEN == 64 && index[0] == 1'b1) update_access_exception = 1'b1;
else begin
for (int i = 0; i < CVA6Cfg.XLEN / 8; i++) begin
if (!pmpcfg_q[index+i].locked) pmpcfg_d[index+i] = csr_wdata[i*8+:8];
end
end
end
riscv::CSR_PMPADDR0,
Expand All @@ -1592,9 +1660,57 @@ module csr_regfile
riscv::CSR_PMPADDR12,
riscv::CSR_PMPADDR13,
riscv::CSR_PMPADDR14,
riscv::CSR_PMPADDR15: begin
// index is specified by the last byte in the address
automatic logic [3:0] index = csr_addr.csr_decode.address[3:0];
riscv::CSR_PMPADDR15,
riscv::CSR_PMPADDR16,
riscv::CSR_PMPADDR17,
riscv::CSR_PMPADDR18,
riscv::CSR_PMPADDR19,
riscv::CSR_PMPADDR20,
riscv::CSR_PMPADDR21,
riscv::CSR_PMPADDR22,
riscv::CSR_PMPADDR23,
riscv::CSR_PMPADDR24,
riscv::CSR_PMPADDR25,
riscv::CSR_PMPADDR26,
riscv::CSR_PMPADDR27,
riscv::CSR_PMPADDR28,
riscv::CSR_PMPADDR29,
riscv::CSR_PMPADDR30,
riscv::CSR_PMPADDR31,
riscv::CSR_PMPADDR32,
riscv::CSR_PMPADDR33,
riscv::CSR_PMPADDR34,
riscv::CSR_PMPADDR35,
riscv::CSR_PMPADDR36,
riscv::CSR_PMPADDR37,
riscv::CSR_PMPADDR38,
riscv::CSR_PMPADDR39,
riscv::CSR_PMPADDR40,
riscv::CSR_PMPADDR41,
riscv::CSR_PMPADDR42,
riscv::CSR_PMPADDR43,
riscv::CSR_PMPADDR44,
riscv::CSR_PMPADDR45,
riscv::CSR_PMPADDR46,
riscv::CSR_PMPADDR47,
riscv::CSR_PMPADDR48,
riscv::CSR_PMPADDR49,
riscv::CSR_PMPADDR50,
riscv::CSR_PMPADDR51,
riscv::CSR_PMPADDR52,
riscv::CSR_PMPADDR53,
riscv::CSR_PMPADDR54,
riscv::CSR_PMPADDR55,
riscv::CSR_PMPADDR56,
riscv::CSR_PMPADDR57,
riscv::CSR_PMPADDR58,
riscv::CSR_PMPADDR59,
riscv::CSR_PMPADDR60,
riscv::CSR_PMPADDR61,
riscv::CSR_PMPADDR62,
riscv::CSR_PMPADDR63: begin
// index is calculated using PMPADDR0 as the offset
automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPADDR0;
// check if the entry or the entry above is locked
if (!pmpcfg_q[index].locked && !(pmpcfg_q[index+1].locked && pmpcfg_q[index+1].addr_mode == riscv::TOR)) begin
pmpaddr_d[index] = csr_wdata[CVA6Cfg.PLEN-3:0];
Expand Down Expand Up @@ -2448,7 +2564,7 @@ module csr_regfile
// wait for interrupt
wfi_q <= 1'b0;
// pmp
for (int i = 0; i < 16; i++) begin
for (int i = 0; i < 64; i++) begin
if (i < CVA6Cfg.NrPMPEntries) begin
pmpcfg_q[i] <= riscv::pmpcfg_t'(CVA6Cfg.PMPCfgRstVal[i]);
pmpaddr_q[i] <= CVA6Cfg.PMPAddrRstVal[i][CVA6Cfg.PLEN-3:0];
Expand Down Expand Up @@ -2535,7 +2651,7 @@ module csr_regfile

// write logic pmp
always_comb begin : write
for (int i = 0; i < 16; i++) begin
for (int i = 0; i < 64; i++) begin
if (i < CVA6Cfg.NrPMPEntries) begin
if (!CVA6Cfg.PMPEntryReadOnly[i]) begin
// PMP locked logic is handled in the CSR write process above
Expand Down
4 changes: 2 additions & 2 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,8 @@ module cva6
logic acc_cons_en_csr;
logic debug_mode;
logic single_step_csr_commit;
riscv::pmpcfg_t [15:0] pmpcfg;
logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr;
riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg;
logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr;
logic [31:0] mcountinhibit_csr_perf;
// ----------------------------
// Performance Counters <-> *
Expand Down
13 changes: 7 additions & 6 deletions core/cva6_mmu/cva6_mmu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,15 @@ module cva6_mmu
input logic flush_tlb_gvma_i,

// Performance counters
output logic itlb_miss_o,
output logic dtlb_miss_o,
output logic itlb_miss_o,
output logic dtlb_miss_o,
// PTW memory interface
input dcache_req_o_t req_port_i,
output dcache_req_i_t req_port_o,
input dcache_req_o_t req_port_i,
output dcache_req_i_t req_port_o,

// PMP
input riscv::pmpcfg_t [15:0] pmpcfg_i,
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i
);

// memory management, pte for cva6
Expand Down
4 changes: 2 additions & 2 deletions core/cva6_mmu/cva6_ptw.sv
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ module cva6_ptw

// PMP

input riscv::pmpcfg_t [15:0] pmpcfg_i,
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i,
input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
output logic [CVA6Cfg.PLEN-1:0] bad_paddr_o,
output logic [CVA6Cfg.GPLEN-1:0] bad_gpaddr_o

Expand Down
4 changes: 2 additions & 2 deletions core/ex_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ module ex_stage
// To count the data TLB misses - PERF_COUNTERS
output logic dtlb_miss_o,
// Report the PMP configuration - CSR_REGFILE
input riscv::pmpcfg_t [15:0] pmpcfg_i,
input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i,
// Report the PMP addresses - CSR_REGFILE
input logic [15:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
// Information dedicated to RVFI - RVFI
output lsu_ctrl_t rvfi_lsu_ctrl_o,
// Information dedicated to RVFI - RVFI
Expand Down
14 changes: 7 additions & 7 deletions core/include/config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ package config_pkg;
// PMP entries number
int unsigned NrPMPEntries;
// PMP CSR configuration reset values
logic [15:0][63:0] PMPCfgRstVal;
logic [63:0][63:0] PMPCfgRstVal;
// PMP CSR address reset values
logic [15:0][63:0] PMPAddrRstVal;
logic [63:0][63:0] PMPAddrRstVal;
// PMP CSR read-only bits
bit [15:0] PMPEntryReadOnly;
bit [63:0] PMPEntryReadOnly;
// PMA non idempotent rules number
int unsigned NrNonIdempotentRules;
// PMA NonIdempotent region base address
Expand Down Expand Up @@ -277,9 +277,9 @@ package config_pkg;
bit TvalEn;
bit DirectVecOnly;
int unsigned NrPMPEntries;
logic [15:0][63:0] PMPCfgRstVal;
logic [15:0][63:0] PMPAddrRstVal;
bit [15:0] PMPEntryReadOnly;
logic [63:0][63:0] PMPCfgRstVal;
logic [63:0][63:0] PMPAddrRstVal;
bit [63:0] PMPEntryReadOnly;
noc_type_e NOCType;
int unsigned NrNonIdempotentRules;
logic [NrMaxRules-1:0][63:0] NonIdempotentAddrBase;
Expand Down Expand Up @@ -351,7 +351,7 @@ package config_pkg;
assert (Cfg.NrNonIdempotentRules <= NrMaxRules);
assert (Cfg.NrExecuteRegionRules <= NrMaxRules);
assert (Cfg.NrCachedRegionRules <= NrMaxRules);
assert (Cfg.NrPMPEntries <= 16);
assert (Cfg.NrPMPEntries <= 64);
`endif
// pragma translate_on
endfunction
Expand Down
Loading

0 comments on commit 246961b

Please sign in to comment.