OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 15 to Rev 16
    Reverse comparison

Rev 15 → Rev 16

/neorv32/trunk/docs/NEORV32.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neorv32/trunk/rtl/core/neorv32_cpu.vhd
63,8 → 63,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Bus Interface --
BUS_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
);
137,7 → 137,6
 
-- pmp interface --
signal pmp_addr : pmp_addr_if_t;
signal pmp_maddr : pmp_addr_if_t;
signal pmp_ctrl : pmp_ctrl_if_t;
signal priv_mode : std_ulogic_vector(1 downto 0); -- current CPU privilege level
 
154,15 → 153,15
end if;
-- U-extension requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true) then
assert false report "NEORV32 CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr = true." severity error;
assert false report "NEORV32 CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true) then
assert false report "NEORV32 CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr = true." severity error;
assert false report "NEORV32 CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- performance counters requires Zicsr extension --
-- performance counters require Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CSR_COUNTERS_USE = true) then
assert false report "NEORV32 CONFIG ERROR! Performance counter CSRs require CPU_EXTENSION_RISCV_Zicsr = true." severity error;
assert false report "NEORV32 CONFIG ERROR! Performance counter CSRs require CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP regions --
if (PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true) then
169,8 → 168,8
assert false report "NEORV32 CONFIG ERROR! Number of PMP regions out of valid range." severity error;
end if;
-- PMP granulartiy --
if ((PMP_GRANULARITY <= 1) or (PMP_GRANULARITY > 31)) and (PMP_USE = true) then
assert false report "NEORV32 CONFIG ERROR! Invalid PMP grnaulartiy (1 < G < 32)." severity error;
if ((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true) then
assert false report "NEORV32 CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
end if;
end if;
end process sanity_check;
226,7 → 225,6
time_i => time_i, -- current system time
-- physical memory protection --
pmp_addr_o => pmp_addr, -- addresses
pmp_maddr_i => pmp_maddr, -- masked addresses
pmp_ctrl_o => pmp_ctrl, -- configs
priv_mode_o => priv_mode, -- current CPU privilege level
-- bus access exceptions --
360,7 → 358,6
be_store_o => be_store, -- bus error on store data access
-- physical memory protection --
pmp_addr_i => pmp_addr, -- addresses
pmp_maddr_o => pmp_maddr, -- masked addresses
pmp_ctrl_i => pmp_ctrl, -- configs
priv_mode_i => priv_mode, -- current CPU privilege level
-- instruction bus --
/neorv32/trunk/rtl/core/neorv32_cpu_bus.vhd
75,7 → 75,6
be_store_o : out std_ulogic; -- bus error on store data access
-- physical memory protection --
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_maddr_o : out pmp_addr_if_t; -- masked addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
priv_mode_i : in std_ulogic_vector(1 downto 0); -- current CPU privilege level
-- instruction bus --
142,14 → 141,17
 
-- physical memory protection --
type pmp_addr34_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c+1 downto 0);
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
type pmp_t is record
addr_mask : pmp_addr34_t; -- 34-bit
i_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for instruction interface
d_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for data interface
if_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for fetch operation
ld_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load operation
st_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
addr_mask : pmp_addr34_t; -- 34-bit physical address
region_base : pmp_addr_t; -- masked region base address for comparator
region_i_addr : pmp_addr_t; -- masked instruction access base address for comparator
region_d_addr : pmp_addr_t; -- masked data access base address for comparator
i_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for instruction interface
d_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for data interface
if_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for fetch operation
ld_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load operation
st_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
end record;
signal pmp : pmp_t;
 
