Line 70... |
Line 70... |
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
|
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
|
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
|
-- Internal Data memory --
|
-- Internal Data memory --
|
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
|
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
|
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
|
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
|
|
-- Internal Cache memory --
|
|
ICACHE_USE : boolean := false; -- implement instruction cache
|
|
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
|
|
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
|
-- External memory interface --
|
-- External memory interface --
|
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
|
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
|
-- Processor peripherals --
|
-- Processor peripherals --
|
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
|
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
|
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
|
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
|
Line 133... |
Line 137... |
architecture neorv32_top_rtl of neorv32_top is
|
architecture neorv32_top_rtl of neorv32_top is
|
|
|
-- CPU boot address --
|
-- CPU boot address --
|
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_USE, boot_rom_base_c, ispace_base_c);
|
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_USE, boot_rom_base_c, ispace_base_c);
|
|
|
|
-- Bus timeout --
|
|
constant bus_timeout_temp_c : natural := 2**index_size_f(bus_timeout_c); -- round to next power-of-two
|
|
constant bus_timeout_proc_c : natural := cond_sel_natural_f(ICACHE_USE, ((ICACHE_BLOCK_SIZE/4)*bus_timeout_temp_c)-1, bus_timeout_c);
|
|
|
-- alignment check for internal memories --
|
-- alignment check for internal memories --
|
constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0');
|
constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0');
|
constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0');
|
constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0');
|
|
|
-- reset generator --
|
-- reset generator --
|
Line 174... |
Line 182... |
fence : std_ulogic; -- fence(i) instruction executed
|
fence : std_ulogic; -- fence(i) instruction executed
|
priv : std_ulogic_vector(1 downto 0); -- current privilege level
|
priv : std_ulogic_vector(1 downto 0); -- current privilege level
|
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
lock : std_ulogic; -- locked/exclusive (=atomic) access
|
lock : std_ulogic; -- locked/exclusive (=atomic) access
|
end record;
|
end record;
|
signal cpu_i, cpu_d, p_bus : bus_interface_t;
|
signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
|
|
|
-- io space access --
|
-- io space access --
|
signal io_acc : std_ulogic;
|
signal io_acc : std_ulogic;
|
signal io_rden : std_ulogic;
|
signal io_rden : std_ulogic;
|
signal io_wren : std_ulogic;
|
signal io_wren : std_ulogic;
|
Line 249... |
Line 257... |
assert not ((ispace_base_c(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) /= imem_align_check_c) and (MEM_INT_IMEM_USE = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address has to be aligned to IMEM size." severity error;
|
assert not ((ispace_base_c(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) /= imem_align_check_c) and (MEM_INT_IMEM_USE = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address has to be aligned to IMEM size." severity error;
|
assert not ((dspace_base_c(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) /= dmem_align_check_c) and (MEM_INT_DMEM_USE = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address has to be aligned to DMEM size." severity error;
|
assert not ((dspace_base_c(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) /= dmem_align_check_c) and (MEM_INT_DMEM_USE = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address has to be aligned to DMEM size." severity error;
|
-- memory system - layout warning --
|
-- memory system - layout warning --
|
assert not (ispace_base_c /= x"00000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framework." severity warning;
|
assert not (ispace_base_c /= x"00000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framework." severity warning;
|
assert not (dspace_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning;
|
assert not (dspace_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning;
|
|
-- memory system - the i-cache is intended to accelerate instruction fetch via the external memory interface only --
|
|
assert not ((ICACHE_USE = true) and (MEM_EXT_USE = false)) report "NEORV32 PROCESSOR CONFIG NOTE. Implementing i-cache without having the external memory interface implemented. The i-cache is intended to accelerate instruction fetch via the external memory interface." severity note;
|
|
-- memory system - cached instruction fetch latency check --
|
|
assert not (ICACHE_USE = true) report "NEORV32 PROCESSOR CONFIG WARNING! Implementing i-cache. Increasing bus access timeout from " & integer'image(bus_timeout_c) & " cycles to " & integer'image(bus_timeout_proc_c) & " cycles." severity warning;
|
|
|
|
|
-- Reset Generator ------------------------------------------------------------------------
|
-- Reset Generator ------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
reset_generator_sync: process(clk_i)
|
reset_generator_sync: process(clk_i)
|
Line 316... |
Line 328... |
neorv32_cpu_inst: neorv32_cpu
|
neorv32_cpu_inst: neorv32_cpu
|
generic map (
|
generic map (
|
-- General --
|
-- General --
|
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
|
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
|
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address
|
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address
|
|
BUS_TIMEOUT => bus_timeout_proc_c, -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
Line 385... |
Line 398... |
fast_irq(1) <= gpio_irq; -- GPIO input pin-change interrupt
|
fast_irq(1) <= gpio_irq; -- GPIO input pin-change interrupt
|
fast_irq(2) <= uart_irq; -- UART TX done or RX complete interrupt
|
fast_irq(2) <= uart_irq; -- UART TX done or RX complete interrupt
|
fast_irq(3) <= spi_irq or twi_irq; -- lowest priority, can be triggered by SPI or TWI
|
fast_irq(3) <= spi_irq or twi_irq; -- lowest priority, can be triggered by SPI or TWI
|
|
|
|
|
|
-- CPU Instruction Cache ------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
neorv32_icache_inst_true:
|
|
if (ICACHE_USE = true) generate
|
|
neorv32_icache_inst: neorv32_cache
|
|
generic map (
|
|
CACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- number of blocks (min 2), has to be a power of 2
|
|
CACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE -- block size in bytes (min 4), has to be a power of 2
|
|
)
|
|
port map (
|
|
-- global control --
|
|
clk_i => clk_i, -- global clock, rising edge
|
|
rstn_i => sys_rstn, -- global reset, low-active, async
|
|
clear_i => cpu_i.fence, -- cache clear
|
|
-- host controller interface --
|
|
host_addr_i => cpu_i.addr, -- bus access address
|
|
host_rdata_o => cpu_i.rdata, -- bus read data
|
|
host_wdata_i => cpu_i.wdata, -- bus write data
|
|
host_ben_i => cpu_i.ben, -- byte enable
|
|
host_we_i => cpu_i.we, -- write enable
|
|
host_re_i => cpu_i.re, -- read enable
|
|
host_cancel_i => cpu_i.cancel, -- cancel current bus transaction
|
|
host_lock_i => cpu_i.lock, -- locked/exclusive access
|
|
host_ack_o => cpu_i.ack, -- bus transfer acknowledge
|
|
host_err_o => cpu_i.err, -- bus transfer error
|
|
-- peripheral bus interface --
|
|
bus_addr_o => i_cache.addr, -- bus access address
|
|
bus_rdata_i => i_cache.rdata, -- bus read data
|
|
bus_wdata_o => i_cache.wdata, -- bus write data
|
|
bus_ben_o => i_cache.ben, -- byte enable
|
|
bus_we_o => i_cache.we, -- write enable
|
|
bus_re_o => i_cache.re, -- read enable
|
|
bus_cancel_o => i_cache.cancel, -- cancel current bus transaction
|
|
bus_lock_o => i_cache.lock, -- locked/exclusive access
|
|
bus_ack_i => i_cache.ack, -- bus transfer acknowledge
|
|
bus_err_i => i_cache.err -- bus transfer error
|
|
);
|
|
end generate;
|
|
|
|
neorv32_icache_inst_false:
|
|
if (ICACHE_USE = false) generate
|
|
i_cache.addr <= cpu_i.addr;
|
|
cpu_i.rdata <= i_cache.rdata;
|
|
i_cache.wdata <= cpu_i.wdata;
|
|
i_cache.ben <= cpu_i.ben;
|
|
i_cache.we <= cpu_i.we;
|
|
i_cache.re <= cpu_i.re;
|
|
i_cache.cancel <= cpu_i.cancel;
|
|
i_cache.lock <= cpu_i.lock;
|
|
cpu_i.ack <= i_cache.ack;
|
|
cpu_i.err <= i_cache.err;
|
|
end generate;
|
|
|
|
|
-- CPU Crossbar Switch --------------------------------------------------------------------
|
-- CPU Crossbar Switch --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_busswitch_inst: neorv32_busswitch
|
neorv32_busswitch_inst: neorv32_busswitch
|
generic map (
|
generic map (
|
PORT_CA_READ_ONLY => false, -- set if controller port A is read-only
|
PORT_CA_READ_ONLY => false, -- set if controller port A is read-only
|
Line 408... |
Line 475... |
ca_bus_cancel_i => cpu_d.cancel, -- cancel current bus transaction
|
ca_bus_cancel_i => cpu_d.cancel, -- cancel current bus transaction
|
ca_bus_lock_i => cpu_d.lock, -- locked/exclusive access
|
ca_bus_lock_i => cpu_d.lock, -- locked/exclusive access
|
ca_bus_ack_o => cpu_d.ack, -- bus transfer acknowledge
|
ca_bus_ack_o => cpu_d.ack, -- bus transfer acknowledge
|
ca_bus_err_o => cpu_d.err, -- bus transfer error
|
ca_bus_err_o => cpu_d.err, -- bus transfer error
|
-- controller interface b --
|
-- controller interface b --
|
cb_bus_addr_i => cpu_i.addr, -- bus access address
|
cb_bus_addr_i => i_cache.addr, -- bus access address
|
cb_bus_rdata_o => cpu_i.rdata, -- bus read data
|
cb_bus_rdata_o => i_cache.rdata, -- bus read data
|
cb_bus_wdata_i => cpu_i.wdata, -- bus write data
|
cb_bus_wdata_i => i_cache.wdata, -- bus write data
|
cb_bus_ben_i => cpu_i.ben, -- byte enable
|
cb_bus_ben_i => i_cache.ben, -- byte enable
|
cb_bus_we_i => cpu_i.we, -- write enable
|
cb_bus_we_i => i_cache.we, -- write enable
|
cb_bus_re_i => cpu_i.re, -- read enable
|
cb_bus_re_i => i_cache.re, -- read enable
|
cb_bus_cancel_i => cpu_i.cancel, -- cancel current bus transaction
|
cb_bus_cancel_i => i_cache.cancel, -- cancel current bus transaction
|
cb_bus_lock_i => cpu_i.lock, -- locked/exclusive access
|
cb_bus_lock_i => i_cache.lock, -- locked/exclusive access
|
cb_bus_ack_o => cpu_i.ack, -- bus transfer acknowledge
|
cb_bus_ack_o => i_cache.ack, -- bus transfer acknowledge
|
cb_bus_err_o => cpu_i.err, -- bus transfer error
|
cb_bus_err_o => i_cache.err, -- bus transfer error
|
-- peripheral bus --
|
-- peripheral bus --
|
p_bus_src_o => p_bus.src, -- access source: 0 = A (data), 1 = B (instructions)
|
p_bus_src_o => p_bus.src, -- access source: 0 = A (data), 1 = B (instructions)
|
p_bus_addr_o => p_bus.addr, -- bus access address
|
p_bus_addr_o => p_bus.addr, -- bus access address
|
p_bus_rdata_i => p_bus.rdata, -- bus read data
|
p_bus_rdata_i => p_bus.rdata, -- bus read data
|
p_bus_wdata_o => p_bus.wdata, -- bus write data
|
p_bus_wdata_o => p_bus.wdata, -- bus write data
|
Line 939... |
Line 1006... |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
|
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
|
MEM_INT_IMEM_ROM => MEM_INT_IMEM_ROM, -- implement processor-internal instruction memory as ROM
|
MEM_INT_IMEM_ROM => MEM_INT_IMEM_ROM, -- implement processor-internal instruction memory as ROM
|
-- Internal Data memory --
|
-- Internal Data memory --
|
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
|
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
|
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
|
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
|
|
-- Internal Cache memory --
|
|
ICACHE_USE => ICACHE_USE, -- implement instruction cache
|
|
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 2), has to be a power of 2
|
|
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
|
|
ICACHE_ASSOCIATIVITY => 1, -- i-cache: associativity (min 1), has to be a power 2
|
-- External memory interface --
|
-- External memory interface --
|
MEM_EXT_USE => MEM_EXT_USE, -- implement external memory bus interface?
|
MEM_EXT_USE => MEM_EXT_USE, -- implement external memory bus interface?
|
-- Processor peripherals --
|
-- Processor peripherals --
|
IO_GPIO_USE => IO_GPIO_USE, -- implement general purpose input/output port unit (GPIO)?
|
IO_GPIO_USE => IO_GPIO_USE, -- implement general purpose input/output port unit (GPIO)?
|
IO_MTIME_USE => IO_MTIME_USE, -- implement machine system timer (MTIME)?
|
IO_MTIME_USE => IO_MTIME_USE, -- implement machine system timer (MTIME)?
|