Line 39... |
Line 39... |
package neorv32_package is
|
package neorv32_package is
|
|
|
-- Architecture Constants -----------------------------------------------------------------
|
-- Architecture Constants -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
constant data_width_c : natural := 32; -- data width - FIXED!
|
constant data_width_c : natural := 32; -- data width - FIXED!
|
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030000"; -- no touchy!
|
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01030500"; -- no touchy!
|
|
constant pmp_max_r_c : natural := 8; -- max PMP regions
|
|
|
-- Helper Functions -----------------------------------------------------------------------
|
-- Helper Functions -----------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
function index_size_f(input : natural) return natural;
|
function index_size_f(input : natural) return natural;
|
function cond_sel_natural_f(cond : boolean; val_t : natural; val_f : natural) return natural;
|
function cond_sel_natural_f(cond : boolean; val_t : natural; val_f : natural) return natural;
|
Line 53... |
Line 54... |
function and_all_f( a : std_ulogic_vector) return std_ulogic;
|
function and_all_f( a : std_ulogic_vector) return std_ulogic;
|
function xor_all_f( a : std_ulogic_vector) return std_ulogic;
|
function xor_all_f( a : std_ulogic_vector) return std_ulogic;
|
function xnor_all_f(a : std_ulogic_vector) return std_ulogic;
|
function xnor_all_f(a : std_ulogic_vector) return std_ulogic;
|
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character;
|
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character;
|
|
|
|
-- Internal Types -------------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
type pmp_ctrl_if_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(7 downto 0);
|
|
type pmp_addr_if_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(33 downto 0);
|
|
|
-- Processor-internal Address Space Layout ------------------------------------------------
|
-- Processor-internal Address Space Layout ------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- Instruction Memory & Data Memory --
|
-- Instruction Memory & Data Memory --
|
-- => configured via top's generics
|
-- => configured via top's generics
|
|
|
Line 359... |
Line 365... |
constant interrupt_firq_2_c : natural := 5; -- fast interrupt channel 2
|
constant interrupt_firq_2_c : natural := 5; -- fast interrupt channel 2
|
constant interrupt_firq_3_c : natural := 6; -- fast interrupt channel 3
|
constant interrupt_firq_3_c : natural := 6; -- fast interrupt channel 3
|
--
|
--
|
constant interrupt_width_c : natural := 7; -- length of this list in bits
|
constant interrupt_width_c : natural := 7; -- length of this list in bits
|
|
|
|
-- CPU Privilege Modes --------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
constant m_priv_mode_c : std_ulogic_vector(1 downto 0) := "11"; -- machine mode
|
|
constant u_priv_mode_c : std_ulogic_vector(1 downto 0) := "00"; -- user mode
|
|
|
-- Clock Generator -------------------------------------------------------------------------
|
-- Clock Generator -------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
constant clk_div2_c : natural := 0;
|
constant clk_div2_c : natural := 0;
|
constant clk_div4_c : natural := 1;
|
constant clk_div4_c : natural := 1;
|
constant clk_div8_c : natural := 2;
|
constant clk_div8_c : natural := 2;
|
Line 383... |
Line 394... |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
|
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
|
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
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
|
-- Memory configuration: Instruction memory --
|
-- Memory configuration: Instruction memory --
|
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
|
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
|
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
|
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
|
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
|
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
|
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
|
Line 462... |
Line 478... |
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= (others => '0'); -- cpu boot address
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= (others => '0'); -- cpu boot address
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
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
|
-- Bus Interface --
|
-- Bus Interface --
|
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
|
);
|
);
|
port (
|
port (
|
-- global control --
|
-- global control --
|
Line 516... |
Line 537... |
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
|
|
-- Physical memory protection (PMP) --
|
|
PMP_USE : boolean := false; -- implement physical memory protection?
|
|
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
|
|
PMP_GRANULARITY : natural := 0 -- granularity (0=none, 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 548... |
Line 574... |
mtime_irq_i : in std_ulogic; -- machine timer interrupt
|
mtime_irq_i : in std_ulogic; -- machine timer interrupt
|
-- fast interrupts (custom) --
|
-- fast interrupts (custom) --
|
firq_i : in std_ulogic_vector(3 downto 0);
|
firq_i : in std_ulogic_vector(3 downto 0);
|
-- system time input from MTIME --
|
-- system time input from MTIME --
|
time_i : in std_ulogic_vector(63 downto 0); -- current system time
|
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 --
|
-- bus access exceptions --
|
mar_i : in std_ulogic_vector(data_width_c-1 downto 0); -- memory address register
|
mar_i : in std_ulogic_vector(data_width_c-1 downto 0); -- memory address register
|
ma_instr_i : in std_ulogic; -- misaligned instruction address
|
ma_instr_i : in std_ulogic; -- misaligned instruction address
|
ma_load_i : in std_ulogic; -- misaligned load data address
|
ma_load_i : in std_ulogic; -- misaligned load data address
|
ma_store_i : in std_ulogic; -- misaligned store data address
|
ma_store_i : in std_ulogic; -- misaligned store data address
|
Line 633... |
Line 664... |
-- Component: CPU Bus Interface -----------------------------------------------------------
|
-- Component: CPU Bus Interface -----------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
component neorv32_cpu_bus
|
component neorv32_cpu_bus
|
generic (
|
generic (
|
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) --
|
|
PMP_USE : boolean := false; -- implement physical memory protection?
|
|
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
|
|
PMP_GRANULARITY : natural := 0 -- granularity (0=none, 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 658... |
Line 693... |
--
|
--
|
ma_load_o : out std_ulogic; -- misaligned load data address
|
ma_load_o : out std_ulogic; -- misaligned load data address
|
ma_store_o : out std_ulogic; -- misaligned store data address
|
ma_store_o : out std_ulogic; -- misaligned store data address
|
be_load_o : out std_ulogic; -- bus error on load data access
|
be_load_o : out std_ulogic; -- bus error on load data access
|
be_store_o : out std_ulogic; -- bus error on store data access
|
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 --
|
-- instruction bus --
|
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
|
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
|
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
|
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
|
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
|
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
|
Line 1124... |
Line 1164... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
function or_all_f(a : std_ulogic_vector) return std_ulogic is
|
function or_all_f(a : std_ulogic_vector) return std_ulogic is
|
variable tmp_v : std_ulogic;
|
variable tmp_v : std_ulogic;
|
begin
|
begin
|
tmp_v := a(a'low);
|
tmp_v := a(a'low);
|
|
if (a'low < a'high) then -- not null range?
|
for i in a'low+1 to a'high loop
|
for i in a'low+1 to a'high loop
|
tmp_v := tmp_v or a(i);
|
tmp_v := tmp_v or a(i);
|
end loop; -- i
|
end loop; -- i
|
|
end if;
|
return tmp_v;
|
return tmp_v;
|
end function or_all_f;
|
end function or_all_f;
|
|
|
-- Function: AND all bits -----------------------------------------------------------------
|
-- Function: AND all bits -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
function and_all_f(a : std_ulogic_vector) return std_ulogic is
|
function and_all_f(a : std_ulogic_vector) return std_ulogic is
|
variable tmp_v : std_ulogic;
|
variable tmp_v : std_ulogic;
|
begin
|
begin
|
tmp_v := a(a'low);
|
tmp_v := a(a'low);
|
|
if (a'low < a'high) then -- not null range?
|
for i in a'low+1 to a'high loop
|
for i in a'low+1 to a'high loop
|
tmp_v := tmp_v and a(i);
|
tmp_v := tmp_v and a(i);
|
end loop; -- i
|
end loop; -- i
|
|
end if;
|
return tmp_v;
|
return tmp_v;
|
end function and_all_f;
|
end function and_all_f;
|
|
|
-- Function: XOR all bits -----------------------------------------------------------------
|
-- Function: XOR all bits -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
function xor_all_f(a : std_ulogic_vector) return std_ulogic is
|
function xor_all_f(a : std_ulogic_vector) return std_ulogic is
|
variable tmp_v : std_ulogic;
|
variable tmp_v : std_ulogic;
|
begin
|
begin
|
tmp_v := a(a'low);
|
tmp_v := a(a'low);
|
|
if (a'low < a'high) then -- not null range?
|
for i in a'low+1 to a'high loop
|
for i in a'low+1 to a'high loop
|
tmp_v := tmp_v xor a(i);
|
tmp_v := tmp_v xor a(i);
|
end loop; -- i
|
end loop; -- i
|
|
end if;
|
return tmp_v;
|
return tmp_v;
|
end function xor_all_f;
|
end function xor_all_f;
|
|
|
-- Function: XNOR all bits ----------------------------------------------------------------
|
-- Function: XNOR all bits ----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
function xnor_all_f(a : std_ulogic_vector) return std_ulogic is
|
function xnor_all_f(a : std_ulogic_vector) return std_ulogic is
|
variable tmp_v : std_ulogic;
|
variable tmp_v : std_ulogic;
|
begin
|
begin
|
tmp_v := a(a'low);
|
tmp_v := a(a'low);
|
|
if (a'low < a'high) then -- not null range?
|
for i in a'low+1 to a'high loop
|
for i in a'low+1 to a'high loop
|
tmp_v := tmp_v xnor a(i);
|
tmp_v := tmp_v xnor a(i);
|
end loop; -- i
|
end loop; -- i
|
|
end if;
|
return tmp_v;
|
return tmp_v;
|
end function xnor_all_f;
|
end function xnor_all_f;
|
|
|
-- Function: Convert to hex char ----------------------------------------------------------
|
-- Function: Convert to hex char ----------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|