Line 1... |
Line 1... |
-- #################################################################################################
|
-- #################################################################################################
|
-- # << NEORV32 - Processor Top Entity >> #
|
-- # << The NEORV32 RISC-V Processor - Top Entity >> #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
-- # This is the top entity of the NEORV32 PROCESSOR. Instantiate this unit in your own project #
|
|
-- # and define all the configuration generics according to your needs or use one of the #
|
|
-- # pre-defined template wrappers. #
|
|
-- # #
|
|
-- # Check out the processor's online documentation for more information: #
|
-- # Check out the processor's online documentation for more information: #
|
-- # HQ: https://github.com/stnolting/neorv32 #
|
-- # HQ: https://github.com/stnolting/neorv32 #
|
-- # Data Sheet: https://stnolting.github.io/neorv32 #
|
-- # Data Sheet: https://stnolting.github.io/neorv32 #
|
-- # User Guide: https://stnolting.github.io/neorv32/ug #
|
-- # User Guide: https://stnolting.github.io/neorv32/ug #
|
-- # ********************************************************************************************* #
|
-- # ********************************************************************************************* #
|
Line 58... |
Line 54... |
-- On-Chip Debugger (OCD) --
|
-- On-Chip Debugger (OCD) --
|
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
|
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
|
|
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
|
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
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 mul/div extension?
|
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
|
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
|
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
|
|
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
|
|
|
-- 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
|
Line 307... |
Line 305... |
err : std_ulogic;
|
err : std_ulogic;
|
end record;
|
end record;
|
constant resp_bus_entry_terminate_c : resp_bus_entry_t := (rdata => (others => '0'), ack => '0', err => '0');
|
constant resp_bus_entry_terminate_c : resp_bus_entry_t := (rdata => (others => '0'), ack => '0', err => '0');
|
|
|
-- module response bus - device ID --
|
-- module response bus - device ID --
|
type resp_bus_id_t is (RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI,
|
type resp_bus_id_t is (RESP_BUSKEEPER, RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI,
|
RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NEOLED, RESP_SYSINFO, RESP_OCD, RESP_SLINK, RESP_XIRQ);
|
RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NEOLED, RESP_SYSINFO, RESP_OCD, RESP_SLINK, RESP_XIRQ);
|
|
|
-- module response bus --
|
-- module response bus --
|
type resp_bus_t is array (resp_bus_id_t) of resp_bus_entry_t;
|
type resp_bus_t is array (resp_bus_id_t) of resp_bus_entry_t;
|
signal resp_bus : resp_bus_t := (others => resp_bus_entry_terminate_c);
|
signal resp_bus : resp_bus_t := (others => resp_bus_entry_terminate_c);
|
Line 332... |
Line 330... |
signal slink_rx_irq : std_ulogic;
|
signal slink_rx_irq : std_ulogic;
|
signal xirq_irq : std_ulogic;
|
signal xirq_irq : std_ulogic;
|
|
|
-- misc --
|
-- misc --
|
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
|
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
|
signal bus_keeper_err : std_ulogic; -- bus keeper: bus access timeout
|
|
|
|
begin
|
begin
|
|
|
-- Processor IO/Peripherals Configuration -------------------------------------------------
|
-- Processor IO/Peripherals Configuration -------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 454... |
Line 451... |
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
|
CPU_DEBUG_ADDR => dm_base_c, -- cpu debug mode start address
|
CPU_DEBUG_ADDR => dm_base_c, -- cpu debug mode start address
|
-- 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_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation 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?
|
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_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
|
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
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_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
|
|
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
|
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
|
-- Extension Options --
|
-- Extension Options --
|
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
Line 528... |
Line 527... |
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
|
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
|
|
|
-- fast interrupts --
|
-- fast interrupts --
|
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout
|
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout
|
fast_irq(01) <= cfs_irq; -- custom functions subsystem
|
fast_irq(01) <= cfs_irq; -- custom functions subsystem
|
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) data received
|
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) RX interrupt
|
fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) sending done
|
fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) TX interrupt
|
fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) data received
|
fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) RX interrupt
|
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) sending done
|
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) TX interrupt
|
fast_irq(06) <= spi_irq; -- SPI transmission done
|
fast_irq(06) <= spi_irq; -- SPI idle
|
fast_irq(07) <= twi_irq; -- TWI transmission done
|
fast_irq(07) <= twi_irq; -- TWI idle
|
fast_irq(08) <= xirq_irq; -- external interrupt controller
|
fast_irq(08) <= xirq_irq; -- external interrupt controller
|
fast_irq(09) <= neoled_irq; -- NEOLED buffer free
|
fast_irq(09) <= neoled_irq; -- NEOLED buffer free
|
fast_irq(10) <= slink_rx_irq; -- SLINK data received
|
fast_irq(10) <= slink_rx_irq; -- SLINK RX interrupt
|
fast_irq(11) <= slink_tx_irq; -- SLINK data send
|
fast_irq(11) <= slink_tx_irq; -- SLINK TX interrupt
|
--
|
--
|
fast_irq(12) <= '0'; -- reserved
|
fast_irq(12) <= '0'; -- reserved
|
fast_irq(13) <= '0'; -- reserved
|
fast_irq(13) <= '0'; -- reserved
|
fast_irq(14) <= '0'; -- reserved
|
fast_irq(14) <= '0'; -- reserved
|
fast_irq(15) <= '0'; -- reserved
|
fast_irq(15) <= '0'; -- LOWEST PRIORITY - reserved
|
|
|
|
|
-- CPU Instruction Cache ------------------------------------------------------------------
|
-- CPU Instruction Cache ------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_icache_inst_true:
|
neorv32_icache_inst_true:
|
Line 648... |
Line 647... |
|
|
-- fence operation (unused) --
|
-- fence operation (unused) --
|
p_bus.fence <= cpu_d.fence or cpu_i.fence;
|
p_bus.fence <= cpu_d.fence or cpu_i.fence;
|
|
|
-- bus response --
|
-- bus response --
|
bus_response: process(resp_bus, bus_keeper_err)
|
bus_response: process(resp_bus)
|
variable rdata_v : std_ulogic_vector(data_width_c-1 downto 0);
|
variable rdata_v : std_ulogic_vector(data_width_c-1 downto 0);
|
variable ack_v : std_ulogic;
|
variable ack_v : std_ulogic;
|
variable err_v : std_ulogic;
|
variable err_v : std_ulogic;
|
begin
|
begin
|
rdata_v := (others => '0');
|
rdata_v := (others => '0');
|
Line 663... |
Line 662... |
ack_v := ack_v or resp_bus(i).ack; -- acknowledge
|
ack_v := ack_v or resp_bus(i).ack; -- acknowledge
|
err_v := err_v or resp_bus(i).err; -- error
|
err_v := err_v or resp_bus(i).err; -- error
|
end loop; -- i
|
end loop; -- i
|
p_bus.rdata <= rdata_v; -- processor bus: CPU transfer data input
|
p_bus.rdata <= rdata_v; -- processor bus: CPU transfer data input
|
p_bus.ack <= ack_v; -- processor bus: CPU transfer ACK input
|
p_bus.ack <= ack_v; -- processor bus: CPU transfer ACK input
|
p_bus.err <= err_v or bus_keeper_err; -- processor bus: CPU transfer data bus error input
|
p_bus.err <= err_v; -- processor bus: CPU transfer data bus error input
|
end process;
|
end process;
|
|
|
|
|
-- Processor-Internal Bus Keeper (BUS_KEEPER) ---------------------------------------------
|
-- Bus Keeper (BUSKEEPER) -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_bus_keeper_inst: neorv32_bus_keeper
|
neorv32_bus_keeper_inst: neorv32_bus_keeper
|
generic map (
|
generic map (
|
-- External memory interface --
|
-- External memory interface --
|
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
|
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
|
Line 683... |
Line 682... |
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
|
)
|
)
|
port map (
|
port map (
|
-- host access --
|
-- host access --
|
clk_i => clk_i, -- global clock line
|
clk_i => clk_i, -- global clock line
|
rstn_i => sys_rstn, -- global reset line, low-active
|
rstn_i => sys_rstn, -- global reset line, low-active, use as async
|
addr_i => p_bus.addr, -- address
|
addr_i => p_bus.addr, -- address
|
rden_i => p_bus.re, -- read enable
|
rden_i => io_rden, -- read enable
|
wren_i => p_bus.we, -- write enable
|
wren_i => io_wren, -- byte write enable
|
ack_i => p_bus.ack, -- transfer acknowledge from bus system
|
data_o => resp_bus(RESP_BUSKEEPER).rdata, -- data out
|
err_i => p_bus.err, -- transfer error from bus system
|
ack_o => resp_bus(RESP_BUSKEEPER).ack, -- transfer acknowledge
|
err_o => bus_keeper_err -- bus error
|
err_o => resp_bus(RESP_BUSKEEPER).err, -- transfer error
|
|
-- bus monitoring --
|
|
bus_addr_i => p_bus.addr, -- address
|
|
bus_rden_i => p_bus.re, -- read enable
|
|
bus_wren_i => p_bus.we, -- write enable
|
|
bus_ack_i => p_bus.ack, -- transfer acknowledge from bus system
|
|
bus_err_i => p_bus.err -- transfer error from bus system
|
);
|
);
|
|
|
|
|
-- Processor-Internal Instruction Memory (IMEM) -------------------------------------------
|
-- Processor-Internal Instruction Memory (IMEM) -------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 1349... |
Line 1354... |
generic map (
|
generic map (
|
-- General --
|
-- General --
|
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
|
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
|
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
|
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
|
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
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_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
|
|
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
|
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
|
-- Extension Options --
|
-- Extension Options --
|
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
|
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
|
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
|
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
|
-- Hardware Performance Monitors (HPM) --
|
|
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
|
|
-- internal Instruction memory --
|
-- internal Instruction memory --
|
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
|
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
|
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
|
-- Internal Data memory --
|
-- Internal Data memory --
|
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
|
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
|