Line 58... |
Line 58... |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode 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.?
|
-- 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
|
-- 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_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
|
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
|
-- Internal Instruction memory --
|
-- Internal Instruction memory --
|
Line 81... |
Line 82... |
IO_SPI_USE : boolean := true; -- implement serial peripheral interface (SPI)?
|
IO_SPI_USE : boolean := true; -- implement serial peripheral interface (SPI)?
|
IO_TWI_USE : boolean := true; -- implement two-wire interface (TWI)?
|
IO_TWI_USE : boolean := true; -- implement two-wire interface (TWI)?
|
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
|
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
|
IO_TRNG_USE : boolean := false; -- implement true random number generator (TRNG)?
|
IO_TRNG_USE : boolean := false; -- implement true random number generator (TRNG)?
|
IO_CFU_USE : boolean := false -- implement custom functions unit (CFU)?
|
IO_CFU0_USE : boolean := false; -- implement custom functions unit 0 (CFU0)?
|
|
IO_CFU1_USE : boolean := false -- implement custom functions unit 1 (CFU1)?
|
);
|
);
|
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 117... |
Line 119... |
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
|
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
|
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
|
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
|
-- PWM (available if IO_PWM_USE = true) --
|
-- PWM (available if IO_PWM_USE = true) --
|
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
|
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
|
-- Interrupts --
|
-- Interrupts --
|
|
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_USE = false
|
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
|
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
|
mext_irq_i : in std_ulogic := '0' -- machine external interrupt
|
mext_irq_i : in std_ulogic := '0' -- machine external interrupt
|
);
|
);
|
end neorv32_top;
|
end neorv32_top;
|
|
|
Line 149... |
Line 152... |
signal wdt_cg_en : std_ulogic;
|
signal wdt_cg_en : std_ulogic;
|
signal uart_cg_en : std_ulogic;
|
signal uart_cg_en : std_ulogic;
|
signal spi_cg_en : std_ulogic;
|
signal spi_cg_en : std_ulogic;
|
signal twi_cg_en : std_ulogic;
|
signal twi_cg_en : std_ulogic;
|
signal pwm_cg_en : std_ulogic;
|
signal pwm_cg_en : std_ulogic;
|
signal cfu_cg_en : std_ulogic;
|
signal cfu0_cg_en : std_ulogic;
|
|
signal cfu1_cg_en : std_ulogic;
|
|
|
-- bus interface --
|
-- bus interface --
|
type bus_interface_t is record
|
type bus_interface_t is record
|
addr : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
addr : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
|
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
|
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
|
Line 197... |
Line 201... |
signal pwm_ack : std_ulogic;
|
signal pwm_ack : std_ulogic;
|
signal wdt_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal wdt_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal wdt_ack : std_ulogic;
|
signal wdt_ack : std_ulogic;
|
signal trng_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal trng_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal trng_ack : std_ulogic;
|
signal trng_ack : std_ulogic;
|
signal cfu_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cfu0_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cfu_ack : std_ulogic;
|
signal cfu0_ack : std_ulogic;
|
|
signal cfu1_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
|
signal cfu1_ack : std_ulogic;
|
signal sysinfo_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal sysinfo_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal sysinfo_ack : std_ulogic;
|
signal sysinfo_ack : std_ulogic;
|
|
|
-- IRQs --
|
-- IRQs --
|
signal mtime_irq : std_ulogic;
|
signal mtime_irq : std_ulogic;
|
Line 210... |
Line 216... |
signal gpio_irq : std_ulogic;
|
signal gpio_irq : std_ulogic;
|
signal wdt_irq : std_ulogic;
|
signal wdt_irq : std_ulogic;
|
signal uart_irq : std_ulogic;
|
signal uart_irq : std_ulogic;
|
signal spi_irq : std_ulogic;
|
signal spi_irq : std_ulogic;
|
signal twi_irq : std_ulogic;
|
signal twi_irq : std_ulogic;
|
signal cfu_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
|
|
|
begin
|
begin
|
Line 277... |
Line 282... |
if (sys_rstn = '0') then
|
if (sys_rstn = '0') then
|
clk_div <= (others => '0');
|
clk_div <= (others => '0');
|
clk_div_ff <= (others => '0');
|
clk_div_ff <= (others => '0');
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- fresh clocks anyone? --
|
-- fresh clocks anyone? --
|
if ((wdt_cg_en or uart_cg_en or spi_cg_en or twi_cg_en or pwm_cg_en or cfu_cg_en) = '1') then
|
if ((wdt_cg_en or uart_cg_en or spi_cg_en or twi_cg_en or pwm_cg_en or cfu0_cg_en or cfu1_cg_en) = '1') then
|
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
|
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
|
end if;
|
end if;
|
clk_div_ff <= clk_div;
|
clk_div_ff <= clk_div;
|
end if;
|
end if;
|
end process clock_generator;
|
end process clock_generator;
|
Line 316... |
Line 321... |
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.?
|
-- 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
|
-- Physical Memory Protection (PMP) --
|
-- Physical Memory Protection (PMP) --
|
PMP_USE => PMP_USE, -- implement PMP?
|
PMP_USE => PMP_USE, -- implement PMP?
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 8)
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 8)
|
PMP_GRANULARITY => PMP_GRANULARITY -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
|
PMP_GRANULARITY => PMP_GRANULARITY -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
|
)
|
)
|
Line 362... |
Line 368... |
-- advanced memory control --
|
-- advanced memory control --
|
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
|
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
|
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(0) <= wdt_irq; -- highest priority
|
fast_irq(0) <= wdt_irq; -- highest priority, watchdog timeout interrupt
|
fast_irq(1) <= gpio_irq or cfu_irq; -- can be triggered by GPIO pin-change or CFU
|
fast_irq(1) <= gpio_irq; -- GPIO input pin-change interrupt
|
fast_irq(2) <= uart_irq;
|
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 Crossbar Switch --------------------------------------------------------------------
|
-- CPU Crossbar Switch --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 413... |
Line 419... |
p_bus_err_i => p_bus.err -- bus transfer error
|
p_bus_err_i => p_bus.err -- bus transfer error
|
);
|
);
|
|
|
-- processor bus: CPU data input --
|
-- processor bus: CPU data input --
|
p_bus.rdata <= (imem_rdata or dmem_rdata or bootrom_rdata) or wishbone_rdata or (gpio_rdata or mtime_rdata or uart_rdata or
|
p_bus.rdata <= (imem_rdata or dmem_rdata or bootrom_rdata) or wishbone_rdata or (gpio_rdata or mtime_rdata or uart_rdata or
|
spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or cfu_rdata or sysinfo_rdata);
|
spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or cfu0_rdata or cfu1_rdata or sysinfo_rdata);
|
|
|
-- processor bus: CPU data ACK input --
|
-- processor bus: CPU data ACK input --
|
p_bus.ack <= (imem_ack or dmem_ack or bootrom_ack) or wishbone_ack or (gpio_ack or mtime_ack or uart_ack or
|
p_bus.ack <= (imem_ack or dmem_ack or bootrom_ack) or wishbone_ack or (gpio_ack or mtime_ack or uart_ack or
|
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or cfu_ack or sysinfo_ack);
|
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or cfu0_ack or cfu1_ack or sysinfo_ack);
|
|
|
-- processor bus: CPU data bus error input --
|
-- processor bus: CPU data bus error input --
|
p_bus.err <= wishbone_err;
|
p_bus.err <= wishbone_err;
|
|
|
|
|
Line 664... |
Line 670... |
neorv32_mtime_inst_false:
|
neorv32_mtime_inst_false:
|
if (IO_MTIME_USE = false) generate
|
if (IO_MTIME_USE = false) generate
|
mtime_rdata <= (others => '0');
|
mtime_rdata <= (others => '0');
|
mtime_time <= (others => '0');
|
mtime_time <= (others => '0');
|
mtime_ack <= '0';
|
mtime_ack <= '0';
|
mtime_irq <= '0';
|
mtime_irq <= mtime_irq_i; -- use external machine timer interrupt
|
end generate;
|
end generate;
|
|
|
|
|
-- Universal Asynchronous Receiver/Transmitter (UART) -------------------------------------
|
-- Universal Asynchronous Receiver/Transmitter (UART) -------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 833... |
Line 839... |
trng_rdata <= (others => '0');
|
trng_rdata <= (others => '0');
|
trng_ack <= '0';
|
trng_ack <= '0';
|
end generate;
|
end generate;
|
|
|
|
|
-- Custom Functions Unit (CFU) ------------------------------------------------------------
|
-- Custom Functions Unit 0 (CFU0) ---------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cfu_inst_true:
|
neorv32_cfu0_inst_true:
|
if (IO_CFU_USE = true) generate
|
if (IO_CFU0_USE = true) generate
|
neorv32_cfu_inst: neorv32_cfu
|
neorv32_cfu0_inst: neorv32_cfu0
|
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, use as async
|
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 => io_rden, -- read enable
|
rden_i => io_rden, -- read enable
|
wren_i => io_wren, -- write enable
|
wren_i => io_wren, -- write enable
|
data_i => p_bus.wdata, -- data in
|
data_i => p_bus.wdata, -- data in
|
data_o => cfu_rdata, -- data out
|
data_o => cfu0_rdata, -- data out
|
ack_o => cfu_ack, -- transfer acknowledge
|
ack_o => cfu0_ack, -- transfer acknowledge
|
-- clock generator --
|
-- clock generator --
|
clkgen_en_o => cfu_cg_en, -- enable clock generator
|
clkgen_en_o => cfu0_cg_en, -- enable clock generator
|
clkgen_i => clk_gen, -- "clock" inputs
|
clkgen_i => clk_gen -- "clock" inputs
|
-- interrupt --
|
-- custom io --
|
irq_o => cfu_irq
|
-- ...
|
|
);
|
|
end generate;
|
|
|
|
neorv32_cfu0_inst_false:
|
|
if (IO_CFU0_USE = false) generate
|
|
cfu0_rdata <= (others => '0');
|
|
cfu0_ack <= '0';
|
|
cfu0_cg_en <= '0';
|
|
end generate;
|
|
|
|
|
|
-- Custom Functions Unit 1 (CFU1) ---------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
neorv32_cfu1_inst_true:
|
|
if (IO_CFU1_USE = true) generate
|
|
neorv32_cfu1_inst: neorv32_cfu1
|
|
port map (
|
|
-- host access --
|
|
clk_i => clk_i, -- global clock line
|
|
rstn_i => sys_rstn, -- global reset line, low-active, use as async
|
|
addr_i => p_bus.addr, -- address
|
|
rden_i => io_rden, -- read enable
|
|
wren_i => io_wren, -- write enable
|
|
data_i => p_bus.wdata, -- data in
|
|
data_o => cfu1_rdata, -- data out
|
|
ack_o => cfu1_ack, -- transfer acknowledge
|
|
-- clock generator --
|
|
clkgen_en_o => cfu1_cg_en, -- enable clock generator
|
|
clkgen_i => clk_gen -- "clock" inputs
|
-- custom io --
|
-- custom io --
|
-- ...
|
-- ...
|
);
|
);
|
end generate;
|
end generate;
|
|
|
neorv32_cfu_inst_false:
|
neorv32_cfu1_inst_false:
|
if (IO_CFU_USE = false) generate
|
if (IO_CFU1_USE = false) generate
|
cfu_rdata <= (others => '0');
|
cfu1_rdata <= (others => '0');
|
cfu_ack <= '0';
|
cfu1_ack <= '0';
|
cfu_cg_en <= '0';
|
cfu1_cg_en <= '0';
|
cfu_irq <= '0';
|
|
end generate;
|
end generate;
|
|
|
|
|
-- System Configuration Information Memory (SYSINFO) --------------------------------------
|
-- System Configuration Information Memory (SYSINFO) --------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 893... |
Line 927... |
IO_SPI_USE => IO_SPI_USE, -- implement serial peripheral interface (SPI)?
|
IO_SPI_USE => IO_SPI_USE, -- implement serial peripheral interface (SPI)?
|
IO_TWI_USE => IO_TWI_USE, -- implement two-wire interface (TWI)?
|
IO_TWI_USE => IO_TWI_USE, -- implement two-wire interface (TWI)?
|
IO_PWM_USE => IO_PWM_USE, -- implement pulse-width modulation unit (PWM)?
|
IO_PWM_USE => IO_PWM_USE, -- implement pulse-width modulation unit (PWM)?
|
IO_WDT_USE => IO_WDT_USE, -- implement watch dog timer (WDT)?
|
IO_WDT_USE => IO_WDT_USE, -- implement watch dog timer (WDT)?
|
IO_TRNG_USE => IO_TRNG_USE, -- implement true random number generator (TRNG)?
|
IO_TRNG_USE => IO_TRNG_USE, -- implement true random number generator (TRNG)?
|
IO_CFU_USE => IO_CFU_USE -- implement custom functions unit (CFU)?
|
IO_CFU0_USE => IO_CFU0_USE, -- implement custom functions unit 0 (CFU0)?
|
|
IO_CFU1_USE => IO_CFU1_USE -- implement custom functions unit 1 (CFU1)?
|
)
|
)
|
port map (
|
port map (
|
-- host access --
|
-- host access --
|
clk_i => clk_i, -- global clock line
|
clk_i => clk_i, -- global clock line
|
addr_i => p_bus.addr, -- address
|
addr_i => p_bus.addr, -- address
|