Line 49... |
Line 49... |
generic (
|
generic (
|
-- General --
|
-- General --
|
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
|
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
|
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader?
|
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader?
|
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
|
HW_THREAD_ID : std_ulogic_vector(31 downto 0) := (others => '0'); -- hardware thread id (hartid)
|
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
|
-- 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 extensions?
|
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit manipulation 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?
|
Line 91... |
Line 91... |
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
|
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
|
IO_PWM_EN : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_PWM_EN : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
|
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
|
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
|
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
|
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
|
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
|
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := (others => '0') -- custom CFS configuration generic
|
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
|
|
IO_NCO_EN : boolean := true -- implement numerically-controlled oscillator (NCO)?
|
);
|
);
|
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 131... |
Line 132... |
-- PWM (available if IO_PWM_EN = true) --
|
-- PWM (available if IO_PWM_EN = true) --
|
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
|
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
|
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
|
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
|
cfs_in_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- custom CFS inputs conduit
|
cfs_in_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- custom CFS inputs conduit
|
cfs_out_o : out std_ulogic_vector(31 downto 0); -- custom CFS outputs conduit
|
cfs_out_o : out std_ulogic_vector(31 downto 0); -- custom CFS outputs conduit
|
|
-- NCO output (available if IO_NCO_EN = true) --
|
|
nco_o : out std_ulogic_vector(02 downto 0); -- numerically-controlled oscillator channels
|
-- system time input from external MTIME (available if IO_MTIME_EN = false) --
|
-- system time input from external MTIME (available if IO_MTIME_EN = false) --
|
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
|
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
|
-- Interrupts --
|
-- Interrupts --
|
soc_firq_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- fast interrupt channels
|
soc_firq_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- fast interrupt channels
|
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
|
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
|
Line 174... |
Line 177... |
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 cfs_cg_en : std_ulogic;
|
signal cfs_cg_en : std_ulogic;
|
|
signal nco_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 227... |
Line 231... |
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 cfs_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cfs_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
signal cfs_err : std_ulogic;
|
signal cfs_err : std_ulogic;
|
signal cfs_ack : std_ulogic;
|
signal cfs_ack : std_ulogic;
|
|
signal nco_rdata : std_ulogic_vector(data_width_c-1 downto 0);
|
|
signal nco_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 313... |
Line 319... |
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 cfs_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 cfs_cg_en or nco_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 538... |
Line 544... |
p_bus_lock_o => p_bus.lock, -- locked/exclusive access
|
p_bus_lock_o => p_bus.lock, -- locked/exclusive access
|
p_bus_ack_i => p_bus.ack, -- bus transfer acknowledge
|
p_bus_ack_i => p_bus.ack, -- bus transfer acknowledge
|
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 transfer 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 cfs_rdata or sysinfo_rdata);
|
spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or cfs_rdata or nco_rdata or sysinfo_rdata);
|
|
|
-- processor bus: CPU data ACK input --
|
-- processor bus: CPU transfer 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 cfs_ack or sysinfo_ack);
|
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or cfs_ack or nco_ack or sysinfo_ack);
|
|
|
-- processor bus: CPU data bus error input --
|
-- processor bus: CPU transfer data bus error input --
|
p_bus.err <= wishbone_err or cfs_err;
|
p_bus.err <= wishbone_err or cfs_err;
|
|
|
-- current CPU privilege level --
|
-- current CPU privilege level --
|
p_bus.priv <= cpu_i.priv; -- cpu_i.priv == cpu_d.priv
|
p_bus.priv <= cpu_i.priv; -- cpu_i.priv == cpu_d.priv
|
|
|
Line 990... |
Line 996... |
pwm_cg_en <= '0';
|
pwm_cg_en <= '0';
|
pwm_o <= (others => '0');
|
pwm_o <= (others => '0');
|
end generate;
|
end generate;
|
|
|
|
|
|
-- Numerically-Controlled Oscillator (NCO) ------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
neorv32_nco_inst_true:
|
|
if (IO_NCO_EN = true) generate
|
|
neorv32_nco_inst: neorv32_nco
|
|
port map (
|
|
-- host access --
|
|
clk_i => clk_i, -- global clock line
|
|
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 => nco_rdata, -- data out
|
|
ack_o => nco_ack, -- transfer acknowledge
|
|
-- clock generator --
|
|
clkgen_en_o => nco_cg_en, -- enable clock generator
|
|
clkgen_i => clk_gen,
|
|
-- NCO output --
|
|
nco_o => nco_o
|
|
);
|
|
end generate;
|
|
|
|
neorv32_nco_inst_false:
|
|
if (IO_NCO_EN = false) generate
|
|
nco_rdata <= (others => '0');
|
|
nco_ack <= '0';
|
|
nco_cg_en <= '0';
|
|
nco_o <= (others => '0');
|
|
end generate;
|
|
|
|
|
-- True Random Number Generator (TRNG) ----------------------------------------------------
|
-- True Random Number Generator (TRNG) ----------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_trng_inst_true:
|
neorv32_trng_inst_true:
|
if (IO_TRNG_EN = true) generate
|
if (IO_TRNG_EN = true) generate
|
neorv32_trng_inst: neorv32_trng
|
neorv32_trng_inst: neorv32_trng
|
Line 1045... |
Line 1082... |
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
|
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
|
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
|
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
|
IO_PWM_EN => IO_PWM_EN, -- implement pulse-width modulation unit (PWM)?
|
IO_PWM_EN => IO_PWM_EN, -- implement pulse-width modulation unit (PWM)?
|
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
|
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
|
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
|
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
|
IO_CFS_EN => IO_CFS_EN -- implement custom functions subsystem (CFS)?
|
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
|
|
IO_NCO_EN => IO_NCO_EN -- implement numerically-controlled oscillator (NCO)?
|
)
|
)
|
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
|