Line 67... |
Line 67... |
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
-- Extension Options --
|
-- Extension Options --
|
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
|
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
|
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
|
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
|
-- Physical Memory Protection (PMP) --
|
-- Physical Memory Protection (PMP) --
|
PMP_USE : boolean := false; -- implement PMP?
|
PMP_USE : boolean := false -- implement PMP?
|
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
|
|
);
|
);
|
port (
|
port (
|
-- global control --
|
-- global control --
|
clk_i : in std_ulogic := '0'; -- global clock, rising edge
|
clk_i : in std_ulogic := '0'; -- global clock, rising edge
|
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
|
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
|
Line 157... |
Line 155... |
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
|
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
|
-- U-extension requires Zicsr extension --
|
-- U-extension requires Zicsr extension --
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
-- PMP requires Zicsr extension --
|
-- PMP requires Zicsr extension --
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
|
-- PMP regions --
|
-- RISC-V standard performance counters -
|
assert not ((PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
|
assert not ((CPU_EXTENSION_RISCV_Zicsr = true) and (zicnt_en_c = false)) report "NEORV32 CPU CONFIG WARNING! Standard RISC-V peformance counters ([m]cycle[h], [m]instret[h]) will not be implemented (not RISC-V-compliant!)." severity warning;
|
-- PMP granulartiy --
|
|
assert not (((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < PMP_GRANULARITY < 33)." severity error;
|
|
-- Instruction prefetch buffer size --
|
-- Instruction prefetch buffer size --
|
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
|
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
|
-- A extension - only lr.w and sc.w supported yet --
|
-- A extension - only lr.w and sc.w supported yet --
|
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 CPU CONFIG WARNING! Atomic operations extension (A) only supports >lr.w< and >sc.w< instructions yet." severity warning;
|
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 CPU CONFIG WARNING! Atomic operations extension (A) only supports >lr.w< and >sc.w< instructions yet." severity warning;
|
|
|
|
-- PMP regions check --
|
|
assert not ((pmp_num_regions_c > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions <pmp_num_regions_c> out of valid range." severity error;
|
|
-- PMP granulartiy --
|
|
assert not ((is_power_of_two_f(pmp_min_granularity_c) = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be a power of two." severity error;
|
|
assert not ((pmp_min_granularity_c < 8) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be >= 8 bytes." severity error;
|
|
|
|
-- PMP notifier --
|
|
assert not (PMP_USE = true) report "NEORV32 CPU CONFIG NOTE: Implementing physical memory protection (PMP) with " & integer'image(pmp_num_regions_c) & " regions and " & integer'image(pmp_min_granularity_c) & " bytes minimal region size (granulartiy)." severity note;
|
|
|
-- Control Unit ---------------------------------------------------------------------------
|
-- Control Unit ---------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
neorv32_cpu_control_inst: neorv32_cpu_control
|
generic map (
|
generic map (
|
Line 183... |
Line 188... |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_USE => PMP_USE, -- implement physical memory protection?
|
PMP_USE => PMP_USE -- implement physical memory protection?
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (1..4)
|
|
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
|
|
)
|
)
|
port map (
|
port map (
|
-- global control --
|
-- global control --
|
clk_i => clk_i, -- global clock, rising edge
|
clk_i => clk_i, -- global clock, rising edge
|
rstn_i => rstn_i, -- global reset, low-active, async
|
rstn_i => rstn_i, -- global reset, low-active, async
|
Line 314... |
Line 317... |
end generate;
|
end generate;
|
|
|
neorv32_cpu_cp_muldiv_inst_false:
|
neorv32_cpu_cp_muldiv_inst_false:
|
if (CPU_EXTENSION_RISCV_M = false) generate
|
if (CPU_EXTENSION_RISCV_M = false) generate
|
cp0_data <= (others => '0');
|
cp0_data <= (others => '0');
|
cp0_valid <= '0';
|
cp0_valid <= cp0_start; -- to make sure CPU does not get stalled if there is an accidental access
|
end generate;
|
end generate;
|
|
|
|
|
-- Co-Processor 1: Atomic Memory Access (SC - store-conditional) --------------------------
|
-- Co-Processor 1: Atomic Memory Access (SC - store-conditional) --------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
atomic_op_cp: process(ctrl, cp1_start)
|
atomic_op_cp: process(cp1_start, ctrl)
|
begin
|
begin
|
-- "fake" co-processor for atomic operations
|
-- "fake" co-processor for atomic operations
|
-- used to get the result of a store-conditional operation into the data path
|
-- used to get the result of a store-conditional operation into the data path
|
if (CPU_EXTENSION_RISCV_A = true) and (cp1_start = '1') then
|
if (CPU_EXTENSION_RISCV_A = true) then
|
|
if (cp1_start = '1') then
|
cp1_data <= (others => '0');
|
cp1_data <= (others => '0');
|
cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
|
cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
|
cp1_valid <= '1';
|
cp1_valid <= '1';
|
else
|
else
|
cp1_data <= (others => '0');
|
cp1_data <= (others => '0');
|
cp1_valid <= '0';
|
cp1_valid <= '0';
|
end if;
|
end if;
|
end process;
|
else
|
|
cp1_data <= (others => '0');
|
|
cp1_valid <= cp1_start; -- to make sure CPU does not get stalled if there is an accidental access
|
|
end if;
|
|
end process atomic_op_cp;
|
|
|
|
|
-- Co-Processor 2: Not implemented (yet) --------------------------------------------------
|
-- Co-Processor 2: Not implemented (yet) --------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- control: ctrl cp2_start
|
-- control: ctrl cp2_start
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
cp2_data <= (others => '0');
|
cp2_data <= (others => '0');
|
cp2_valid <= '0';
|
cp2_valid <= cp2_start; -- to make sure CPU does not get stalled if there is an accidental access
|
|
|
|
|
-- Co-Processor 3: Not implemented (yet) --------------------------------------------------
|
-- Co-Processor 3: Not implemented (yet) --------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- control: ctrl cp3_start
|
-- control: ctrl cp3_start
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
-- inputs: rs1 rs2 alu_cmp alu_opb
|
cp3_data <= (others => '0');
|
cp3_data <= (others => '0');
|
cp3_valid <= '0';
|
cp3_valid <= cp3_start; -- to make sure CPU does not get stalled if there is an accidental access
|
|
|
|
|
-- Bus Interface Unit ---------------------------------------------------------------------
|
-- Bus Interface Unit ---------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cpu_bus_inst: neorv32_cpu_bus
|
neorv32_cpu_bus_inst: neorv32_cpu_bus
|
generic map (
|
generic map (
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_USE => PMP_USE, -- implement physical memory protection?
|
PMP_USE => PMP_USE -- implement physical memory protection?
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (1..4)
|
|
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
|
|
)
|
)
|
port map (
|
port map (
|
-- global control --
|
-- global control --
|
clk_i => clk_i, -- global clock, rising edge
|
clk_i => clk_i, -- global clock, rising edge
|
rstn_i => rstn_i, -- global reset, low-active, async
|
rstn_i => rstn_i, -- global reset, low-active, async
|