Allow disabling certain PMP modes (#808)

This commit is contained in:
stnolting 2024-02-16 07:19:48 +01:00 committed by GitHub
commit beab81e6b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 120 additions and 77 deletions

View file

@ -30,6 +30,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Link |
|:----:|:-------:|:--------|:----:|
| 16.02.2024 | 1.9.5.1 | :sparkles: add two new generics to exclude certain PMP modes from synthesis | [#808](https://github.com/stnolting/neorv32/pull/808) |
| 16.02.2024 | [**:rocket:1.9.5**](https://github.com/stnolting/neorv32/releases/tag/v1.9.5) | **New release** | |
| 15.02.2023 | 1.9.4.13 | allow the DMA to issue a FENCE operation | [#807](https://github.com/stnolting/neorv32/pull/807) |
| 14.02.2024 | 1.9.4.12 | :bug: close another illegal compressed instruction encoding loophole | [#806](https://github.com/stnolting/neorv32/pull/806) |

View file

@ -784,13 +784,19 @@ The NEORV32 PMP is fully compatible to the RISC-V Privileged Architecture Specif
**grant permissions to user mode**, which by default has none, and can **revoke permissions from M-mode**, which
by default has full permissions. The PMP is configured via the <<_machine_physical_memory_protection_csrs>>.
Several <<_processor_top_entity_generics>> are provided to fine-tune the CPU's PMP capabilities:
* `PMP_NUM_REGIONS` defines the number of implemented PMP region
* `PMP_MIN_GRANULARITY` defines the minimal granularity of each region
* `PMP_TOR_MODE_EN` controls the implementation of the top-of-region (TOR) mode
* `PMP_NAP_MODE_EN` controls the implementation of the naturally-aligned-power-of-two (NA4 and NAPOT) modes
.PMP Rules when in Debug Mode
[NOTE]
When in debug-mode all PMP rules are ignored making the debugger have maximum access rights.
[IMPORTANT]
Instruction fetches are also triggered when denied by a certain PMP rule. However, the fetched instruction(s)
will not be executed and will not change CPU core state to preserve memory access protection.
will not be executed and will not change CPU core state.
==== `Smcntrpmf` - ISA Extension

View file

@ -561,6 +561,11 @@ See section <<_pmp_isa_extension>> for more information.
| 7 | `PMPCFG_L` | r/w | **L**: Lock bit, prevents further write accesses, also enforces access rights in machine-mode, can only be cleared by CPU reset
|=======================
.Implemented Modes
[NOTE]
In order to reduce the CPU size certain PMP modes (`A` bits) can be excluded from synthesis.
Use the `PMP_TOR_MODE_EN` and `PMP_NAP_MODE_EN` <<_processor_top_entity_generics>> to control
implementation of the according modes.
{empty} +
[discrete]
@ -593,12 +598,6 @@ The `pmpaddr*` CSRs are used to configure the region's address boundaries.
| Description | Region address configuration. The two MSBs of each CSR are hardwired to zero (= bits 33:32 of the physical address).
|=======================
.Address Register Update Latency
[IMPORTANT]
After writing a `pmpaddr` CSR the hardware requires up to 32 clock cycles to compute the according
address masks. Make sure to wait for this time before completing the PMP region configuration
(only relevant for `NA4` and `NAPOT` modes).
<<<
// ####################################################################################################################

View file

@ -228,6 +228,8 @@ The generic type "`suv(x:y)`" is an abbreviation for "`std_ulogic_vector(x downt
4+^| **Physical Memory Protection (<<_pmp_isa_extension>>)**
| `PMP_NUM_REGIONS` | natural | 0 | Number of implemented PMP regions (0..16).
| `PMP_MIN_GRANULARITY` | natural | 4 | Minimal region granularity in bytes. Has to be a power of two, min 4.
| `PMP_TOR_MODE_EN` | boolean | true | Implement support for top-of-region (TOR) mode.
| `PMP_NAP_MODE_EN` | boolean | true | Implement support for naturally-aligned power-of-two (NAPOT & NA4) modes.
4+^| **Hardware Performance Monitors (<<_zihpm_isa_extension>>)**
| `HPM_NUM_CNTS` | natural | 0 | Number of implemented hardware performance monitor counters (0..13).
| `HPM_CNT_WIDTH` | natural | 40 | Total LSB-aligned size of each HPM counter. Min 0, max 64.

View file

@ -68,6 +68,8 @@ entity neorv32_cpu is
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural range 0 to 16; -- number of regions (0..16)
PMP_MIN_GRANULARITY : natural; -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
PMP_TOR_MODE_EN : boolean; -- implement TOR mode
PMP_NAP_MODE_EN : boolean; -- implement NAPOT/NA4 modes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural range 0 to 13; -- number of implemented HPM counters (0..13)
HPM_CNT_WIDTH : natural range 0 to 64 -- total size of HPM counters (0..64)
@ -101,7 +103,7 @@ architecture neorv32_cpu_rtl of neorv32_cpu is
constant regfile_rs4_en_c : boolean := CPU_EXTENSION_RISCV_Zxcfu; -- 4th register file read port (rs4)
constant pmp_enable_c : boolean := boolean(PMP_NUM_REGIONS > 0);
-- external CSR interface --
-- control-unit-external CSR interface --
signal xcsr_we : std_ulogic;
signal xcsr_addr : std_ulogic_vector(11 downto 0);
signal xcsr_wdata : std_ulogic_vector(XLEN-1 downto 0);
@ -358,8 +360,10 @@ begin
if pmp_enable_c generate
neorv32_cpu_pmp_inst: entity neorv32.neorv32_cpu_pmp
generic map (
NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..16)
GRANULARITY => PMP_MIN_GRANULARITY -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..16)
GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
TOR_EN => PMP_TOR_MODE_EN, -- implement TOR mode
NAP_EN => PMP_NAP_MODE_EN -- implement NAPOT/NA4 modes
)
port map (
-- global control --

View file

@ -1,6 +1,8 @@
-- #################################################################################################
-- # << NEORV32 CPU - Physical Memory Protection Unit >> #
-- # ********************************************************************************************* #
-- # Compatible to the RISC-V PMP privilege architecture specifications. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 #
@ -41,7 +43,9 @@ use neorv32.neorv32_package.all;
entity neorv32_cpu_pmp is
generic (
NUM_REGIONS : natural range 0 to 16; -- number of regions (0..16)
GRANULARITY : natural range 4 to natural'high -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
GRANULARITY : natural range 4 to natural'high; -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
TOR_EN : boolean; -- implement TOR mode
NAP_EN : boolean -- implement NAPOT/NA4 modes
);
port (
-- global control --
@ -112,25 +116,16 @@ architecture neorv32_cpu_pmp_rtl of neorv32_cpu_pmp is
type addr_mask_t is array (0 to NUM_REGIONS-1) of std_ulogic_vector(XLEN-1 downto pmp_lsb_c);
signal addr_mask_napot, addr_mask : addr_mask_t;
type region_t is record
i_cmp_mm : std_ulogic_vector(NUM_REGIONS-1 downto 0);
i_cmp_ge : std_ulogic_vector(NUM_REGIONS-1 downto 0);
i_cmp_lt : std_ulogic_vector(NUM_REGIONS-1 downto 0);
d_cmp_mm : std_ulogic_vector(NUM_REGIONS-1 downto 0);
d_cmp_ge : std_ulogic_vector(NUM_REGIONS-1 downto 0);
d_cmp_lt : std_ulogic_vector(NUM_REGIONS-1 downto 0);
i_match : std_ulogic_vector(NUM_REGIONS-1 downto 0);
d_match : std_ulogic_vector(NUM_REGIONS-1 downto 0);
perm_ex : std_ulogic_vector(NUM_REGIONS-1 downto 0);
perm_rw : std_ulogic_vector(NUM_REGIONS-1 downto 0);
i_cmp_mm, d_cmp_mm : std_ulogic_vector(NUM_REGIONS-1 downto 0); -- masked match
i_cmp_ge, d_cmp_ge : std_ulogic_vector(NUM_REGIONS-1 downto 0); -- greater or equal
i_cmp_lt, d_cmp_lt : std_ulogic_vector(NUM_REGIONS-1 downto 0); -- less than
i_match, d_match : std_ulogic_vector(NUM_REGIONS-1 downto 0); -- region address match
perm_ex, perm_rw : std_ulogic_vector(NUM_REGIONS-1 downto 0); -- region's permission
end record;
signal region : region_t;
-- permission check --
type check_t is record
fail_ex : std_ulogic_vector(NUM_REGIONS downto 0);
fail_rw : std_ulogic_vector(NUM_REGIONS downto 0);
end record;
signal check : check_t;
-- permission check violation --
signal fail_ex, fail_rw : std_ulogic_vector(NUM_REGIONS downto 0);
begin
@ -160,6 +155,7 @@ begin
csr_reg_gen:
for i in 0 to NUM_REGIONS-1 generate
csr_reg: process(rstn_i, clk_i)
variable mode_v : std_ulogic_vector(1 downto 0);
begin
if (rstn_i = '0') then
csr.cfg(i) <= (others => '0');
@ -171,11 +167,17 @@ begin
csr.cfg(i)(cfg_r_c) <= csr_wdata_i((i mod 4)*8+0); -- R (read)
csr.cfg(i)(cfg_w_c) <= csr_wdata_i((i mod 4)*8+1); -- W (write)
csr.cfg(i)(cfg_x_c) <= csr_wdata_i((i mod 4)*8+2); -- X (execute)
if (granularity_c > 4) and (csr_wdata_i((i mod 4)*8+4 downto (i mod 4)*8+3) = mode_na4_c) then
csr.cfg(i)(cfg_ah_c downto cfg_al_c) <= mode_off_c; -- NA4 not available, fall back to OFF
else
csr.cfg(i)(cfg_ah_c downto cfg_al_c) <= csr_wdata_i((i mod 4)*8+4 downto (i mod 4)*8+3); -- A (mode)
-- A (mode) --
mode_v := csr_wdata_i((i mod 4)*8+4 downto (i mod 4)*8+3);
if ((mode_v = mode_tor_c) and (TOR_EN = false)) or -- TOR mode not implemented
((mode_v = mode_na4_c) and (NAP_EN = false)) or -- NA4 mode not implemented
((mode_v = mode_napot_c) and (NAP_EN = false)) or -- NAPOT mode not implemented
((mode_v = mode_na4_c) and (granularity_c > 4)) then -- NA4 not available
csr.cfg(i)(cfg_ah_c downto cfg_al_c) <= mode_off_c;
else -- valid configuration
csr.cfg(i)(cfg_ah_c downto cfg_al_c) <= mode_v;
end if;
--
csr.cfg(i)(cfg_rl_c) <= '0'; -- reserved
csr.cfg(i)(cfg_rh_c) <= '0'; -- reserved
csr.cfg(i)(cfg_l_c) <= csr_wdata_i((i mod 4)*8+7); -- L (locked)
@ -222,14 +224,18 @@ begin
begin
addr_rd(i) <= (others => '0');
addr_rd(i)(XLEN-1 downto pmp_lsb_c-2) <= csr.addr(i)(XLEN-1 downto pmp_lsb_c-2);
if (granularity_c = 8) then -- bit G-1 reads as zero in TOR or OFF mode
if (granularity_c = 8) and TOR_EN then -- bit G-1 reads as zero in TOR or OFF mode
if (csr.cfg(i)(cfg_ah_c) = '0') then -- TOR/OFF mode
addr_rd(i)(pmp_lsb_c) <= '0';
end if;
elsif (granularity_c > 8) then
addr_rd(i)(pmp_lsb_c-2 downto 0) <= (others => '1'); -- in NAPOT mode bits G-2:0 must read as one
if (csr.cfg(i)(cfg_ah_c) = '0') then -- TOR/OFF mode
addr_rd(i)(pmp_lsb_c-1 downto 0) <= (others => '0'); -- in TOR or OFF mode bits G-1:0 must read as zero
if NAP_EN then
addr_rd(i)(pmp_lsb_c-2 downto 0) <= (others => '1'); -- in NAPOT mode bits G-2:0 must read as one
end if;
if TOR_EN then
if (csr.cfg(i)(cfg_ah_c) = '0') then -- TOR/OFF mode
addr_rd(i)(pmp_lsb_c-1 downto 0) <= (others => '0'); -- in TOR or OFF mode bits G-1:0 must read as zero
end if;
end if;
end if;
end process address_read_back;
@ -258,47 +264,52 @@ begin
xaddr(r) <= csr.addr(r) & "00"; -- mask byte offset
-- compute address masks for NAPOT mode --
addr_mask_napot(r)(pmp_lsb_c) <= '0';
addr_mask_napot_gen:
for i in pmp_lsb_c+1 to XLEN-1 generate
addr_mask_napot(r)(i) <= addr_mask_napot(r)(i-1) or (not xaddr(r)(i-1));
end generate;
nap_mode_enable:
if NAP_EN generate
-- address mask select --
addr_masking: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
addr_mask(r) <= (others => '0');
elsif rising_edge(clk_i) then
if (csr.cfg(r)(cfg_al_c) = '1') then -- NAPOT
addr_mask(r) <= addr_mask_napot(r);
else -- NA4
addr_mask(r) <= (others => '1');
-- compute address masks for NAPOT mode --
addr_mask_napot(r)(pmp_lsb_c) <= '0';
addr_mask_napot_gen:
for i in pmp_lsb_c+1 to XLEN-1 generate
addr_mask_napot(r)(i) <= addr_mask_napot(r)(i-1) or (not xaddr(r)(i-1));
end generate;
-- address mask select --
addr_masking: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
addr_mask(r) <= (others => '0');
elsif rising_edge(clk_i) then
if (csr.cfg(r)(cfg_al_c) = '1') then -- NAPOT
addr_mask(r) <= addr_mask_napot(r);
else -- NA4
addr_mask(r) <= (others => '1');
end if;
end if;
end if;
end process addr_masking;
end process addr_masking;
end generate;
-- check region address match --
-- NA4 and NAPOT --
region.i_cmp_mm(r) <= '1' when ((addr_if_i(XLEN-1 downto pmp_lsb_c) and addr_mask(r)) = (xaddr(r)(XLEN-1 downto pmp_lsb_c) and addr_mask(r))) else '0';
region.d_cmp_mm(r) <= '1' when ((addr_ls_i(XLEN-1 downto pmp_lsb_c) and addr_mask(r)) = (xaddr(r)(XLEN-1 downto pmp_lsb_c) and addr_mask(r))) else '0';
region.i_cmp_mm(r) <= '1' when ((addr_if_i(XLEN-1 downto pmp_lsb_c) and addr_mask(r)) = (xaddr(r)(XLEN-1 downto pmp_lsb_c) and addr_mask(r))) and NAP_EN else '0';
region.d_cmp_mm(r) <= '1' when ((addr_ls_i(XLEN-1 downto pmp_lsb_c) and addr_mask(r)) = (xaddr(r)(XLEN-1 downto pmp_lsb_c) and addr_mask(r))) and NAP_EN else '0';
-- TOR region 0 --
addr_match_r0_gen:
if (r = 0) generate -- first entry: use ZERO as base and current entry as bound
region.i_cmp_ge(r) <= '1'; -- address is always greater than or equal to zero
region.i_cmp_ge(r) <= '1' when TOR_EN else '0'; -- address is always greater than or equal to zero (and TOR mode enabled)
region.i_cmp_lt(r) <= '0'; -- unused
region.d_cmp_ge(r) <= '1'; -- address is always greater than or equal to zero
region.d_cmp_ge(r) <= '1' when TOR_EN else '0'; -- address is always greater than or equal to zero (and TOR mode enabled)
region.d_cmp_lt(r) <= '0'; -- unused
end generate;
-- TOR region any --
addr_match_rx_gen:
if (r > 0) generate -- use previous entry as base and current entry as bound
region.i_cmp_ge(r) <= '1' when (unsigned(addr_if_i(XLEN-1 downto pmp_lsb_c)) >= unsigned(xaddr(r-1)(XLEN-1 downto pmp_lsb_c))) else '0';
region.i_cmp_lt(r) <= '1' when (unsigned(addr_if_i(XLEN-1 downto pmp_lsb_c)) < unsigned(xaddr(r )(XLEN-1 downto pmp_lsb_c))) else '0';
region.d_cmp_ge(r) <= '1' when (unsigned(addr_ls_i(XLEN-1 downto pmp_lsb_c)) >= unsigned(xaddr(r-1)(XLEN-1 downto pmp_lsb_c))) else '0';
region.d_cmp_lt(r) <= '1' when (unsigned(addr_ls_i(XLEN-1 downto pmp_lsb_c)) < unsigned(xaddr(r )(XLEN-1 downto pmp_lsb_c))) else '0';
region.i_cmp_ge(r) <= '1' when (unsigned(addr_if_i(XLEN-1 downto pmp_lsb_c)) >= unsigned(xaddr(r-1)(XLEN-1 downto pmp_lsb_c))) and TOR_EN else '0';
region.i_cmp_lt(r) <= '1' when (unsigned(addr_if_i(XLEN-1 downto pmp_lsb_c)) < unsigned(xaddr(r )(XLEN-1 downto pmp_lsb_c))) and TOR_EN else '0';
region.d_cmp_ge(r) <= '1' when (unsigned(addr_ls_i(XLEN-1 downto pmp_lsb_c)) >= unsigned(xaddr(r-1)(XLEN-1 downto pmp_lsb_c))) and TOR_EN else '0';
region.d_cmp_lt(r) <= '1' when (unsigned(addr_ls_i(XLEN-1 downto pmp_lsb_c)) < unsigned(xaddr(r )(XLEN-1 downto pmp_lsb_c))) and TOR_EN else '0';
end generate;
@ -310,21 +321,31 @@ begin
region.i_match(r) <= '0';
region.d_match(r) <= '0';
when mode_tor_c => -- top of region
if (r = (NUM_REGIONS-1)) then -- very last entry
region.i_match(r) <= region.i_cmp_ge(r) and region.i_cmp_lt(r);
region.d_match(r) <= region.d_cmp_ge(r) and region.d_cmp_lt(r);
else -- this saves a LOT of comparators
region.i_match(r) <= region.i_cmp_ge(r) and (not region.i_cmp_ge(r+1));
region.d_match(r) <= region.d_cmp_ge(r) and (not region.d_cmp_ge(r+1));
if TOR_EN then -- TOR mode implemented?
if (r = (NUM_REGIONS-1)) then -- very last entry
region.i_match(r) <= region.i_cmp_ge(r) and region.i_cmp_lt(r);
region.d_match(r) <= region.d_cmp_ge(r) and region.d_cmp_lt(r);
else -- this saves a LOT of comparators
region.i_match(r) <= region.i_cmp_ge(r) and (not region.i_cmp_ge(r+1));
region.d_match(r) <= region.d_cmp_ge(r) and (not region.d_cmp_ge(r+1));
end if;
else
region.i_match(r) <= '0';
region.d_match(r) <= '0';
end if;
when others => -- naturally-aligned region
region.i_match(r) <= region.i_cmp_mm(r);
region.d_match(r) <= region.d_cmp_mm(r);
if NAP_EN then -- NAPOT/NA4 modes implemented?
region.i_match(r) <= region.i_cmp_mm(r);
region.d_match(r) <= region.d_cmp_mm(r);
else
region.i_match(r) <= '0';
region.d_match(r) <= '0';
end if;
end case;
end process match_gen;
-- compute region permission --
-- compute region permissions --
perm_gen: process(csr.cfg, ctrl_i)
begin
-- execute (X) --
@ -357,13 +378,13 @@ begin
-- -------------------------------------------------------------------------------------------
-- check for access fault (using static prioritization) --
check.fail_ex(NUM_REGIONS) <= '1' when (ctrl_i.cpu_priv /= priv_mode_m_c) else '0'; -- default (if not match): fault if not M-mode
check.fail_rw(NUM_REGIONS) <= '1' when (ctrl_i.lsu_priv /= priv_mode_m_c) else '0'; -- default (if not match): fault if not M-mode
fail_ex(NUM_REGIONS) <= '1' when (ctrl_i.cpu_priv /= priv_mode_m_c) else '0'; -- default (if not match): fault if not M-mode
fail_rw(NUM_REGIONS) <= '1' when (ctrl_i.lsu_priv /= priv_mode_m_c) else '0'; -- default (if not match): fault if not M-mode
-- this is a *structural* description of a prioritization logic implemented as a multiplexer chain --
fault_check_gen:
for r in NUM_REGIONS-1 downto 0 generate -- start with lowest priority
check.fail_ex(r) <= not region.perm_ex(r) when (region.i_match(r) = '1') else check.fail_ex(r+1);
check.fail_rw(r) <= not region.perm_rw(r) when (region.d_match(r) = '1') else check.fail_rw(r+1);
fail_ex(r) <= not region.perm_ex(r) when (region.i_match(r) = '1') else fail_ex(r+1);
fail_rw(r) <= not region.perm_rw(r) when (region.d_match(r) = '1') else fail_rw(r+1);
end generate;
@ -374,8 +395,8 @@ begin
fault_ex_o <= '0';
fault_rw_o <= '0';
elsif rising_edge(clk_i) then
fault_ex_o <= (not ctrl_i.cpu_debug) and check.fail_ex(0); -- ignore PMP rules when in debug mode
fault_rw_o <= (not ctrl_i.cpu_debug) and check.fail_rw(0);
fault_ex_o <= (not ctrl_i.cpu_debug) and fail_ex(0); -- ignore PMP rules when in debug mode
fault_rw_o <= (not ctrl_i.cpu_debug) and fail_rw(0);
end if;
end process access_check;

View file

@ -53,7 +53,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090500"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090501"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width
@ -776,6 +776,8 @@ package neorv32_package is
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural range 0 to 16 := 0;
PMP_MIN_GRANULARITY : natural := 4;
PMP_TOR_MODE_EN : boolean := true;
PMP_NAP_MODE_EN : boolean := true;
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural range 0 to 13 := 0;
HPM_CNT_WIDTH : natural range 0 to 64 := 40;

View file

@ -78,6 +78,8 @@ entity neorv32_top is
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural range 0 to 16 := 0; -- number of regions (0..16)
PMP_MIN_GRANULARITY : natural := 4; -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
PMP_TOR_MODE_EN : boolean := true; -- implement TOR mode
PMP_NAP_MODE_EN : boolean := true; -- implement NAPOT/NA4 modes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural range 0 to 13 := 0; -- number of implemented HPM counters (0..13)
@ -538,6 +540,8 @@ begin
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS,
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY,
PMP_TOR_MODE_EN => PMP_TOR_MODE_EN,
PMP_NAP_MODE_EN => PMP_NAP_MODE_EN,
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS,
HPM_CNT_WIDTH => HPM_CNT_WIDTH

View file

@ -245,6 +245,8 @@ begin
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => 5, -- number of regions (0..16)
PMP_MIN_GRANULARITY => 4, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
PMP_TOR_MODE_EN => true, -- implement TOR mode
PMP_NAP_MODE_EN => true, -- implement NAPOT/NA4 mode
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => 12, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => 40, -- total size of HPM counters (0..64)

View file

@ -188,6 +188,8 @@ begin
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => 5, -- number of regions (0..16)
PMP_MIN_GRANULARITY => 4, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
PMP_TOR_MODE_EN => true, -- implement TOR mode
PMP_NAP_MODE_EN => true, -- implement NAPOT/NA4 mode
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => 12, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => 40, -- total size of HPM counters (0..64)