Line 156... |
Line 156... |
ld_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load 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
|
st_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
|
end record;
|
end record;
|
signal pmp : pmp_t;
|
signal pmp : pmp_t;
|
|
|
-- pmp faults anybody? --
|
-- memory control signal buffer (when using PMP) --
|
|
signal d_bus_we, d_bus_we_buf : std_ulogic;
|
|
signal d_bus_re, d_bus_re_buf : std_ulogic;
|
|
signal i_bus_re, i_bus_re_buf : std_ulogic;
|
|
|
|
-- pmp faults anyone? --
|
signal if_pmp_fault : std_ulogic; -- pmp instruction access fault
|
signal if_pmp_fault : std_ulogic; -- pmp instruction access fault
|
signal ld_pmp_fault : std_ulogic; -- pmp load access fault
|
signal ld_pmp_fault : std_ulogic; -- pmp load access fault
|
signal st_pmp_fault : std_ulogic; -- pmp store access fault
|
signal st_pmp_fault : std_ulogic; -- pmp store access fault
|
|
|
begin
|
begin
|
|
|
|
-- Sanity Checks --------------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
assert not (PMP_NUM_REGIONS > pmp_num_regions_critical_c) report "NEORV32 CPU CONFIG WARNING! Number of implemented PMP regions (PMP_NUM_REGIONS = " & integer'image(PMP_NUM_REGIONS) & ") beyond critical limit (pmp_num_regions_critical_c = " & integer'image(pmp_num_regions_critical_c) & "). Inserting another register stage (that will increase memory latency by +1 cycle)." severity warning;
|
|
|
|
|
-- Data Interface: Access Address ---------------------------------------------------------
|
-- Data Interface: Access Address ---------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
mem_adr_reg: process(clk_i)
|
mem_adr_reg: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
Line 322... |
Line 332... |
|
|
-- data bus (read/write)--
|
-- data bus (read/write)--
|
d_bus_addr_o <= mar;
|
d_bus_addr_o <= mar;
|
d_bus_wdata_o <= d_bus_wdata;
|
d_bus_wdata_o <= d_bus_wdata;
|
d_bus_ben_o <= d_bus_ben;
|
d_bus_ben_o <= d_bus_ben;
|
d_bus_we_o <= ctrl_i(ctrl_bus_wr_c) and (not d_misaligned) and (not st_pmp_fault); -- no actual write when misaligned or PMP fault
|
d_bus_we <= ctrl_i(ctrl_bus_wr_c) and (not d_misaligned) and (not st_pmp_fault); -- no actual write when misaligned or PMP fault
|
d_bus_re_o <= ctrl_i(ctrl_bus_rd_c) and (not d_misaligned) and (not ld_pmp_fault); -- no actual read when misaligned or PMP fault
|
d_bus_re <= ctrl_i(ctrl_bus_rd_c) and (not d_misaligned) and (not ld_pmp_fault); -- no actual read when misaligned or PMP fault
|
|
d_bus_we_o <= d_bus_we_buf when (PMP_NUM_REGIONS > pmp_num_regions_critical_c) else d_bus_we;
|
|
d_bus_re_o <= d_bus_re_buf when (PMP_NUM_REGIONS > pmp_num_regions_critical_c) else d_bus_re;
|
d_bus_fence_o <= ctrl_i(ctrl_bus_fence_c);
|
d_bus_fence_o <= ctrl_i(ctrl_bus_fence_c);
|
d_bus_rdata <= d_bus_rdata_i;
|
d_bus_rdata <= d_bus_rdata_i;
|
d_bus_lock_o <= ctrl_i(ctrl_bus_lock_c);
|
d_bus_lock_o <= ctrl_i(ctrl_bus_lock_c);
|
|
|
|
-- additional register stage for control signals if using PMP_NUM_REGIONS > pmp_num_regions_critical_c --
|
|
pmp_dbus_buffer: process(rstn_i, clk_i)
|
|
begin
|
|
if (rstn_i = '0') then
|
|
d_bus_we_buf <= '0';
|
|
d_bus_re_buf <= '0';
|
|
elsif rising_edge(clk_i) then
|
|
d_bus_we_buf <= d_bus_we;
|
|
d_bus_re_buf <= d_bus_re;
|
|
end if;
|
|
end process pmp_dbus_buffer;
|
|
|
|
|
-- Instruction Fetch Arbiter --------------------------------------------------------------
|
-- Instruction Fetch Arbiter --------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
ifetch_arbiter: process(rstn_i, clk_i)
|
ifetch_arbiter: process(rstn_i, clk_i)
|
begin
|
begin
|
Line 373... |
Line 397... |
-- instruction bus (read-only) --
|
-- instruction bus (read-only) --
|
i_bus_addr_o <= fetch_pc_i(data_width_c-1 downto 2) & "00"; -- instruction access is always 4-byte aligned (even for compressed instructions)
|
i_bus_addr_o <= fetch_pc_i(data_width_c-1 downto 2) & "00"; -- instruction access is always 4-byte aligned (even for compressed instructions)
|
i_bus_wdata_o <= (others => '0'); -- instruction fetch is read-only
|
i_bus_wdata_o <= (others => '0'); -- instruction fetch is read-only
|
i_bus_ben_o <= (others => '0');
|
i_bus_ben_o <= (others => '0');
|
i_bus_we_o <= '0';
|
i_bus_we_o <= '0';
|
i_bus_re_o <= ctrl_i(ctrl_bus_if_c) and (not i_misaligned) and (not if_pmp_fault); -- no actual read when misaligned or PMP fault
|
i_bus_re <= ctrl_i(ctrl_bus_if_c) and (not i_misaligned) and (not if_pmp_fault); -- no actual read when misaligned or PMP fault
|
|
i_bus_re_o <= i_bus_re_buf when (PMP_NUM_REGIONS > pmp_num_regions_critical_c) else i_bus_re;
|
i_bus_fence_o <= ctrl_i(ctrl_bus_fencei_c);
|
i_bus_fence_o <= ctrl_i(ctrl_bus_fencei_c);
|
instr_o <= i_bus_rdata_i;
|
instr_o <= i_bus_rdata_i;
|
i_bus_lock_o <= '0'; -- instruction fetch cannot be atomic
|
i_bus_lock_o <= '0'; -- instruction fetch cannot be atomic
|
|
|
|
|
-- check instruction access --
|
-- check instruction access --
|
i_misaligned <= '0' when (CPU_EXTENSION_RISCV_C = true) else -- no alignment exceptions possible when using C-extension
|
i_misaligned <= '0' when (CPU_EXTENSION_RISCV_C = true) else -- no alignment exceptions possible when using C-extension
|
'1' when (fetch_pc_i(1) = '1') else '0'; -- 32-bit accesses only
|
'1' when (fetch_pc_i(1) = '1') else '0'; -- 32-bit accesses only
|
|
|
|
-- additional register stage for control signals if using PMP_NUM_REGIONS > pmp_num_regions_critical_c --
|
|
pmp_ibus_buffer: process(rstn_i, clk_i)
|
|
begin
|
|
if (rstn_i = '0') then
|
|
i_bus_re_buf <= '0';
|
|
elsif rising_edge(clk_i) then
|
|
i_bus_re_buf <= i_bus_re;
|
|
end if;
|
|
end process pmp_ibus_buffer;
|
|
|
|
|
-- Physical Memory Protection (PMP) -------------------------------------------------------
|
-- Physical Memory Protection (PMP) -------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- compute address masks (ITERATIVE!!!) --
|
-- compute address masks (ITERATIVE!!!) --
|
pmp_masks: process(clk_i)
|
pmp_masks: process(clk_i)
|