diff --git a/core/cva6.sv b/core/cva6.sv index 4502b60b0f..f4543a8490 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -560,8 +560,8 @@ module cva6 logic acc_cons_en_csr; logic debug_mode; logic single_step_csr_commit; - riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg; - logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr; + riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg; + logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr; logic [31:0] mcountinhibit_csr_perf; // ---------------------------- // Performance Counters <-> * diff --git a/core/cva6_mmu/cva6_ptw.sv b/core/cva6_mmu/cva6_ptw.sv index c4713701dd..0700891db0 100644 --- a/core/cva6_mmu/cva6_ptw.sv +++ b/core/cva6_mmu/cva6_ptw.sv @@ -230,10 +230,7 @@ module cva6_ptw pmp #( - .CVA6Cfg (CVA6Cfg), - .PLEN (CVA6Cfg.PLEN), - .PMP_LEN (CVA6Cfg.PLEN - 2), - .NR_ENTRIES(CVA6Cfg.NrPMPEntries) + .CVA6Cfg(CVA6Cfg) ) i_pmp_ptw ( .addr_i (ptw_pptr_q), // PTW access are always checked as if in S-Mode... diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 115c17f1c5..3095a2c736 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -222,9 +222,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 [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, // Report the PMP addresses - CSR_REGFILE - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):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 diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 134b6a3dc1..1fcf4a751e 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -148,9 +148,9 @@ module load_store_unit input amo_resp_t amo_resp_i, // PMP configuration - CSR_REGFILE - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, // PMP address - CSR_REGFILE - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i, // RVFI inforamtion - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, diff --git a/core/pmp/src/pmp.sv b/core/pmp/src/pmp.sv index 1d2cf02651..f3498711ed 100644 --- a/core/pmp/src/pmp.sv +++ b/core/pmp/src/pmp.sv @@ -13,34 +13,29 @@ // Description: purely combinatorial PMP unit (with extraction for more complex configs such as NAPOT) module pmp #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter int unsigned PLEN = 34, // rv64: 56 - parameter int unsigned PMP_LEN = 32, // rv64: 54 - parameter int unsigned NR_ENTRIES = 4 + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( // Input - input logic [PLEN-1:0] addr_i, + input logic [CVA6Cfg.PLEN-1:0] addr_i, input riscv::pmp_access_t access_type_i, input riscv::priv_lvl_t priv_lvl_i, // Configuration - input logic [NR_ENTRIES-1:0][PMP_LEN-1:0] conf_addr_i, - input riscv::pmpcfg_t [NR_ENTRIES-1:0] conf_i, + input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] conf_addr_i, + input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] conf_i, // Output output logic allow_o ); // if there are no PMPs we can always grant the access. - if (NR_ENTRIES > 0) begin : gen_pmp - logic [NR_ENTRIES-1:0] match; + if (CVA6Cfg.NrPMPEntries > 0) begin : gen_pmp + logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] match; - for (genvar i = 0; i < NR_ENTRIES; i++) begin - logic [PMP_LEN-1:0] conf_addr_prev; + for (genvar i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin + logic [CVA6Cfg.PLEN-3:0] conf_addr_prev; assign conf_addr_prev = (i == 0) ? '0 : conf_addr_i[i-1]; pmp_entry #( - .CVA6Cfg(CVA6Cfg), - .PLEN (PLEN), - .PMP_LEN(PMP_LEN) + .CVA6Cfg(CVA6Cfg) ) i_pmp_entry ( .addr_i (addr_i), .conf_addr_i (conf_addr_i[i]), @@ -54,7 +49,7 @@ module pmp #( int i; allow_o = 1'b0; - for (i = 0; i < NR_ENTRIES; i++) begin + for (i = 0; i < CVA6Cfg.NrPMPEntries; i++) begin // either we are in S or U mode or the config is locked in which // case it also applies in M mode if (priv_lvl_i != riscv::PRIV_LVL_M || conf_i[i].locked) begin @@ -65,7 +60,7 @@ module pmp #( end end end - if (i == NR_ENTRIES) begin // no PMP entry matched the address + if (i == CVA6Cfg.NrPMPEntries) begin // no PMP entry matched the address // allow all accesses from M-mode for no pmp match if (priv_lvl_i == riscv::PRIV_LVL_M) allow_o = 1'b1; // disallow accesses for all other modes diff --git a/core/pmp/src/pmp_data_if.sv b/core/pmp/src/pmp_data_if.sv index 2e6c03a11f..d18149fb29 100644 --- a/core/pmp/src/pmp_data_if.sv +++ b/core/pmp/src/pmp_data_if.sv @@ -36,8 +36,8 @@ module pmp_data_if input riscv::priv_lvl_t ld_st_priv_lvl_i, input logic ld_st_v_i, // PMP - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i + input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i, + input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); // virtual address causing the exception logic [CVA6Cfg.XLEN-1:0] fetch_vaddr_xlen, lsu_vaddr_xlen; @@ -96,10 +96,7 @@ module pmp_data_if // Instruction fetch pmp #( - .CVA6Cfg (CVA6Cfg), - .PLEN (CVA6Cfg.PLEN), - .PMP_LEN (CVA6Cfg.PLEN - 2), - .NR_ENTRIES(CVA6Cfg.NrPMPEntries) + .CVA6Cfg(CVA6Cfg) ) i_pmp_if ( .addr_i (icache_areq_i.fetch_paddr), .priv_lvl_i (priv_lvl_i), @@ -144,10 +141,7 @@ module pmp_data_if // Load/store PMP check pmp #( - .CVA6Cfg (CVA6Cfg), - .PLEN (CVA6Cfg.PLEN), - .PMP_LEN (CVA6Cfg.PLEN - 2), - .NR_ENTRIES(CVA6Cfg.NrPMPEntries) + .CVA6Cfg(CVA6Cfg) ) i_pmp_data ( .addr_i (lsu_paddr_i), .priv_lvl_i (ld_st_priv_lvl_i), diff --git a/core/pmp/src/pmp_entry.sv b/core/pmp/src/pmp_entry.sv index 68e3c5a49a..8ae956b28f 100644 --- a/core/pmp/src/pmp_entry.sv +++ b/core/pmp/src/pmp_entry.sv @@ -18,24 +18,24 @@ module pmp_entry #( parameter int unsigned PMP_LEN = 54 ) ( // Input - input logic [PLEN-1:0] addr_i, + input logic [CVA6Cfg.PLEN-1:0] addr_i, // Configuration - input logic [PMP_LEN-1:0] conf_addr_i, - input logic [PMP_LEN-1:0] conf_addr_prev_i, + input logic [CVA6Cfg.PLEN-3:0] conf_addr_i, + input logic [CVA6Cfg.PLEN-3:0] conf_addr_prev_i, input riscv::pmp_addr_mode_t conf_addr_mode_i, // Output output logic match_o ); - logic [PLEN-1:0] conf_addr_n; - logic [$clog2(PLEN)-1:0] trail_ones; - logic [PLEN-1:0] base; - logic [PLEN-1:0] mask; + logic [CVA6Cfg.PLEN-1:0] conf_addr_n; + logic [$clog2(CVA6Cfg.PLEN)-1:0] trail_ones; + logic [CVA6Cfg.PLEN-1:0] base; + logic [CVA6Cfg.PLEN-1:0] mask; int unsigned size; assign conf_addr_n = {2'b11, ~conf_addr_i}; lzc #( - .WIDTH(PLEN), + .WIDTH(CVA6Cfg.PLEN), .MODE (1'b0) ) i_lzc ( .in_i (conf_addr_n), @@ -67,7 +67,7 @@ module pmp_entry #( riscv::NAPOT: begin // use the extracted trailing ones - size = {{(32 - $clog2(PLEN)) {1'b0}}, trail_ones} + 3; + size = {{(32 - $clog2(CVA6Cfg.PLEN)) {1'b0}}, trail_ones} + 3; mask = '1 << size; base = ({2'b0, conf_addr_i} << 2) & mask; @@ -78,15 +78,15 @@ module pmp_entry #( assert (size >= 2); if (conf_addr_mode_i == riscv::NAPOT) begin assert (size > 2); - if (size < PMP_LEN) assert (conf_addr_i[size-3] == 0); - for (int i = 0; i < PMP_LEN; i++) begin + if (size < CVA6Cfg.PLEN-2) assert (conf_addr_i[size-3] == 0); + for (int i = 0; i < CVA6Cfg.PLEN-2; i++) begin if (size > 3 && i <= size - 4) begin assert (conf_addr_i[i] == 1); // check that all the rest are ones end end end - if (size < PLEN - 1) begin + if (size < CVA6Cfg.PLEN - 1) begin if (base + 2 ** size > base) begin // check for overflow if (match_o == 0) begin assert (addr_i >= base + 2 ** size || addr_i < base);