Line 1... |
Line 1... |
-- #################################################################################################
|
-- #################################################################################################
|
-- # << NEORV32 - Bus Interface Unit >> #
|
-- # << NEORV32 - Bus Interface Unit >> #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # Instruction and data bus interfaces. #
|
-- # Instruction and data bus interfaces and physical memory protection (PMP). #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # BSD 3-Clause License #
|
-- # BSD 3-Clause License #
|
-- # #
|
-- # #
|
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
|
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
|
-- # #
|
-- # #
|
Line 46... |
Line 46... |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
|
BUS_TIMEOUT : natural := 15; -- cycles after which a valid bus access will timeout
|
BUS_TIMEOUT : natural := 15; -- cycles after which a valid bus access will timeout
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_USE : boolean := false; -- implement physical memory protection?
|
PMP_USE : boolean := false; -- implement physical memory protection?
|
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
|
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
|
PMP_GRANULARITY : natural := 16 -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
|
PMP_GRANULARITY : natural := 16 -- granularity (1=8B, 2=16B, 3=32B, ...)
|
);
|
);
|
port (
|
port (
|
-- global control --
|
-- global control --
|
clk_i : in std_ulogic; -- global clock, rising edge
|
clk_i : in std_ulogic; -- global clock, rising edge
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
Line 460... |
Line 460... |
|
|
-- check access type and regions's permissions --
|
-- check access type and regions's permissions --
|
pmp_check_permission: process(pmp, pmp_ctrl_i, priv_mode_i)
|
pmp_check_permission: process(pmp, pmp_ctrl_i, priv_mode_i)
|
begin
|
begin
|
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
|
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
|
if ((priv_mode_i = u_priv_mode_c) or (pmp_ctrl_i(r)(pmp_cfg_l_c) = '1')) and -- user privilege level or locked pmp entry - enforce permissions also for machine mode
|
if ((priv_mode_i = u_priv_mode_c) or (pmp_ctrl_i(r)(pmp_cfg_l_c) = '1')) and -- user privilege level or locked pmp entry -> enforce permissions also for machine mode
|
(pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) /= pmp_off_mode_c) then -- active entry
|
(pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) /= pmp_off_mode_c) then -- active entry
|
pmp.if_fault(r) <= pmp.i_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_x_c)); -- fetch access match no execute permission
|
pmp.if_fault(r) <= pmp.i_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_x_c)); -- fetch access match no execute permission
|
pmp.ld_fault(r) <= pmp.d_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_r_c)); -- load access match no read permission
|
pmp.ld_fault(r) <= pmp.d_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_r_c)); -- load access match no read permission
|
pmp.st_fault(r) <= pmp.d_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_w_c)); -- store access match no write permission
|
pmp.st_fault(r) <= pmp.d_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_w_c)); -- store access match no write permission
|
else
|
else
|