411,24 → 413,15
-- Physical Memory Protection (PMP) -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- compute address masks --
pmp_masks: process(pmp_addr_i, pmp, pmp_ctrl_i)
pmp_masks: process(pmp_addr_i)
begin
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
pmp.addr_mask(r) <= (others => '0'); -- default
for i in PMP_GRANULARITY+2 to 33 loop
if (i = PMP_GRANULARITY+2) then
if (pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) = pmp_napot_mode_c) then
pmp.addr_mask(r)(i) <= '0';
else -- OFF or unsupported mode
pmp.addr_mask(r)(i) <= '1'; -- required for SW to check min granularity when entry is disabled
end if;
else
if (pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) = pmp_napot_mode_c) then
-- current bit = not AND(all previous bits)
pmp.addr_mask(r)(i) <= not and_all_f(pmp_addr_i(r)(i-1 downto PMP_GRANULARITY+2));
else -- OFF or unsupported mode
pmp.addr_mask(r)(i) <= '1'; -- required for SW to check min granularity when entry is disabled
end if;
for i in PMP_GRANULARITY+1 to 33 loop
if (i = PMP_GRANULARITY+1) then
pmp.addr_mask(r)(i) <= '0';
else -- current bit = not AND(all previous bits)
pmp.addr_mask(r)(i) <= not (and_all_f(pmp_addr_i(r)(i-1 downto PMP_GRANULARITY)));
end if;
end loop; -- i
end loop; -- r
435,37 → 428,29
end process pmp_masks;
 
 
-- masked pmpaddr output for CSR read-back --
pmp_masked_output: process(pmp_addr_i, pmp)
begin
pmp_maddr_o <= (others => (others => '0'));
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
pmp_maddr_o(r) <= pmp_addr_i(r) and pmp.addr_mask(r);
end loop; -- r
end process pmp_masked_output;
-- compute operands for comparator --
pmp_prepare_check:
for r in 0 to PMP_NUM_REGIONS-1 generate -- iterate over all regions
-- ignore lowest 3 bits of access addresses -> minimal region size = 8 bytes
pmp.region_i_addr(r) <= (fetch_pc_i(31 downto 3) & "000") and pmp.addr_mask(r)(33 downto 2);
pmp.region_d_addr(r) <= (mar(31 downto 3) & "000") and pmp.addr_mask(r)(33 downto 2);
pmp.region_base(r) <= pmp_addr_i(r)(33 downto 2) and pmp.addr_mask(r)(33 downto 2);
end generate; -- r
 
 
-- check for access address match --
pmp_addr_check: process (pmp, fetch_pc_i, mar, pmp_addr_i)
variable i_cmp_v : std_ulogic_vector(31 downto 0);
variable d_cmp_v : std_ulogic_vector(31 downto 0);
variable b_cmp_v : std_ulogic_vector(31 downto 0);
pmp_addr_check: process (pmp)
begin
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
b_cmp_v := pmp_addr_i(r)(33 downto 2) and pmp.addr_mask(r)(33 downto 2);
-- instruction interface --
i_cmp_v := fetch_pc_i and pmp.addr_mask(r)(33 downto 2);
if (i_cmp_v(31 downto PMP_GRANULARITY+2) = b_cmp_v(31 downto PMP_GRANULARITY+2)) then
pmp.i_match(r) <= '0';
if (pmp.region_i_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
pmp.i_match(r) <= '1';
else
pmp.i_match(r) <= '0';
end if;
-- data interface --
d_cmp_v := mar and pmp.addr_mask(r)(33 downto 2);
if (d_cmp_v(31 downto PMP_GRANULARITY+2) = b_cmp_v(31 downto PMP_GRANULARITY+2)) then
pmp.d_match(r) <= '0';
if (pmp.region_d_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
pmp.d_match(r) <= '1';
else
pmp.d_match(r) <= '0';
end if;
end loop; -- r
end process pmp_addr_check;
/neorv32/trunk/rtl/core/neorv32_cpu_control.vhd
92,7 → 92,6
time_i : in std_ulogic_vector(63 downto 0); -- current system time
-- physical memory protection --
pmp_addr_o : out pmp_addr_if_t; -- addresses
pmp_maddr_i : in pmp_addr_if_t; -- masked addresses
pmp_ctrl_o : out pmp_ctrl_if_t; -- configs
priv_mode_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
-- bus access exceptions --
1467,7 → 1466,6
csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
csr_rdata_o(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- U CPU extension
csr_rdata_o(23) <= '1'; -- X CPU extension (non-std extensions)
csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Z CPU extension
csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
when x"304" => -- R/W: mie - machine interrupt-enable register
1535,7 → 1533,7
 
when x"3b0" => -- R/W: pmpaddr0 - physical memory protection address register 0
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
csr_rdata_o <= pmp_maddr_i(0)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(0);
if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1544,7 → 1542,7
end if;
when x"3b1" => -- R/W: pmpaddr1 - physical memory protection address register 1
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 2) then
csr_rdata_o <= pmp_maddr_i(1)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(1);
if (csr.pmpcfg(1)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1553,7 → 1551,7
end if;
when x"3b2" => -- R/W: pmpaddr2 - physical memory protection address register 2
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 3) then
csr_rdata_o <= pmp_maddr_i(2)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(2);
if (csr.pmpcfg(2)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1562,7 → 1560,7
end if;
when x"3b3" => -- R/W: pmpaddr3 - physical memory protection address register 3
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 4) then
csr_rdata_o <= pmp_maddr_i(3)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(3);
if (csr.pmpcfg(3)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1571,7 → 1569,7
end if;
when x"3b4" => -- R/W: pmpaddr4 - physical memory protection address register 4
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 5) then
csr_rdata_o <= pmp_maddr_i(4)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(4);
if (csr.pmpcfg(4)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1580,7 → 1578,7
end if;
when x"3b5" => -- R/W: pmpaddr5 - physical memory protection address register 5
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 6) then
csr_rdata_o <= pmp_maddr_i(5)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(5);
if (csr.pmpcfg(5)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1589,7 → 1587,7
end if;
when x"3b6" => -- R/W: pmpaddr6 - physical memory protection address register 6
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 7) then
csr_rdata_o <= pmp_maddr_i(6)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(6);
if (csr.pmpcfg(6)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
1598,7 → 1596,7
end if;
when x"3b7" => -- R/W: pmpaddr7 - physical memory protection address register 7
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 8) then
csr_rdata_o <= pmp_maddr_i(7)(33 downto 2);
csr_rdata_o <= csr.pmpaddr(7);
if (csr.pmpcfg(7)(4 downto 3) = "00") then -- mode = off
csr_rdata_o(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
/neorv32/trunk/rtl/core/neorv32_package.vhd
41,7 → 41,7
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - FIXED!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030500"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030501"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions
 
-- Helper Functions -----------------------------------------------------------------------
401,8 → 401,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
485,8 → 485,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Bus Interface --
BUS_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
);
578,7 → 578,6
time_i : in std_ulogic_vector(63 downto 0); -- current system time
-- physical memory protection --
pmp_addr_o : out pmp_addr_if_t; -- addresses
pmp_maddr_i : in pmp_addr_if_t; -- masked addresses
pmp_ctrl_o : out pmp_ctrl_if_t; -- configs
priv_mode_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
-- bus access exceptions --
697,7 → 696,6
be_store_o : out std_ulogic; -- bus error on store data access
-- physical memory protection --
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_maddr_o : out pmp_addr_if_t; -- masked addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
priv_mode_i : in std_ulogic_vector(1 downto 0); -- current CPU privilege level
-- instruction bus --
/neorv32/trunk/rtl/core/neorv32_top.vhd
60,8 → 60,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
333,8 → 333,8
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 16)
PMP_GRANULARITY => PMP_GRANULARITY, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 8)
PMP_GRANULARITY => PMP_GRANULARITY, -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Bus Interface --
BUS_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after which a valid bus access will timeout
)
/neorv32/trunk/rtl/top_templates/neorv32_test_setup.vhd
83,7 → 83,7
-- Physical Memory Protection (PMP) --
PMP_USE => false, -- implement PMP?
PMP_NUM_REGIONS => 4, -- number of regions (max 16)
PMP_GRANULARITY => 15, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_GRANULARITY => 14, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE => x"00000000", -- base address of instruction memory space
MEM_ISPACE_SIZE => 16*1024, -- total size of instruction memory space in byte
/neorv32/trunk/sim/vivado/neorv32_tb_behav.wcfg
12,15 → 12,15
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1400827333fs"></ZoomStartTime>
<ZoomEndTime time="1401034534fs"></ZoomEndTime>
<Cursor1Time time="1400917733fs"></Cursor1Time>
<ZoomStartTime time="1233000084fs"></ZoomStartTime>
<ZoomEndTime time="1233509585fs"></ZoomEndTime>
<Cursor1Time time="1233085000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="178"></NameColumnWidth>
<ValueColumnWidth column_width="108"></ValueColumnWidth>
<NameColumnWidth column_width="203"></NameColumnWidth>
<ValueColumnWidth column_width="100"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="132" />
<WVObjectSize size="131" />
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.FETCH</obj_property>
<obj_property name="DisplayName">label</obj_property>
303,7 → 303,23
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr" type="array">
<obj_property name="ElementShortName">.pmpaddr[0:3][31:0]</obj_property>
<obj_property name="ObjectShortName">.pmpaddr[0:3][31:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[0]" type="array">
<obj_property name="ElementShortName">[0][31:0]</obj_property>
<obj_property name="ObjectShortName">[0][31:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[1]" type="array">
<obj_property name="ElementShortName">[1][31:0]</obj_property>
<obj_property name="ObjectShortName">[1][31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[2]" type="array">
<obj_property name="ElementShortName">[2][31:0]</obj_property>
<obj_property name="ObjectShortName">[2][31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr.pmpaddr[3]" type="array">
<obj_property name="ElementShortName">[3][31:0]</obj_property>
<obj_property name="ObjectShortName">[3][31:0]</obj_property>
</wvobject>
</wvobject>
</wvobject>
<wvobject type="divider" fp_name="divider139">
454,256 → 470,14
<obj_property name="ElementShortName">pmp</obj_property>
<obj_property name="ObjectShortName">pmp</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.addr_mask" type="array">
<obj_property name="ElementShortName">.addr_mask[0:3][33:0]</obj_property>
<obj_property name="ObjectShortName">.addr_mask[0:3][33:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.addr_mask[0]" type="array">
<obj_property name="ElementShortName">[0][33:0]</obj_property>
<obj_property name="ObjectShortName">[0][33:0]</obj_property>
<obj_property name="Radix">BINARYRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.addr_mask[1]" type="array">
<obj_property name="ElementShortName">[1][33:0]</obj_property>
<obj_property name="ObjectShortName">[1][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.addr_mask[2]" type="array">
<obj_property name="ElementShortName">[2][33:0]</obj_property>
<obj_property name="ObjectShortName">[2][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.addr_mask[3]" type="array">
<obj_property name="ElementShortName">[3][33:0]</obj_property>
<obj_property name="ObjectShortName">[3][33:0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.i_match" type="array">
<obj_property name="ElementShortName">.i_match[3:0]</obj_property>
<obj_property name="ObjectShortName">.i_match[3:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.d_match" type="array">
<obj_property name="ElementShortName">.d_match[3:0]</obj_property>
<obj_property name="ObjectShortName">.d_match[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.if_fault" type="array">
<obj_property name="ElementShortName">.if_fault[3:0]</obj_property>
<obj_property name="ObjectShortName">.if_fault[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.ld_fault" type="array">
<obj_property name="ElementShortName">.ld_fault[3:0]</obj_property>
<obj_property name="ObjectShortName">.ld_fault[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp.st_fault" type="array">
<obj_property name="ElementShortName">.st_fault[3:0]</obj_property>
<obj_property name="ObjectShortName">.st_fault[3:0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i" type="array">
<obj_property name="ElementShortName">pmp_addr_i[0:15][33:0]</obj_property>
<obj_property name="ObjectShortName">pmp_addr_i[0:15][33:0]</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[0]" type="array">
<obj_property name="ElementShortName">[0][33:0]</obj_property>
<obj_property name="ObjectShortName">[0][33:0]</obj_property>
<obj_property name="Radix">BINARYRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[1]" type="array">
<obj_property name="ElementShortName">[1][33:0]</obj_property>
<obj_property name="ObjectShortName">[1][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[2]" type="array">
<obj_property name="ElementShortName">[2][33:0]</obj_property>
<obj_property name="ObjectShortName">[2][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[3]" type="array">
<obj_property name="ElementShortName">[3][33:0]</obj_property>
<obj_property name="ObjectShortName">[3][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[4]" type="array">
<obj_property name="ElementShortName">[4][33:0]</obj_property>
<obj_property name="ObjectShortName">[4][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[5]" type="array">
<obj_property name="ElementShortName">[5][33:0]</obj_property>
<obj_property name="ObjectShortName">[5][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[6]" type="array">
<obj_property name="ElementShortName">[6][33:0]</obj_property>
<obj_property name="ObjectShortName">[6][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[7]" type="array">
<obj_property name="ElementShortName">[7][33:0]</obj_property>
<obj_property name="ObjectShortName">[7][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[8]" type="array">
<obj_property name="ElementShortName">[8][33:0]</obj_property>
<obj_property name="ObjectShortName">[8][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[9]" type="array">
<obj_property name="ElementShortName">[9][33:0]</obj_property>
<obj_property name="ObjectShortName">[9][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[10]" type="array">
<obj_property name="ElementShortName">[10][33:0]</obj_property>
<obj_property name="ObjectShortName">[10][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[11]" type="array">
<obj_property name="ElementShortName">[11][33:0]</obj_property>
<obj_property name="ObjectShortName">[11][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[12]" type="array">
<obj_property name="ElementShortName">[12][33:0]</obj_property>
<obj_property name="ObjectShortName">[12][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[13]" type="array">
<obj_property name="ElementShortName">[13][33:0]</obj_property>
<obj_property name="ObjectShortName">[13][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[14]" type="array">
<obj_property name="ElementShortName">[14][33:0]</obj_property>
<obj_property name="ObjectShortName">[14][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_addr_i[15]" type="array">
<obj_property name="ElementShortName">[15][33:0]</obj_property>
<obj_property name="ObjectShortName">[15][33:0]</obj_property>
</wvobject>
<obj_property name="ElementShortName">pmp_addr_i[0:7][33:0]</obj_property>
<obj_property name="ObjectShortName">pmp_addr_i[0:7][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o" type="array">
<obj_property name="ElementShortName">pmp_maddr_o[0:15][33:0]</obj_property>
<obj_property name="ObjectShortName">pmp_maddr_o[0:15][33:0]</obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[0]" type="array">
<obj_property name="ElementShortName">[0][33:0]</obj_property>
<obj_property name="ObjectShortName">[0][33:0]</obj_property>
<obj_property name="Radix">BINARYRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[1]" type="array">
<obj_property name="ElementShortName">[1][33:0]</obj_property>
<obj_property name="ObjectShortName">[1][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[2]" type="array">
<obj_property name="ElementShortName">[2][33:0]</obj_property>
<obj_property name="ObjectShortName">[2][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[3]" type="array">
<obj_property name="ElementShortName">[3][33:0]</obj_property>
<obj_property name="ObjectShortName">[3][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[4]" type="array">
<obj_property name="ElementShortName">[4][33:0]</obj_property>
<obj_property name="ObjectShortName">[4][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[5]" type="array">
<obj_property name="ElementShortName">[5][33:0]</obj_property>
<obj_property name="ObjectShortName">[5][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[6]" type="array">
<obj_property name="ElementShortName">[6][33:0]</obj_property>
<obj_property name="ObjectShortName">[6][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[7]" type="array">
<obj_property name="ElementShortName">[7][33:0]</obj_property>
<obj_property name="ObjectShortName">[7][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[8]" type="array">
<obj_property name="ElementShortName">[8][33:0]</obj_property>
<obj_property name="ObjectShortName">[8][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[9]" type="array">
<obj_property name="ElementShortName">[9][33:0]</obj_property>
<obj_property name="ObjectShortName">[9][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[10]" type="array">
<obj_property name="ElementShortName">[10][33:0]</obj_property>
<obj_property name="ObjectShortName">[10][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[11]" type="array">
<obj_property name="ElementShortName">[11][33:0]</obj_property>
<obj_property name="ObjectShortName">[11][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[12]" type="array">
<obj_property name="ElementShortName">[12][33:0]</obj_property>
<obj_property name="ObjectShortName">[12][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[13]" type="array">
<obj_property name="ElementShortName">[13][33:0]</obj_property>
<obj_property name="ObjectShortName">[13][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[14]" type="array">
<obj_property name="ElementShortName">[14][33:0]</obj_property>
<obj_property name="ObjectShortName">[14][33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_maddr_o[15]" type="array">
<obj_property name="ElementShortName">[15][33:0]</obj_property>
<obj_property name="ObjectShortName">[15][33:0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i" type="array">
<obj_property name="ElementShortName">pmp_ctrl_i[0:15][7:0]</obj_property>
<obj_property name="ObjectShortName">pmp_ctrl_i[0:15][7:0]</obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[0]" type="array">
<obj_property name="ElementShortName">[0][7:0]</obj_property>
<obj_property name="ObjectShortName">[0][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[1]" type="array">
<obj_property name="ElementShortName">[1][7:0]</obj_property>
<obj_property name="ObjectShortName">[1][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[2]" type="array">
<obj_property name="ElementShortName">[2][7:0]</obj_property>
<obj_property name="ObjectShortName">[2][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[3]" type="array">
<obj_property name="ElementShortName">[3][7:0]</obj_property>
<obj_property name="ObjectShortName">[3][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[4]" type="array">
<obj_property name="ElementShortName">[4][7:0]</obj_property>
<obj_property name="ObjectShortName">[4][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[5]" type="array">
<obj_property name="ElementShortName">[5][7:0]</obj_property>
<obj_property name="ObjectShortName">[5][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[6]" type="array">
<obj_property name="ElementShortName">[6][7:0]</obj_property>
<obj_property name="ObjectShortName">[6][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[7]" type="array">
<obj_property name="ElementShortName">[7][7:0]</obj_property>
<obj_property name="ObjectShortName">[7][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[8]" type="array">
<obj_property name="ElementShortName">[8][7:0]</obj_property>
<obj_property name="ObjectShortName">[8][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[9]" type="array">
<obj_property name="ElementShortName">[9][7:0]</obj_property>
<obj_property name="ObjectShortName">[9][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[10]" type="array">
<obj_property name="ElementShortName">[10][7:0]</obj_property>
<obj_property name="ObjectShortName">[10][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[11]" type="array">
<obj_property name="ElementShortName">[11][7:0]</obj_property>
<obj_property name="ObjectShortName">[11][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[12]" type="array">
<obj_property name="ElementShortName">[12][7:0]</obj_property>
<obj_property name="ObjectShortName">[12][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[13]" type="array">
<obj_property name="ElementShortName">[13][7:0]</obj_property>
<obj_property name="ObjectShortName">[13][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[14]" type="array">
<obj_property name="ElementShortName">[14][7:0]</obj_property>
<obj_property name="ObjectShortName">[14][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp_ctrl_i[15]" type="array">
<obj_property name="ElementShortName">[15][7:0]</obj_property>
<obj_property name="ObjectShortName">[15][7:0]</obj_property>
</wvobject>
<obj_property name="ElementShortName">pmp_ctrl_i[0:7][7:0]</obj_property>
<obj_property name="ObjectShortName">pmp_ctrl_i[0:7][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/priv_mode_i" type="array">
<obj_property name="ElementShortName">priv_mode_i[1:0]</obj_property>
/neorv32/trunk/sim/neorv32_tb.vhd
140,7 → 140,7
-- Physical Memory Protection (PMP) --
PMP_USE => true, -- implement PMP?
PMP_NUM_REGIONS => 4, -- number of regions (max 16)
PMP_GRANULARITY => 15, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_GRANULARITY => 14, -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE => x"00000000", -- base address of instruction memory space
MEM_ISPACE_SIZE => 16*1024, -- total size of instruction memory space in byte
/neorv32/trunk/sw/example/cpu_test/main.c
742,23 → 742,15
// find out number of regions
for (i=0; i<16; i++) {
exception_handler_answer = 0xFFFFFFFF;
switch (i) {
case 0: neorv32_cpu_csr_read(0x3b0); break;
case 1: neorv32_cpu_csr_read(0x3b1); break;
case 2: neorv32_cpu_csr_read(0x3b2); break;
case 3: neorv32_cpu_csr_read(0x3b3); break;
case 4: neorv32_cpu_csr_read(0x3b4); break;
case 5: neorv32_cpu_csr_read(0x3b5); break;
case 6: neorv32_cpu_csr_read(0x3b6); break;
case 7: neorv32_cpu_csr_read(0x3b7); break;
case 8: neorv32_cpu_csr_read(0x3b8); break;
case 9: neorv32_cpu_csr_read(0x3b9); break;
case 10: neorv32_cpu_csr_read(0x3ba); break;
case 11: neorv32_cpu_csr_read(0x3bb); break;
case 12: neorv32_cpu_csr_read(0x3bc); break;
case 13: neorv32_cpu_csr_read(0x3bd); break;
case 14: neorv32_cpu_csr_read(0x3be); break;
case 15: neorv32_cpu_csr_read(0x3bf); break;
switch (i) { // try to access pmpaddr regs
case 0: neorv32_cpu_csr_read(CSR_PMPADDR0); break;
case 1: neorv32_cpu_csr_read(CSR_PMPADDR1); break;
case 2: neorv32_cpu_csr_read(CSR_PMPADDR2); break;
case 3: neorv32_cpu_csr_read(CSR_PMPADDR3); break;
case 4: neorv32_cpu_csr_read(CSR_PMPADDR4); break;
case 5: neorv32_cpu_csr_read(CSR_PMPADDR5); break;
case 6: neorv32_cpu_csr_read(CSR_PMPADDR6); break;
case 7: neorv32_cpu_csr_read(CSR_PMPADDR7); break;
default: break;
}
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
774,18 → 766,25
uint32_t pmp_test_g = neorv32_cpu_csr_read(0x3b0);
 
// find least-significat set bit
for (i=31; i>=0; i--) {
for (i=31; i!=0; i--) {
if (((pmp_test_g >> i) & 1) == 0) {
break;
}
}
neorv32_uart_printf("Min granulartiy: %u bytes per region\n", 1<<(i+2));
 
neorv32_uart_printf("Min granularity (0x%x): ", pmp_test_g);
if (i < 29) {
neorv32_uart_printf("%u bytes per region\n", (uint32_t)(1 << (i+1+2)));
}
else {
neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
}
 
// test available modes
neorv32_uart_printf("Mode TOR: ");
neorv32_cpu_csr_write(0x3a0, 0x08);
if ((neorv32_cpu_csr_read(0x3a0) & 0xFF) == 0x08) {
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x08) {
neorv32_uart_printf("available\n");
}
else {
793,8 → 792,8
}
 
neorv32_uart_printf("Mode NA4: ");
neorv32_cpu_csr_write(0x3a0, 0x10);
if ((neorv32_cpu_csr_read(0x3a0) & 0xFF) == 0x10) {
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x10);
if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x10) {
neorv32_uart_printf("available\n");
}
else {
802,8 → 801,8
}
 
neorv32_uart_printf("Mode NAPOT: ");
neorv32_cpu_csr_write(0x3a0, 0x18);
if ((neorv32_cpu_csr_read(0x3a0) & 0xFF) == 0x18) {
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x18);
if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x18) {
neorv32_uart_printf("available\n");
}
else {
811,30 → 810,61
}
 
 
// test user mode access fault
neorv32_cpu_csr_write(0x3b0, 0x00007fff); // 64k area @ 0x00000000
neorv32_cpu_csr_write(0x3a0, 0b00011100); // NAPOT, execute permission, NO load permission
// Test access to protected region
// ---------------------------------------------
neorv32_uart_printf("Creating protected page (NAPOT, 64k) @ 0xFFFFA000, (!x, !w, r)...\n");
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffdfff); // 64k area @ 0xFFFFA000
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // NAPOT, read permission, NO write and execute permissions
 
neorv32_uart_printf("U-mode protected load fault test: ");
 
// ------ LOAD: should work ------
neorv32_uart_printf("U-mode (!X,!W,R) load test: ");
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile ("lw zero, 0xFFFFFF90(zero)"); // MTIME load access, should work
}
#if (DETAILED_EXCEPTION_DEBUG==0)
if (exception_handler_answer == 0xFFFFFFFF) {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
test_ok();
}
else {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
test_fail();
}
#endif
 
 
// ------ STORE: should fail ------
neorv32_uart_printf("U-mode (!X,!W,R) store test: ");
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// load from protected area
asm volatile ("lw zero, 0(zero)");
asm volatile ("sw zero, 0xFFFFFF90(zero)"); // MTIME store access, should fail
}
#if (DETAILED_EXCEPTION_DEBUG==0)
if (exception_handler_answer == TRAP_CODE_S_ACCESS) {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
#if (DETAILED_EXCEPTION_DEBUG==0)
if (exception_handler_answer == TRAP_CODE_L_ACCESS) {
neorv32_uart_printf("ok\n");
cnt_ok++;
test_ok();
}
else {
neorv32_uart_printf("fail\n");
cnt_fail++;
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
test_fail();
}
#endif
}
/neorv32/trunk/sw/lib/include/neorv32.h
36,7 → 36,6
/**********************************************************************//**
* @file neorv32.h
* @author Stephan Nolting
* @date 30 May 2020
*
* @brief Main NEORV32 core library file.
*
141,7 → 140,7
 
 
/**********************************************************************//**
* CPU <b>misa</b> CSR (r/w): Machine instruction set extensions (RISC-V spec.)
* CPU <b>misa</b> CSR (r/-): Machine instruction set extensions (RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MISA_enum {
CPU_MISA_C_EXT = 2, /**< CPU misa CSR (2): C: Compressed instructions CPU extension available (r/-)*/
150,7 → 149,6
CPU_MISA_M_EXT = 12, /**< CPU misa CSR (12): M: Multiplier/divider CPU extension available (r/-)*/
CPU_MISA_U_EXT = 20, /**< CPU misa CSR (20): U: User mode CPU extension available (r/-)*/
CPU_MISA_X_EXT = 23, /**< CPU misa CSR (23): X: Non-standard CPU extension available (r/-) */
CPU_MISA_Z_EXT = 25, /**< CPU misa CSR (25): Z: Privileged architecture CPU extension(s) available (r/-) */
CPU_MISA_MXL_LO_EXT = 30, /**< CPU misa CSR (30): MXL.lo: CPU data width (r/-) */
CPU_MISA_MXL_HI_EXT = 31 /**< CPU misa CSR (31): MXL.Hi: CPU data width (r/-) */
};
/neorv32/trunk/sw/lib/source/neorv32_cpu.c
242,6 → 242,7
* Switch from privilege mode MACHINE to privilege mode USER.
*
* @note This function requires the U extension to be implemented.
* @note Maybe you should do a fencei after this.
**************************************************************************/
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) {
 
/neorv32/trunk/README.md
98,7 → 98,7
 
### To-Do / Wish List
 
- Add AXI / AXI-Lite bridges
- Add AXI(-Lite) bridges
- Option to use DSP-based multiplier in `M` extension (would be so much faster)
- Synthesis results for more platforms
- Port Dhrystone benchmark
189,7 → 189,7
* Four fast interrupt requests (custom extension)
 
**Privileged architecture / User mode** (`U` extension, requires `Zicsr` extension):
* Privilege levels: `M-mode` (Machine mode) + `U-Mode` (User mode)
* Privilege levels: `M-mode` (Machine mode) + `U-mode` (User mode)
 
**Privileged architecture / FENCE.I** (`Zifencei` extension):
* System instructions: `FENCEI`
318,6 → 318,7
(except for the TWI signals, which are of type *std_logic*).
 
The top entity of the **CPU** is [**neorv32_cpu.vhd**](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_cpu.vhd) (from the `rtl/core` folder).
All signals of this top entity are of type *std_ulogic* or *std_ulogic_vector*, respectively.
 
Use the generics to configure the processor/CPU according to your needs. Each generic is initilized with the default configuration.
Detailed information regarding the signals and configuration generics can be found in the [NEORV32 documentary](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
343,8 → 344,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
429,8 → 430,8
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 16)
PMP_GRANULARITY : natural := 15; -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Bus Interface --
BUS_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.