Merge branch 'main' into rework_bootloader

This commit is contained in:
stnolting 2025-04-04 05:04:31 +02:00
commit 258400a2f2
25 changed files with 835 additions and 305 deletions

View file

@ -29,6 +29,8 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 01.04.2025 | 1.11.2.4 | :bug: fix bug in PWM clock prescaler | [#1222](https://github.com/stnolting/neorv32/pull/1222) |
| 29.03.2025 | 1.11.2.3 | :sparkles: add optional 32 hardware spinlocks (`HWSPINLOCK` module) | [#1220](https://github.com/stnolting/neorv32/pull/1220) |
| 24.03.2025 | 1.11.2.2 | TWD: add separate RX/TX FIFO configuration; add dummy response (if TX FIFO is empty); add optional no-ACK on read access if TX FIFO is empty | [#1210](https://github.com/stnolting/neorv32/pull/1210) |
| 21.03.2025 | 1.11.2.1 | :warning: remove clock gating option | [#1214](https://github.com/stnolting/neorv32/pull/1214) |
| 15.03.2025 | [**:rocket:1.11.2**](https://github.com/stnolting/neorv32/releases/tag/v1.11.2) | **New release** | |

View file

@ -188,6 +188,7 @@ for custom tightly-coupled co-processors, accelerators or interfaces
data transfers and conversions
* cyclic redundancy check unit ([CRC](https://stnolting.github.io/neorv32/#_cyclic_redundancy_check_crc)) to test
data integrity (CRC8/16/32)
* 32 dedicated hardware spinlocks ([HWSPINLOCK](https://stnolting.github.io/neorv32/#_hardware_spinlocks_hwspinlock))
**Debugging**

View file

@ -566,14 +566,27 @@ To benchmark a certain processor configuration for its setup-specific CPI value
==== `A` ISA Extension
The `A` ISA extension adds instructions for bit-manipulation operations.
This ISA extension cannot be enabled by a specific generic. Instead, it is enabled if a specific set of
sub-extensions is enabled. The `A` extension is shorthand for the following set of other extensions:
The `A` ISA extension adds instructions and mechanisms for atomic memory operations hat can be used to
manage mutually-exclusive access to shared resources. Note that this ISA extension cannot be enabled by
a specific generic. Instead, it is enabled if a specific set of sub-extensions is enabled. The `A`
extension is shorthand for the following set of other extensions:
* <<_zaamo_isa_extension>> - Atomic read-modify-write instructions.
* <<_zalrsc_isa_extension>> - Atomic reservation-set instructions.
A processor configuration which implements `A` must implement all of the above extensions.
.Atomic Variable in C Languages
[NOTE]
The C `_Atomic` specifier should be used for atomic variables.
See section <<_coherence_example>> for more information.
.Hardware-Based Spinlocks
[TIP]
The `A` ISA extension and the according sub-extensions require a lot of additional logic that increases
the size of the processor. Furthermore, the `A` instructions require special attention to maintain
<<_memory_coherence>>. Alternatively (or as a further addition), hardware-based spinlocks can be enabled,
which can be used to build more complex synchronization structures without the need for the complex `A`
ISA extension or special attention to memory coherence. See the <<_hardware_spinlocks_hwspinlock>> module
description for more information.
==== `B` ISA Extension
@ -692,7 +705,7 @@ RISC-V specs. Also, custom trap codes for <<_mcause>> are implemented.
==== `Zaamo` ISA Extension
The `Zaamo` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension,`A`>> ISA extension and compromises
The `Zaamo` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension>> and compromises
instructions for read-modify-write <<_atomic_memory_access>> operations. It is enabled by the top's
<<_processor_top_entity_generics, `RISCV_ISA_Zaamo`>> generic.
@ -718,7 +731,7 @@ is raised, respectively.
==== `Zalrsc` ISA Extension
The `Zalrsc` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension,`A`>> ISA extension and compromises
The `Zalrsc` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension>> and compromises
instructions for reservation-set <<_atomic_memory_access>> operations. It is enabled by the top's
<<_processor_top_entity_generics, `RISCV_ISA_Zalrsc`>> generic.

View file

@ -206,6 +206,7 @@ rtl/core
├-neorv32_fifo.vhd - Generic FIFO component
├-neorv32_gpio.vhd - General purpose input/output port unit
├-neorv32_gptmr.vhd - General purpose 32-bit timer
├-neorv32_hwspinlock.vhd - Hardware spinlocks
├-neorv32_imem.vhd - Generic processor-internal instruction memory
├-neorv32_neoled.vhd - NeoPixel (TM) compatible smart LED interface
├-neorv32_onewire.vhd - One-Wire serial interface controller

View file

@ -42,6 +42,7 @@ image::neorv32_processor.png[align=center]
* _optional_ autonomous direct memory access controller (<<_direct_memory_access_controller_dma,**DMA**>>)
* _optional_ stream link interface (<<_stream_link_interface_slink,**SLINK**>>), AXI4-Stream compatible
* _optional_ cyclic redundancy check unit (<<_cyclic_redundancy_check_crc,**CRC**>>)
* _optional_ hardware spinlocks (32x) (<<_hardware_spinlocks_hwspinlock,**HWSPINLOCK**>>)
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>)
* _optional_ system configuration information memory to determine hardware configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)
@ -306,6 +307,7 @@ The generic type "`suv(x:y)`" is an abbreviation for "`std_ulogic_vector(x downt
| `IO_SLINK_RX_FIFO` | natural | 1 | SLINK RX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_SLINK_TX_FIFO` | natural | 1 | SLINK TX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_CRC_EN` | boolean | false | Implement the <<_cyclic_redundancy_check_crc>> unit.
| `IO_HWSPINLOCK_EN` | boolean | false | Implement the <<_hardware_spinlocks_hwspinlock>> module.
|=======================
@ -319,10 +321,6 @@ by the top's `clk_i` signal. This clock signal is used by all internal registers
on the **rising edge** of this clock signal. External "clocks" like the OCD's JTAG clock or the SDI's serial clock
are synchronized into the processor's clock domain before being used as "general logic signal" (and not as a dedicated clock).
.CPU Clock Gating
[NOTE]
The CPU core provides an optional clock-gating feature to switch off large parts of the core when sleep mode is entered.
See section <<_cpu_clock_gating>> for more information.
==== Peripheral Clocks
@ -696,6 +694,43 @@ will cause a cache miss that will fetch up-to-date data from the memory system.
Executing any fence instruction will stall the CPU until all the requested ordering/synchronization
steps are completed.
===== Coherence Example
The following C example shows how to declare and use an atomic variable using the`_Atomic` specifier:
.Atomic Variables - C Source Code
[source, c]
----
_Atomic int counter = 0;
counter = 3;
counter++;
----
The initial assignment `counter = 0` is translated into a store-word instruction (`sw`) that is
automatically encapsulated within two `fence` instructions. This guarantees <<_memory_coherence>> as each
FENCE will synchronize the CPU's data cache cache with upstream/main memory.
.Atomic Variables - According RISC-V Assembly Code
[source, assembly]
----
li a3,3
li a4,1
fence rw,w
sw a3,0(a2)
fence rw,rw
amoadd.w.aqrl zero,a4,(a2)
----
The increment (`counter++`) is implemented as RISC-V atomic memory operation (`amoadd`). However, the
compiler does not encapsulate this in within FENCE instructions. Hence, the altered atomic variable
is **not** updated in the CPU's data cache (but in upstream/main memory).
The above example clearly shows that special attention must be paid to memory coherence when using
atomic memory operations.
<<<
// ####################################################################################################################
@ -851,4 +886,6 @@ include::soc_neoled.adoc[]
include::soc_gptmr.adoc[]
include::soc_hwspinlock.adoc[]
include::soc_sysinfo.adoc[]

View file

@ -0,0 +1,50 @@
<<<
:sectnums:
==== Hardware Spinlocks (HWSPINLOCK)
[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files: | neorv32_hwspinlock.vhd |
| Software driver files: | neorv32_hwspinlock.c | link:https://stnolting.github.io/neorv32/sw/neorv32__hwspinlock_8c.html[Online software reference (Doxygen)]
| | neorv32_hwspinlock.h | link:https://stnolting.github.io/neorv32/sw/neorv32__hwspinlock_8h.html[Online software reference (Doxygen)]
| Top entity ports: | none |
| Configuration generics: | `IO_HWSPINLOCK_EN` | implement hardware spinlocks when `true`
| CPU interrupts: | none |
|=======================
**Overview**
The HWSPINLOCK module provides 32 binary hardware spinlocks that can be used to manage mutually-exclusive access
to shared resources. Each hardware spinlock is a one-bit flag, mapped to a different address (`LOCK[0]` to `LOCK[31]`).
Software interacts with each spinlock with one of the following operations:
* `LOCK[i]` read access: Attempt to claim the lock. Read value is non-zero if the lock was successfully claimed,
or zero if the lock had already been claimed by a previous read.
* `LOCK[i]` write access (any value): Release the lock. The next attempt to claim the lock will succeed.
Hence, all `LOCK` register cause _side-effects_ when being accessed.
For debugging purposes, the current state of all 32 spinlocks can be observed via the read-only `STATUS` register.
.Advantages over RISC-V atomic memory operations
[TIP]
Using the HWSPINLOCK module instead of software-managed synchronization primitives based on the <<_a_isa_extension>>
reduces hardware complexity (smaller size) and also simplifies <<_memory_coherence>>
.Example Program
[TIP]
A simple example program can be found in `sw/example/demo_dual_core_hwspinlock`.
**Register Map**
.HWSPINLOCK module register map (`struct NEORV32_HWSPINLOCK`)
[cols="<2,<2,^1,^1,<6"]
[options="header",grid="rows"]
|=======================
| Address | Name [C] | Bit(s) | R/W | Function
| `0xfff30000` | `LOCK[0]` | 0 | r/w | Binary hardware spinlock 0
| ... | ... | ... | ... | Binary hardware spinlocks 1 to 30
| `0xfff3007C` | `LOCK[31]` | 0 | r/w | Binary hardware spinlock 31
| `0xfff30080` | `STATUS` | 31:0 | r/- | Status of all spinlocks (one bit per lock, e.g. bit 0 represents the state of `LOCK[0]`)
|=======================

View file

@ -8,7 +8,7 @@
| Hardware source files: | neorv32_sysinfo.vhd |
| Software driver files: | neorv32_sysinfo.h | link:https://stnolting.github.io/neorv32/sw/neorv32__sysinfo_8h.html[Online software reference (Doxygen)]
| Top entity ports: | none |
| Configuration generics: | * | most of the top's configuration generics
| Configuration generics: | all | most of the top's configuration generics
| CPU interrupts: | none |
|=======================
@ -72,38 +72,38 @@ Bit fields in this register are set to all-zero if the according memory system i
[options="header",grid="all"]
|=======================
| Bit | Name [C] | Description
| `0` | `SYSINFO_SOC_BOOTLOADER` | set if processor-internal bootloader is implemented (via top's `BOOT_MODE_SELECT` generic; see <<_boot_configuration>>)
| `1` | `SYSINFO_SOC_XBUS` | set if external Wishbone bus interface is implemented (via top's `XBUS_EN` generic)
| `2` | `SYSINFO_SOC_MEM_INT_IMEM` | set if processor-internal DMEM is implemented (via top's `MEM_INT_IMEM_EN` generic)
| `3` | `SYSINFO_SOC_MEM_INT_DMEM` | set if processor-internal IMEM is implemented (via top's `MEM_INT_DMEM_EN` generic)
| `4` | `SYSINFO_SOC_OCD` | set if on-chip debugger is implemented (via top's `OCD_EN` generic)
| `5` | `SYSINFO_SOC_ICACHE` | set if processor-internal instruction cache is implemented (via top's `ICACHE_EN` generic)
| `6` | `SYSINFO_SOC_DCACHE` | set if processor-internal data cache is implemented (via top's `DCACHE_EN` generic)
| `7` | - |_reserved_, read as zero
| `8` | `SYSINFO_SOC_XBUS_CACHE` | set if external bus interface cache is implemented (via top's `XBUS_CACHE_EN` generic)
| `9` | - |_reserved_, read as zero
| `10` | - |_reserved_, read as zero
| `11` | `SYSINFO_SOC_OCD_AUTH` | set if on-chip debugger authentication is implemented (via top's `OCD_AUTHENTICATION` generic)
| `12` | `SYSINFO_SOC_IMEM_ROM` | set if processor-internal IMEM is implemented as pre-initialized ROM (via top's `BOOT_MODE_SELECT` generic; see <<_boot_configuration>>)
| `13` | `SYSINFO_SOC_IO_TWD` | set if TWD is implemented (via top's `IO_TWD_EN` generic)
| `14` | `SYSINFO_SOC_IO_DMA` | set if direct memory access controller is implemented (via top's `IO_DMA_EN` generic)
| `15` | `SYSINFO_SOC_IO_GPIO` | set if GPIO is implemented (via top's `IO_GPIO_EN` generic)
| `16` | `SYSINFO_SOC_IO_CLINT` | set if CLINT is implemented (via top's `IO_CLINT_EN` generic)
| `17` | `SYSINFO_SOC_IO_UART0` | set if primary UART0 is implemented (via top's `IO_UART0_EN` generic)
| `18` | `SYSINFO_SOC_IO_SPI` | set if SPI is implemented (via top's `IO_SPI_EN` generic)
| `19` | `SYSINFO_SOC_IO_TWI` | set if TWI is implemented (via top's `IO_TWI_EN` generic)
| `20` | `SYSINFO_SOC_IO_PWM` | set if PWM is implemented (via top's `IO_PWM_NUM_CH` generic)
| `21` | `SYSINFO_SOC_IO_WDT` | set if WDT is implemented (via top's `IO_WDT_EN` generic)
| `22` | `SYSINFO_SOC_IO_CFS` | set if custom functions subsystem is implemented (via top's `IO_CFS_EN` generic)
| `23` | `SYSINFO_SOC_IO_TRNG` | set if TRNG is implemented (via top's `IO_TRNG_EN` generic)
| `24` | `SYSINFO_SOC_IO_SDI` | set if SDI is implemented (via top's `IO_SDI_EN` generic)
| `25` | `SYSINFO_SOC_IO_UART1` | set if secondary UART1 is implemented (via top's `IO_UART1_EN` generic)
| `26` | `SYSINFO_SOC_IO_NEOLED` | set if NEOLED is implemented (via top's `IO_NEOLED_EN` generic)
| `27` | - |_reserved_, read as zero
| `28` | `SYSINFO_SOC_IO_GPTMR` | set if GPTMR is implemented (via top's `IO_GPTMR_EN` generic)
| `29` | `SYSINFO_SOC_IO_SLINK` | set if stream link interface is implemented (via top's `IO_SLINK_EN` generic)
| `30` | `SYSINFO_SOC_IO_ONEWIRE` | set if ONEWIRE interface is implemented (via top's `IO_ONEWIRE_EN` generic)
| `31` | `SYSINFO_SOC_IO_CRC` | set if cyclic redundancy check unit is implemented (via top's `IO_CRC_EN` generic)
| `0` | `SYSINFO_SOC_BOOTLOADER` | set if processor-internal bootloader is implemented (via top's `BOOT_MODE_SELECT` generic; see <<_boot_configuration>>)
| `1` | `SYSINFO_SOC_XBUS` | set if external Wishbone bus interface is implemented (via top's `XBUS_EN` generic)
| `2` | `SYSINFO_SOC_MEM_INT_IMEM` | set if processor-internal DMEM is implemented (via top's `MEM_INT_IMEM_EN` generic)
| `3` | `SYSINFO_SOC_MEM_INT_DMEM` | set if processor-internal IMEM is implemented (via top's `MEM_INT_DMEM_EN` generic)
| `4` | `SYSINFO_SOC_OCD` | set if on-chip debugger is implemented (via top's `OCD_EN` generic)
| `5` | `SYSINFO_SOC_ICACHE` | set if processor-internal instruction cache is implemented (via top's `ICACHE_EN` generic)
| `6` | `SYSINFO_SOC_DCACHE` | set if processor-internal data cache is implemented (via top's `DCACHE_EN` generic)
| `7` | - |_reserved_, read as zero
| `8` | `SYSINFO_SOC_XBUS_CACHE` | set if external bus interface cache is implemented (via top's `XBUS_CACHE_EN` generic)
| `9` | - |_reserved_, read as zero
| `10` | - |_reserved_, read as zero
| `11` | `SYSINFO_SOC_OCD_AUTH` | set if on-chip debugger authentication is implemented (via top's `OCD_AUTHENTICATION` generic)
| `12` | `SYSINFO_SOC_IMEM_ROM` | set if processor-internal IMEM is implemented as pre-initialized ROM (via top's `BOOT_MODE_SELECT` generic; see <<_boot_configuration>>)
| `13` | `SYSINFO_SOC_IO_TWD` | set if TWD is implemented (via top's `IO_TWD_EN` generic)
| `14` | `SYSINFO_SOC_IO_DMA` | set if direct memory access controller is implemented (via top's `IO_DMA_EN` generic)
| `15` | `SYSINFO_SOC_IO_GPIO` | set if GPIO is implemented (via top's `IO_GPIO_EN` generic)
| `16` | `SYSINFO_SOC_IO_CLINT` | set if CLINT is implemented (via top's `IO_CLINT_EN` generic)
| `17` | `SYSINFO_SOC_IO_UART0` | set if primary UART0 is implemented (via top's `IO_UART0_EN` generic)
| `18` | `SYSINFO_SOC_IO_SPI` | set if SPI is implemented (via top's `IO_SPI_EN` generic)
| `19` | `SYSINFO_SOC_IO_TWI` | set if TWI is implemented (via top's `IO_TWI_EN` generic)
| `20` | `SYSINFO_SOC_IO_PWM` | set if PWM is implemented (via top's `IO_PWM_NUM_CH` generic)
| `21` | `SYSINFO_SOC_IO_WDT` | set if WDT is implemented (via top's `IO_WDT_EN` generic)
| `22` | `SYSINFO_SOC_IO_CFS` | set if custom functions subsystem is implemented (via top's `IO_CFS_EN` generic)
| `23` | `SYSINFO_SOC_IO_TRNG` | set if TRNG is implemented (via top's `IO_TRNG_EN` generic)
| `24` | `SYSINFO_SOC_IO_SDI` | set if SDI is implemented (via top's `IO_SDI_EN` generic)
| `25` | `SYSINFO_SOC_IO_UART1` | set if secondary UART1 is implemented (via top's `IO_UART1_EN` generic)
| `26` | `SYSINFO_SOC_IO_NEOLED` | set if NEOLED is implemented (via top's `IO_NEOLED_EN` generic)
| `27` | `SYSINFO_SOC_IO_HWSPINLOCK` | set if HWSPINLOCK is implemented (via top's `IO_HWSPINLOCK_EN` generic)
| `28` | `SYSINFO_SOC_IO_GPTMR` | set if GPTMR is implemented (via top's `IO_GPTMR_EN` generic)
| `29` | `SYSINFO_SOC_IO_SLINK` | set if stream link interface is implemented (via top's `IO_SLINK_EN` generic)
| `30` | `SYSINFO_SOC_IO_ONEWIRE` | set if ONEWIRE interface is implemented (via top's `IO_ONEWIRE_EN` generic)
| `31` | `SYSINFO_SOC_IO_CRC` | set if cyclic redundancy check unit is implemented (via top's `IO_CRC_EN` generic)
|=======================

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 348 KiB

Before After
Before After

View file

@ -0,0 +1,76 @@
-- ================================================================================ --
-- NEORV32 SoC - 32 Binary Hardware Spinlocks (HWSPINLOCK) --
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
-- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. --
-- Licensed under the BSD-3-Clause license, see LICENSE for details. --
-- SPDX-License-Identifier: BSD-3-Clause --
-- ================================================================================ --
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library neorv32;
use neorv32.neorv32_package.all;
entity neorv32_hwspinlock is
port (
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active, async
bus_req_i : in bus_req_t; -- bus request
bus_rsp_o : out bus_rsp_t -- bus response
);
end neorv32_hwspinlock;
architecture neorv32_hwspinlock_rtl of neorv32_hwspinlock is
signal lock_q, sel : std_ulogic_vector(31 downto 0);
begin
-- Spinlocks ------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
spinlock_gen:
for i in 0 to 31 generate
-- binary spinlock --
spinlock: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
lock_q(i) <= '0';
elsif rising_edge(clk_i) then
if (bus_req_i.stb = '1') and (bus_req_i.addr(7) = '0') and (sel(i) = '1') then
lock_q(i) <= not bus_req_i.rw; -- claim on read, release on write
end if;
end if;
end process spinlock;
-- spinlock select --
sel(i) <= '1' when (bus_req_i.addr(6 downto 2) = std_ulogic_vector(to_unsigned(i, 5))) else '0';
end generate; -- /spinlock_gen
-- Bus Response ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
bus_response: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
bus_rsp_o <= rsp_terminate_c;
elsif rising_edge(clk_i) then
bus_rsp_o.ack <= bus_req_i.stb;
bus_rsp_o.err <= '0';
bus_rsp_o.data <= (others => '0');
if (bus_req_i.stb = '1') and (bus_req_i.rw = '0') then
if (bus_req_i.addr(7) = '0') then -- individual lock state
bus_rsp_o.data <= lock_q and sel;
else -- state of all locks
bus_rsp_o.data <= lock_q;
end if;
end if;
end if;
end process bus_response;
end neorv32_hwspinlock_rtl;

View file

@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110202"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110204"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width
@ -57,39 +57,39 @@ package neorv32_package is
constant mem_uncached_begin_c : std_ulogic_vector(31 downto 0) := x"f0000000";
-- IO Address Map (base address must be aligned to the region's size) --
constant iodev_size_c : natural := 64*1024; -- size of a single IO device (bytes)
constant base_io_bootrom_c : std_ulogic_vector(31 downto 0) := x"ffe00000";
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe10000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe20000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe30000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe40000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe50000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe60000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe70000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe80000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe90000"; -- reserved
constant base_io_twd_c : std_ulogic_vector(31 downto 0) := x"ffea0000";
constant base_io_cfs_c : std_ulogic_vector(31 downto 0) := x"ffeb0000";
constant base_io_slink_c : std_ulogic_vector(31 downto 0) := x"ffec0000";
constant base_io_dma_c : std_ulogic_vector(31 downto 0) := x"ffed0000";
constant base_io_crc_c : std_ulogic_vector(31 downto 0) := x"ffee0000";
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffef0000"; -- reserved
constant base_io_pwm_c : std_ulogic_vector(31 downto 0) := x"fff00000";
constant base_io_gptmr_c : std_ulogic_vector(31 downto 0) := x"fff10000";
constant base_io_onewire_c : std_ulogic_vector(31 downto 0) := x"fff20000";
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"fff30000"; -- reserved
constant base_io_clint_c : std_ulogic_vector(31 downto 0) := x"fff40000";
constant base_io_uart0_c : std_ulogic_vector(31 downto 0) := x"fff50000";
constant base_io_uart1_c : std_ulogic_vector(31 downto 0) := x"fff60000";
constant base_io_sdi_c : std_ulogic_vector(31 downto 0) := x"fff70000";
constant base_io_spi_c : std_ulogic_vector(31 downto 0) := x"fff80000";
constant base_io_twi_c : std_ulogic_vector(31 downto 0) := x"fff90000";
constant base_io_trng_c : std_ulogic_vector(31 downto 0) := x"fffa0000";
constant base_io_wdt_c : std_ulogic_vector(31 downto 0) := x"fffb0000";
constant base_io_gpio_c : std_ulogic_vector(31 downto 0) := x"fffc0000";
constant base_io_neoled_c : std_ulogic_vector(31 downto 0) := x"fffd0000";
constant base_io_sysinfo_c : std_ulogic_vector(31 downto 0) := x"fffe0000";
constant base_io_ocd_c : std_ulogic_vector(31 downto 0) := x"ffff0000";
constant iodev_size_c : natural := 64*1024; -- size of a single IO device (bytes)
constant base_io_bootrom_c : std_ulogic_vector(31 downto 0) := x"ffe00000";
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe10000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe20000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe30000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe40000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe50000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe60000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe70000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe80000"; -- reserved
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffe90000"; -- reserved
constant base_io_twd_c : std_ulogic_vector(31 downto 0) := x"ffea0000";
constant base_io_cfs_c : std_ulogic_vector(31 downto 0) := x"ffeb0000";
constant base_io_slink_c : std_ulogic_vector(31 downto 0) := x"ffec0000";
constant base_io_dma_c : std_ulogic_vector(31 downto 0) := x"ffed0000";
constant base_io_crc_c : std_ulogic_vector(31 downto 0) := x"ffee0000";
--constant base_io_???_c : std_ulogic_vector(31 downto 0) := x"ffef0000"; -- reserved
constant base_io_pwm_c : std_ulogic_vector(31 downto 0) := x"fff00000";
constant base_io_gptmr_c : std_ulogic_vector(31 downto 0) := x"fff10000";
constant base_io_onewire_c : std_ulogic_vector(31 downto 0) := x"fff20000";
constant base_io_hwspinlock_c : std_ulogic_vector(31 downto 0) := x"fff30000";
constant base_io_clint_c : std_ulogic_vector(31 downto 0) := x"fff40000";
constant base_io_uart0_c : std_ulogic_vector(31 downto 0) := x"fff50000";
constant base_io_uart1_c : std_ulogic_vector(31 downto 0) := x"fff60000";
constant base_io_sdi_c : std_ulogic_vector(31 downto 0) := x"fff70000";
constant base_io_spi_c : std_ulogic_vector(31 downto 0) := x"fff80000";
constant base_io_twi_c : std_ulogic_vector(31 downto 0) := x"fff90000";
constant base_io_trng_c : std_ulogic_vector(31 downto 0) := x"fffa0000";
constant base_io_wdt_c : std_ulogic_vector(31 downto 0) := x"fffb0000";
constant base_io_gpio_c : std_ulogic_vector(31 downto 0) := x"fffc0000";
constant base_io_neoled_c : std_ulogic_vector(31 downto 0) := x"fffd0000";
constant base_io_sysinfo_c : std_ulogic_vector(31 downto 0) := x"fffe0000";
constant base_io_ocd_c : std_ulogic_vector(31 downto 0) := x"ffff0000";
-- On-Chip Debugger - Debug Module Entry Points (Code ROM) --
constant dm_exc_entry_c : std_ulogic_vector(31 downto 0) := x"fffffe00"; -- = base_io_ocd_c + code_rom_base + 0
@ -891,7 +891,8 @@ package neorv32_package is
IO_SLINK_EN : boolean := false;
IO_SLINK_RX_FIFO : natural range 1 to 2**15 := 1;
IO_SLINK_TX_FIFO : natural range 1 to 2**15 := 1;
IO_CRC_EN : boolean := false
IO_CRC_EN : boolean := false;
IO_HWSPINLOCK_EN : boolean := false
);
port (
-- Global control --

View file

@ -198,17 +198,20 @@ begin
pwm_core: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
cnt_tick <= '0';
cnt_cdiv <= (others => '0');
cnt_duty <= (others => '0');
pwm_o <= '0';
elsif rising_edge(clk_i) then
-- clock divider --
cnt_tick <= '0'; -- default
if (cfg_en = '0') then
cnt_cdiv <= (others => '0');
elsif (clkgen_i(to_integer(unsigned(cfg_prsc))) = '1') then -- pre-scaled clock (coarse)
if (cnt_tick = '1') then -- fine-tuned clock
if (cnt_cdiv = cfg_cdiv) then -- fine-tuned clock
cnt_cdiv <= (others => '0');
cnt_tick <= '1'; -- single-shot
else
cnt_cdiv <= std_ulogic_vector(unsigned(cnt_cdiv) + 1);
end if;
@ -231,7 +234,4 @@ begin
end if;
end process pwm_core;
-- fine-tuned clock tick --
cnt_tick <= '1' when (cnt_cdiv = cfg_cdiv) else '0';
end neorv32_pwm_channel_rtl;

View file

@ -32,30 +32,31 @@ entity neorv32_sysinfo is
DCACHE_EN : boolean; -- implement data cache
DCACHE_NUM_BLOCKS : natural; -- d-cache: number of blocks (min 2), has to be a power of 2
DCACHE_BLOCK_SIZE : natural; -- d-cache: block size in bytes (min 4), has to be a power of 2
XBUS_EN : boolean; -- implement external memory bus interface?
XBUS_EN : boolean; -- implement external memory bus interface
XBUS_CACHE_EN : boolean; -- implement external bus cache
XBUS_CACHE_NUM_BLOCKS : natural; -- x-cache: number of blocks (min 1), has to be a power of 2
XBUS_CACHE_BLOCK_SIZE : natural; -- x-cache: block size in bytes (min 4), has to be a power of 2
OCD_EN : boolean; -- implement OCD?
OCD_AUTHENTICATION : boolean; -- implement OCD authenticator?
IO_GPIO_EN : boolean; -- implement general purpose IO port (GPIO)?
IO_CLINT_EN : boolean; -- implement machine local interruptor (CLINT)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_SDI_EN : boolean; -- implement serial data interface (SDI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_TWD_EN : boolean; -- implement two-wire device (TWD)?
IO_PWM_EN : boolean; -- implement pulse-width modulation controller (PWM)?
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_GPTMR_EN : boolean; -- implement general purpose timer (GPTMR)?
IO_ONEWIRE_EN : boolean; -- implement 1-wire interface (ONEWIRE)?
IO_DMA_EN : boolean; -- implement direct memory access controller (DMA)?
IO_SLINK_EN : boolean; -- implement stream link interface (SLINK)?
IO_CRC_EN : boolean -- implement cyclic redundancy check unit (CRC)?
OCD_EN : boolean; -- implement OCD
OCD_AUTHENTICATION : boolean; -- implement OCD authenticator
IO_GPIO_EN : boolean; -- implement general purpose IO port (GPIO)
IO_CLINT_EN : boolean; -- implement machine local interruptor (CLINT)
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)
IO_SDI_EN : boolean; -- implement serial data interface (SDI)
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)
IO_TWD_EN : boolean; -- implement two-wire device (TWD)
IO_PWM_EN : boolean; -- implement pulse-width modulation controller (PWM)
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)
IO_GPTMR_EN : boolean; -- implement general purpose timer (GPTMR)
IO_ONEWIRE_EN : boolean; -- implement 1-wire interface (ONEWIRE)
IO_DMA_EN : boolean; -- implement direct memory access controller (DMA)
IO_SLINK_EN : boolean; -- implement stream link interface (SLINK)
IO_CRC_EN : boolean; -- implement cyclic redundancy check unit (CRC)
IO_HWSPINLOCK_EN : boolean -- implement hardware spinlocks (HWSPINLOCK)
);
port (
clk_i : in std_ulogic; -- global clock line
@ -114,38 +115,38 @@ begin
-- SYSINFO(2): SoC Configuration ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
sysinfo(2)(0) <= '1' when INT_BOOTLOADER_EN else '0'; -- processor-internal bootloader implemented?
sysinfo(2)(1) <= '1' when XBUS_EN else '0'; -- external bus interface implemented?
sysinfo(2)(2) <= '1' when int_imem_en_c else '0'; -- processor-internal instruction memory implemented?
sysinfo(2)(3) <= '1' when int_dmem_en_c else '0'; -- processor-internal data memory implemented?
sysinfo(2)(4) <= '1' when OCD_EN else '0'; -- on-chip debugger implemented?
sysinfo(2)(5) <= '1' when ICACHE_EN else '0'; -- processor-internal instruction cache implemented?
sysinfo(2)(6) <= '1' when DCACHE_EN else '0'; -- processor-internal data cache implemented?
sysinfo(2)(0) <= '1' when INT_BOOTLOADER_EN else '0'; -- processor-internal bootloader implemented
sysinfo(2)(1) <= '1' when XBUS_EN else '0'; -- external bus interface implemented
sysinfo(2)(2) <= '1' when int_imem_en_c else '0'; -- processor-internal instruction memory implemented
sysinfo(2)(3) <= '1' when int_dmem_en_c else '0'; -- processor-internal data memory implemented
sysinfo(2)(4) <= '1' when OCD_EN else '0'; -- on-chip debugger implemented
sysinfo(2)(5) <= '1' when ICACHE_EN else '0'; -- processor-internal instruction cache implemented
sysinfo(2)(6) <= '1' when DCACHE_EN else '0'; -- processor-internal data cache implemented
sysinfo(2)(7) <= '0'; -- reserved
sysinfo(2)(8) <= '1' when xcache_en_c else '0'; -- external bus interface cache implemented?
sysinfo(2)(8) <= '1' when xcache_en_c else '0'; -- external bus interface cache implemented
sysinfo(2)(9) <= '0'; -- reserved
sysinfo(2)(10) <= '0'; -- reserved
sysinfo(2)(11) <= '1' when ocd_auth_en_c else '0'; -- on-chip debugger authentication implemented?
sysinfo(2)(12) <= '1' when int_imem_rom_c else '0'; -- processor-internal instruction memory implemented as pre-initialized ROM?
sysinfo(2)(13) <= '1' when IO_TWD_EN else '0'; -- two-wire device (TWD) implemented?
sysinfo(2)(14) <= '1' when IO_DMA_EN else '0'; -- direct memory access controller (DMA) implemented?
sysinfo(2)(15) <= '1' when IO_GPIO_EN else '0'; -- general purpose input/output port unit (GPIO) implemented?
sysinfo(2)(16) <= '1' when IO_CLINT_EN else '0'; -- core local interruptor (CLINT) implemented?
sysinfo(2)(17) <= '1' when IO_UART0_EN else '0'; -- primary universal asynchronous receiver/transmitter (UART0) implemented?
sysinfo(2)(18) <= '1' when IO_SPI_EN else '0'; -- serial peripheral interface (SPI) implemented?
sysinfo(2)(19) <= '1' when IO_TWI_EN else '0'; -- two-wire interface (TWI) implemented?
sysinfo(2)(20) <= '1' when IO_PWM_EN else '0'; -- pulse-width modulation unit (PWM) implemented?
sysinfo(2)(21) <= '1' when IO_WDT_EN else '0'; -- watch dog timer (WDT) implemented?
sysinfo(2)(22) <= '1' when IO_CFS_EN else '0'; -- custom functions subsystem (CFS) implemented?
sysinfo(2)(23) <= '1' when IO_TRNG_EN else '0'; -- true random number generator (TRNG) implemented?
sysinfo(2)(24) <= '1' when IO_SDI_EN else '0'; -- serial data interface (SDI) implemented?
sysinfo(2)(25) <= '1' when IO_UART1_EN else '0'; -- secondary universal asynchronous receiver/transmitter (UART1) implemented?
sysinfo(2)(26) <= '1' when IO_NEOLED_EN else '0'; -- NeoPixel-compatible smart LED interface (NEOLED) implemented?
sysinfo(2)(27) <= '0'; -- reserved
sysinfo(2)(28) <= '1' when IO_GPTMR_EN else '0'; -- general purpose timer (GPTMR) implemented?
sysinfo(2)(29) <= '1' when IO_SLINK_EN else '0'; -- stream link interface (SLINK) implemented?
sysinfo(2)(30) <= '1' when IO_ONEWIRE_EN else '0'; -- 1-wire interface (ONEWIRE) implemented?
sysinfo(2)(31) <= '1' when IO_CRC_EN else '0'; -- cyclic redundancy check unit (CRC) implemented?
sysinfo(2)(11) <= '1' when ocd_auth_en_c else '0'; -- on-chip debugger authentication implemented
sysinfo(2)(12) <= '1' when int_imem_rom_c else '0'; -- processor-internal instruction memory implemented as pre-initialized ROM
sysinfo(2)(13) <= '1' when IO_TWD_EN else '0'; -- two-wire device (TWD) implemented
sysinfo(2)(14) <= '1' when IO_DMA_EN else '0'; -- direct memory access controller (DMA) implemented
sysinfo(2)(15) <= '1' when IO_GPIO_EN else '0'; -- general purpose input/output port unit (GPIO) implemented
sysinfo(2)(16) <= '1' when IO_CLINT_EN else '0'; -- core local interruptor (CLINT) implemented
sysinfo(2)(17) <= '1' when IO_UART0_EN else '0'; -- primary universal asynchronous receiver/transmitter (UART0) implemented
sysinfo(2)(18) <= '1' when IO_SPI_EN else '0'; -- serial peripheral interface (SPI) implemented
sysinfo(2)(19) <= '1' when IO_TWI_EN else '0'; -- two-wire interface (TWI) implemented
sysinfo(2)(20) <= '1' when IO_PWM_EN else '0'; -- pulse-width modulation unit (PWM) implemented
sysinfo(2)(21) <= '1' when IO_WDT_EN else '0'; -- watch dog timer (WDT) implemented
sysinfo(2)(22) <= '1' when IO_CFS_EN else '0'; -- custom functions subsystem (CFS) implemented
sysinfo(2)(23) <= '1' when IO_TRNG_EN else '0'; -- true random number generator (TRNG) implemented
sysinfo(2)(24) <= '1' when IO_SDI_EN else '0'; -- serial data interface (SDI) implemented
sysinfo(2)(25) <= '1' when IO_UART1_EN else '0'; -- secondary universal asynchronous receiver/transmitter (UART1) implemented
sysinfo(2)(26) <= '1' when IO_NEOLED_EN else '0'; -- NeoPixel-compatible smart LED interface (NEOLED) implemented
sysinfo(2)(27) <= '1' when IO_HWSPINLOCK_EN else '0'; -- hardware spinlocks (HWSPINLOCK) implemented
sysinfo(2)(28) <= '1' when IO_GPTMR_EN else '0'; -- general purpose timer (GPTMR) implemented
sysinfo(2)(29) <= '1' when IO_SLINK_EN else '0'; -- stream link interface (SLINK) implemented
sysinfo(2)(30) <= '1' when IO_ONEWIRE_EN else '0'; -- 1-wire interface (ONEWIRE) implemented
sysinfo(2)(31) <= '1' when IO_CRC_EN else '0'; -- cyclic redundancy check unit (CRC) implemented
-- SYSINFO(4): Cache Configuration --------------------------------------------------------
-- -------------------------------------------------------------------------------------------

View file

@ -95,7 +95,7 @@ entity neorv32_top is
DCACHE_BLOCK_SIZE : natural range 4 to 2**16 := 64; -- d-cache: block size in bytes (min 4), has to be a power of 2
-- External bus interface (XBUS) --
XBUS_EN : boolean := false; -- implement external memory bus interface?
XBUS_EN : boolean := false; -- implement external memory bus interface
XBUS_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled)
XBUS_REGSTAGE_EN : boolean := false; -- add XBUS register stage
XBUS_CACHE_EN : boolean := false; -- enable external bus cache (x-cache)
@ -105,40 +105,41 @@ entity neorv32_top is
-- Processor peripherals --
IO_DISABLE_SYSINFO : boolean := false; -- disable the SYSINFO module (for advanced users only)
IO_GPIO_NUM : natural range 0 to 32 := 0; -- number of GPIO input/output pairs (0..32)
IO_CLINT_EN : boolean := false; -- implement core local interruptor (CLINT)?
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_CLINT_EN : boolean := false; -- implement core local interruptor (CLINT)
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)
IO_UART0_RX_FIFO : natural range 1 to 2**15 := 1; -- RX FIFO depth, has to be a power of two, min 1
IO_UART0_TX_FIFO : natural range 1 to 2**15 := 1; -- TX FIFO depth, has to be a power of two, min 1
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)
IO_UART1_RX_FIFO : natural range 1 to 2**15 := 1; -- RX FIFO depth, has to be a power of two, min 1
IO_UART1_TX_FIFO : natural range 1 to 2**15 := 1; -- TX FIFO depth, has to be a power of two, min 1
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)?
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)
IO_SPI_FIFO : natural range 1 to 2**15 := 1; -- RTX FIFO depth, has to be a power of two, min 1
IO_SDI_EN : boolean := false; -- implement serial data interface (SDI)?
IO_SDI_EN : boolean := false; -- implement serial data interface (SDI)
IO_SDI_FIFO : natural range 1 to 2**15 := 1; -- RTX FIFO depth, has to be zero or a power of two, min 1
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)?
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)
IO_TWI_FIFO : natural range 1 to 2**15 := 1; -- RTX FIFO depth, has to be zero or a power of two, min 1
IO_TWD_EN : boolean := false; -- implement two-wire device (TWD)?
IO_TWD_EN : boolean := false; -- implement two-wire device (TWD)
IO_TWD_RX_FIFO : natural range 1 to 2**15 := 1; -- TX FIFO depth, has to be zero or a power of two, min 1
IO_TWD_TX_FIFO : natural range 1 to 2**15 := 1; -- RX FIFO depth, has to be zero or a power of two, min 1
IO_PWM_NUM_CH : natural range 0 to 16 := 0; -- number of PWM channels to implement (0..16)
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)
IO_TRNG_FIFO : natural range 1 to 2**15 := 1; -- data FIFO depth, has to be a power of two, min 1
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) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : natural := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : natural := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)
IO_NEOLED_TX_FIFO : natural range 1 to 2**15 := 1; -- NEOLED FIFO depth, has to be a power of two, min 1
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_ONEWIRE_EN : boolean := false; -- implement 1-wire interface (ONEWIRE)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)
IO_ONEWIRE_EN : boolean := false; -- implement 1-wire interface (ONEWIRE)
IO_ONEWIRE_FIFO : natural range 1 to 2**15 := 1; -- RTX FIFO depth, has to be zero or a power of two, min 1
IO_DMA_EN : boolean := false; -- implement direct memory access controller (DMA)?
IO_SLINK_EN : boolean := false; -- implement stream link interface (SLINK)?
IO_DMA_EN : boolean := false; -- implement direct memory access controller (DMA)
IO_SLINK_EN : boolean := false; -- implement stream link interface (SLINK)
IO_SLINK_RX_FIFO : natural range 1 to 2**15 := 1; -- RX FIFO depth, has to be a power of two, min 1
IO_SLINK_TX_FIFO : natural range 1 to 2**15 := 1; -- TX FIFO depth, has to be a power of two, min 1
IO_CRC_EN : boolean := false -- implement cyclic redundancy check unit (CRC)?
IO_CRC_EN : boolean := false; -- implement cyclic redundancy check unit (CRC)
IO_HWSPINLOCK_EN : boolean := false -- implement hardware spinlocks (HWSPINLOCK)
);
port (
-- Global control --
@ -311,7 +312,7 @@ architecture neorv32_top_rtl of neorv32_top is
type io_devices_enum_t is (
IODEV_BOOTROM, IODEV_OCD, IODEV_SYSINFO, IODEV_NEOLED, IODEV_GPIO, IODEV_WDT, IODEV_TRNG,
IODEV_TWI, IODEV_SPI, IODEV_SDI, IODEV_UART1, IODEV_UART0, IODEV_CLINT, IODEV_ONEWIRE,
IODEV_GPTMR, IODEV_PWM, IODEV_CRC, IODEV_DMA, IODEV_SLINK, IODEV_CFS, IODEV_TWD
IODEV_GPTMR, IODEV_PWM, IODEV_CRC, IODEV_DMA, IODEV_SLINK, IODEV_CFS, IODEV_HWSPINLOCK, IODEV_TWD
);
type iodev_req_t is array (io_devices_enum_t) of bus_req_t;
type iodev_rsp_t is array (io_devices_enum_t) of bus_rsp_t;
@ -377,6 +378,7 @@ begin
cond_sel_string_f(IO_ONEWIRE_EN, "ONEWIRE ", "") &
cond_sel_string_f(IO_DMA_EN, "DMA ", "") &
cond_sel_string_f(IO_SLINK_EN, "SLINK ", "") &
cond_sel_string_f(IO_HWSPINLOCK_EN, "HWSPINLOCK ", "") &
cond_sel_string_f(IO_CRC_EN, "CRC ", "") &
cond_sel_string_f(io_sysinfo_en_c, "SYSINFO ", "") &
cond_sel_string_f(OCD_EN, cond_sel_string_f(OCD_AUTHENTICATION, "OCD-AUTH ", "OCD "), "") &
@ -642,7 +644,7 @@ begin
end generate; -- /core_complex
-- Inter-Core Communication (ICC) Links ---------------------------------------------------
-- Inter-Core Communication (ICC) Links - Cross-Connect -----------------------------------
-- -------------------------------------------------------------------------------------------
icc_connect: process(icc_tx)
begin
@ -966,76 +968,76 @@ begin
INREG_EN => true,
OUTREG_EN => true,
DEV_SIZE => iodev_size_c,
DEV_00_EN => bootrom_en_c, DEV_00_BASE => base_io_bootrom_c,
DEV_01_EN => false, DEV_01_BASE => (others => '0'), -- reserved
DEV_02_EN => false, DEV_02_BASE => (others => '0'), -- reserved
DEV_03_EN => false, DEV_03_BASE => (others => '0'), -- reserved
DEV_04_EN => false, DEV_04_BASE => (others => '0'), -- reserved
DEV_05_EN => false, DEV_05_BASE => (others => '0'), -- reserved
DEV_06_EN => false, DEV_06_BASE => (others => '0'), -- reserved
DEV_07_EN => false, DEV_07_BASE => (others => '0'), -- reserved
DEV_08_EN => false, DEV_08_BASE => (others => '0'), -- reserved
DEV_09_EN => false, DEV_09_BASE => (others => '0'), -- reserved
DEV_10_EN => IO_TWD_EN, DEV_10_BASE => base_io_twd_c,
DEV_11_EN => IO_CFS_EN, DEV_11_BASE => base_io_cfs_c,
DEV_12_EN => IO_SLINK_EN, DEV_12_BASE => base_io_slink_c,
DEV_13_EN => IO_DMA_EN, DEV_13_BASE => base_io_dma_c,
DEV_14_EN => IO_CRC_EN, DEV_14_BASE => base_io_crc_c,
DEV_15_EN => false, DEV_15_BASE => (others => '0'), -- reserved
DEV_16_EN => io_pwm_en_c, DEV_16_BASE => base_io_pwm_c,
DEV_17_EN => IO_GPTMR_EN, DEV_17_BASE => base_io_gptmr_c,
DEV_18_EN => IO_ONEWIRE_EN, DEV_18_BASE => base_io_onewire_c,
DEV_19_EN => false, DEV_19_BASE => (others => '0'), -- reserved
DEV_20_EN => IO_CLINT_EN, DEV_20_BASE => base_io_clint_c,
DEV_21_EN => IO_UART0_EN, DEV_21_BASE => base_io_uart0_c,
DEV_22_EN => IO_UART1_EN, DEV_22_BASE => base_io_uart1_c,
DEV_23_EN => IO_SDI_EN, DEV_23_BASE => base_io_sdi_c,
DEV_24_EN => IO_SPI_EN, DEV_24_BASE => base_io_spi_c,
DEV_25_EN => IO_TWI_EN, DEV_25_BASE => base_io_twi_c,
DEV_26_EN => IO_TRNG_EN, DEV_26_BASE => base_io_trng_c,
DEV_27_EN => IO_WDT_EN, DEV_27_BASE => base_io_wdt_c,
DEV_28_EN => io_gpio_en_c, DEV_28_BASE => base_io_gpio_c,
DEV_29_EN => IO_NEOLED_EN, DEV_29_BASE => base_io_neoled_c,
DEV_30_EN => io_sysinfo_en_c, DEV_30_BASE => base_io_sysinfo_c,
DEV_31_EN => OCD_EN, DEV_31_BASE => base_io_ocd_c
DEV_00_EN => bootrom_en_c, DEV_00_BASE => base_io_bootrom_c,
DEV_01_EN => false, DEV_01_BASE => (others => '0'), -- reserved
DEV_02_EN => false, DEV_02_BASE => (others => '0'), -- reserved
DEV_03_EN => false, DEV_03_BASE => (others => '0'), -- reserved
DEV_04_EN => false, DEV_04_BASE => (others => '0'), -- reserved
DEV_05_EN => false, DEV_05_BASE => (others => '0'), -- reserved
DEV_06_EN => false, DEV_06_BASE => (others => '0'), -- reserved
DEV_07_EN => false, DEV_07_BASE => (others => '0'), -- reserved
DEV_08_EN => false, DEV_08_BASE => (others => '0'), -- reserved
DEV_09_EN => false, DEV_09_BASE => (others => '0'), -- reserved
DEV_10_EN => IO_TWD_EN, DEV_10_BASE => base_io_twd_c,
DEV_11_EN => IO_CFS_EN, DEV_11_BASE => base_io_cfs_c,
DEV_12_EN => IO_SLINK_EN, DEV_12_BASE => base_io_slink_c,
DEV_13_EN => IO_DMA_EN, DEV_13_BASE => base_io_dma_c,
DEV_14_EN => IO_CRC_EN, DEV_14_BASE => base_io_crc_c,
DEV_15_EN => false, DEV_15_BASE => (others => '0'), -- reserved
DEV_16_EN => io_pwm_en_c, DEV_16_BASE => base_io_pwm_c,
DEV_17_EN => IO_GPTMR_EN, DEV_17_BASE => base_io_gptmr_c,
DEV_18_EN => IO_ONEWIRE_EN, DEV_18_BASE => base_io_onewire_c,
DEV_19_EN => IO_HWSPINLOCK_EN, DEV_19_BASE => base_io_hwspinlock_c,
DEV_20_EN => IO_CLINT_EN, DEV_20_BASE => base_io_clint_c,
DEV_21_EN => IO_UART0_EN, DEV_21_BASE => base_io_uart0_c,
DEV_22_EN => IO_UART1_EN, DEV_22_BASE => base_io_uart1_c,
DEV_23_EN => IO_SDI_EN, DEV_23_BASE => base_io_sdi_c,
DEV_24_EN => IO_SPI_EN, DEV_24_BASE => base_io_spi_c,
DEV_25_EN => IO_TWI_EN, DEV_25_BASE => base_io_twi_c,
DEV_26_EN => IO_TRNG_EN, DEV_26_BASE => base_io_trng_c,
DEV_27_EN => IO_WDT_EN, DEV_27_BASE => base_io_wdt_c,
DEV_28_EN => io_gpio_en_c, DEV_28_BASE => base_io_gpio_c,
DEV_29_EN => IO_NEOLED_EN, DEV_29_BASE => base_io_neoled_c,
DEV_30_EN => io_sysinfo_en_c, DEV_30_BASE => base_io_sysinfo_c,
DEV_31_EN => OCD_EN, DEV_31_BASE => base_io_ocd_c
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
main_req_i => io_req,
main_rsp_o => io_rsp,
dev_00_req_o => iodev_req(IODEV_BOOTROM), dev_00_rsp_i => iodev_rsp(IODEV_BOOTROM),
dev_01_req_o => open, dev_01_rsp_i => rsp_terminate_c, -- reserved
dev_02_req_o => open, dev_02_rsp_i => rsp_terminate_c, -- reserved
dev_03_req_o => open, dev_03_rsp_i => rsp_terminate_c, -- reserved
dev_04_req_o => open, dev_04_rsp_i => rsp_terminate_c, -- reserved
dev_05_req_o => open, dev_05_rsp_i => rsp_terminate_c, -- reserved
dev_06_req_o => open, dev_06_rsp_i => rsp_terminate_c, -- reserved
dev_07_req_o => open, dev_07_rsp_i => rsp_terminate_c, -- reserved
dev_08_req_o => open, dev_08_rsp_i => rsp_terminate_c, -- reserved
dev_09_req_o => open, dev_09_rsp_i => rsp_terminate_c, -- reserved
dev_10_req_o => iodev_req(IODEV_TWD), dev_10_rsp_i => iodev_rsp(IODEV_TWD),
dev_11_req_o => iodev_req(IODEV_CFS), dev_11_rsp_i => iodev_rsp(IODEV_CFS),
dev_12_req_o => iodev_req(IODEV_SLINK), dev_12_rsp_i => iodev_rsp(IODEV_SLINK),
dev_13_req_o => iodev_req(IODEV_DMA), dev_13_rsp_i => iodev_rsp(IODEV_DMA),
dev_14_req_o => iodev_req(IODEV_CRC), dev_14_rsp_i => iodev_rsp(IODEV_CRC),
dev_15_req_o => open, dev_15_rsp_i => rsp_terminate_c, -- reserved
dev_16_req_o => iodev_req(IODEV_PWM), dev_16_rsp_i => iodev_rsp(IODEV_PWM),
dev_17_req_o => iodev_req(IODEV_GPTMR), dev_17_rsp_i => iodev_rsp(IODEV_GPTMR),
dev_18_req_o => iodev_req(IODEV_ONEWIRE), dev_18_rsp_i => iodev_rsp(IODEV_ONEWIRE),
dev_19_req_o => open, dev_19_rsp_i => rsp_terminate_c, -- reserved
dev_20_req_o => iodev_req(IODEV_CLINT), dev_20_rsp_i => iodev_rsp(IODEV_CLINT),
dev_21_req_o => iodev_req(IODEV_UART0), dev_21_rsp_i => iodev_rsp(IODEV_UART0),
dev_22_req_o => iodev_req(IODEV_UART1), dev_22_rsp_i => iodev_rsp(IODEV_UART1),
dev_23_req_o => iodev_req(IODEV_SDI), dev_23_rsp_i => iodev_rsp(IODEV_SDI),
dev_24_req_o => iodev_req(IODEV_SPI), dev_24_rsp_i => iodev_rsp(IODEV_SPI),
dev_25_req_o => iodev_req(IODEV_TWI), dev_25_rsp_i => iodev_rsp(IODEV_TWI),
dev_26_req_o => iodev_req(IODEV_TRNG), dev_26_rsp_i => iodev_rsp(IODEV_TRNG),
dev_27_req_o => iodev_req(IODEV_WDT), dev_27_rsp_i => iodev_rsp(IODEV_WDT),
dev_28_req_o => iodev_req(IODEV_GPIO), dev_28_rsp_i => iodev_rsp(IODEV_GPIO),
dev_29_req_o => iodev_req(IODEV_NEOLED), dev_29_rsp_i => iodev_rsp(IODEV_NEOLED),
dev_30_req_o => iodev_req(IODEV_SYSINFO), dev_30_rsp_i => iodev_rsp(IODEV_SYSINFO),
dev_31_req_o => iodev_req(IODEV_OCD), dev_31_rsp_i => iodev_rsp(IODEV_OCD)
dev_00_req_o => iodev_req(IODEV_BOOTROM), dev_00_rsp_i => iodev_rsp(IODEV_BOOTROM),
dev_01_req_o => open, dev_01_rsp_i => rsp_terminate_c, -- reserved
dev_02_req_o => open, dev_02_rsp_i => rsp_terminate_c, -- reserved
dev_03_req_o => open, dev_03_rsp_i => rsp_terminate_c, -- reserved
dev_04_req_o => open, dev_04_rsp_i => rsp_terminate_c, -- reserved
dev_05_req_o => open, dev_05_rsp_i => rsp_terminate_c, -- reserved
dev_06_req_o => open, dev_06_rsp_i => rsp_terminate_c, -- reserved
dev_07_req_o => open, dev_07_rsp_i => rsp_terminate_c, -- reserved
dev_08_req_o => open, dev_08_rsp_i => rsp_terminate_c, -- reserved
dev_09_req_o => open, dev_09_rsp_i => rsp_terminate_c, -- reserved
dev_10_req_o => iodev_req(IODEV_TWD), dev_10_rsp_i => iodev_rsp(IODEV_TWD),
dev_11_req_o => iodev_req(IODEV_CFS), dev_11_rsp_i => iodev_rsp(IODEV_CFS),
dev_12_req_o => iodev_req(IODEV_SLINK), dev_12_rsp_i => iodev_rsp(IODEV_SLINK),
dev_13_req_o => iodev_req(IODEV_DMA), dev_13_rsp_i => iodev_rsp(IODEV_DMA),
dev_14_req_o => iodev_req(IODEV_CRC), dev_14_rsp_i => iodev_rsp(IODEV_CRC),
dev_15_req_o => open, dev_15_rsp_i => rsp_terminate_c, -- reserved
dev_16_req_o => iodev_req(IODEV_PWM), dev_16_rsp_i => iodev_rsp(IODEV_PWM),
dev_17_req_o => iodev_req(IODEV_GPTMR), dev_17_rsp_i => iodev_rsp(IODEV_GPTMR),
dev_18_req_o => iodev_req(IODEV_ONEWIRE), dev_18_rsp_i => iodev_rsp(IODEV_ONEWIRE),
dev_19_req_o => iodev_req(IODEV_HWSPINLOCK), dev_19_rsp_i => iodev_rsp(IODEV_HWSPINLOCK),
dev_20_req_o => iodev_req(IODEV_CLINT), dev_20_rsp_i => iodev_rsp(IODEV_CLINT),
dev_21_req_o => iodev_req(IODEV_UART0), dev_21_rsp_i => iodev_rsp(IODEV_UART0),
dev_22_req_o => iodev_req(IODEV_UART1), dev_22_rsp_i => iodev_rsp(IODEV_UART1),
dev_23_req_o => iodev_req(IODEV_SDI), dev_23_rsp_i => iodev_rsp(IODEV_SDI),
dev_24_req_o => iodev_req(IODEV_SPI), dev_24_rsp_i => iodev_rsp(IODEV_SPI),
dev_25_req_o => iodev_req(IODEV_TWI), dev_25_rsp_i => iodev_rsp(IODEV_TWI),
dev_26_req_o => iodev_req(IODEV_TRNG), dev_26_rsp_i => iodev_rsp(IODEV_TRNG),
dev_27_req_o => iodev_req(IODEV_WDT), dev_27_rsp_i => iodev_rsp(IODEV_WDT),
dev_28_req_o => iodev_req(IODEV_GPIO), dev_28_rsp_i => iodev_rsp(IODEV_GPIO),
dev_29_req_o => iodev_req(IODEV_NEOLED), dev_29_rsp_i => iodev_rsp(IODEV_NEOLED),
dev_30_req_o => iodev_req(IODEV_SYSINFO), dev_30_rsp_i => iodev_rsp(IODEV_SYSINFO),
dev_31_req_o => iodev_req(IODEV_OCD), dev_31_rsp_i => iodev_rsp(IODEV_OCD)
);
@ -1570,6 +1572,25 @@ begin
end generate;
-- Hardware Spinlocks (HWSPINLOCK) --------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_hwspinlock_enabled:
if IO_HWSPINLOCK_EN generate
neorv32_hwspinlock_inst: entity neorv32.neorv32_hwspinlock
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_HWSPINLOCK),
bus_rsp_o => iodev_rsp(IODEV_HWSPINLOCK)
);
end generate;
neorv32_hwspinlock_disabled:
if not IO_HWSPINLOCK_EN generate
iodev_rsp(IODEV_HWSPINLOCK) <= rsp_terminate_c;
end generate;
-- System Configuration Information Memory (SYSINFO) --------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_sysinfo_enabled:
@ -1614,7 +1635,8 @@ begin
IO_ONEWIRE_EN => IO_ONEWIRE_EN,
IO_DMA_EN => IO_DMA_EN,
IO_SLINK_EN => IO_SLINK_EN,
IO_CRC_EN => IO_CRC_EN
IO_CRC_EN => IO_CRC_EN,
IO_HWSPINLOCK_EN => IO_HWSPINLOCK_EN
)
port map (
clk_i => clk_i,

View file

@ -43,6 +43,7 @@ NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_gptmr.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_onewire.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_slink.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_crc.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_hwspinlock.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_sysinfo.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_debug_dtm.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_debug_auth.vhd

View file

@ -409,6 +409,11 @@ proc setup_ip_gui {} {
add_params $group {
{ IO_CRC_EN {Enable CRC} }
}
set group [add_group $page {Hardware Spinlocks (HWSPINLOCK)}]
add_params $group {
{ IO_HWSPINLOCK_EN {Implement 32 HW-based spinlocks} }
}
}
setup_ip_gui

View file

@ -129,7 +129,9 @@ entity neorv32_vivado_ip is
IO_SLINK_EN : boolean := false;
IO_SLINK_RX_FIFO : natural range 1 to 2**15 := 1;
IO_SLINK_TX_FIFO : natural range 1 to 2**15 := 1;
IO_CRC_EN : boolean := false
IO_CRC_EN : boolean := false;
IO_HWSPINLOCK_EN : boolean := false
);
port (
-- ------------------------------------------------------------
@ -439,7 +441,8 @@ begin
IO_SLINK_EN => IO_SLINK_EN,
IO_SLINK_RX_FIFO => IO_SLINK_RX_FIFO,
IO_SLINK_TX_FIFO => IO_SLINK_TX_FIFO,
IO_CRC_EN => IO_CRC_EN
IO_CRC_EN => IO_CRC_EN,
IO_HWSPINLOCK_EN => IO_HWSPINLOCK_EN
)
port map (
-- Global control --

View file

@ -222,7 +222,8 @@ begin
IO_SLINK_EN => true,
IO_SLINK_RX_FIFO => 4,
IO_SLINK_TX_FIFO => 4,
IO_CRC_EN => true
IO_CRC_EN => true,
IO_HWSPINLOCK_EN => true
)
port map (
-- Global control --

View file

@ -0,0 +1,33 @@
# Application makefile.
# Use this makefile to configure all relevant CPU / compiler options.
# Override the default CPU ISA
MARCH = rv32ia_zicsr_zifencei
# Override the default RISC-V GCC prefix
#RISCV_PREFIX ?= riscv-none-elf-
# Override default optimization goal
EFFORT = -Os
# Add extended debug symbols
USER_FLAGS += -ggdb -gdwarf-3
# Adjust processor IMEM size
USER_FLAGS += -Wl,--defsym,__neorv32_rom_size=16k
# Adjust processor DMEM size
USER_FLAGS += -Wl,--defsym,__neorv32_ram_size=8k
# Adjust maximum heap size
#USER_FLAGS += -Wl,--defsym,__neorv32_heap_size=3k
# Additional sources
#APP_SRC += $(wildcard ./*.c)
#APP_INC += -I .
# Set path to NEORV32 root directory
NEORV32_HOME ?= ../../..
# Include the main NEORV32 makefile
include $(NEORV32_HOME)/sw/common/common.mk

View file

@ -0,0 +1,110 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //
/**********************************************************************//**
* @file demo_dual_core_hwspinlock/main.c
* @brief Dual-core SMP demo program using the NEORV32 hardware spinlocks.
**************************************************************************/
#include <neorv32.h>
/** User configuration */
#define BAUD_RATE 19200
/** Hardware spinlock enumeration **/
enum hw_spinlock_enum {
SPINLOCK_UART0 = 0 // lock for mutual-exclusive access to UART0
// here we could add up to 31 additional locks for shared resources
};
/** Global variables */
volatile uint8_t __attribute__ ((aligned (16))) core1_stack[2048]; // stack memory for core1
/**********************************************************************//**
* Main application that is executed on both cores.
*
* @return Irrelevant.
**************************************************************************/
int app_main(void) {
// setup local NEORV32 runtime-environment (RTE) if we are core 1
if (neorv32_smp_whoami() == 1) {
neorv32_rte_setup();
}
while (1) {
// block until we have acquired the lock for the shared resources
// the other core will wait here until the lock is released
neorv32_hwspinlock_acquire_blocking(SPINLOCK_UART0);
// UART0 is the shared resource
if (neorv32_smp_whoami() == 0) {
neorv32_uart0_printf("[core 0] Hello world!\n");
}
else {
neorv32_uart0_printf("[core 1] Hey there!\n");
}
// release the lock so the other core can use the shared resource
neorv32_hwspinlock_release(SPINLOCK_UART0);
}
return 0;
}
/**********************************************************************//**
* Main function for core 0 (primary core).
*
* @attention This program requires the dual-core configuration, the CLINT, UART0
* and the HWSPINLOCK module.
*
* @return Irrelevant (but can be inspected by the debugger).
**************************************************************************/
int main(void) {
// setup NEORV32 runtime-environment (RTE) for _this_ core (core0)
neorv32_rte_setup();
// setup UART0 at default baud rate, no interrupts
if (neorv32_uart0_available() == 0) { // UART0 available?
return -1;
}
neorv32_uart0_setup(BAUD_RATE, 0);
neorv32_uart0_printf("\n<< NEORV32 Hardware Spinlock Dual-Core Demo >>\n\n");
// check hardware configuration
if (neorv32_sysinfo_get_numcores() < 2) { // two cores available?
neorv32_uart0_printf("[ERROR] dual-core option not enabled!\n");
return -1;
}
if (neorv32_clint_available() == 0) { // CLINT available?
neorv32_uart0_printf("[ERROR] CLINT module not available!\n");
return -1;
}
if (neorv32_hwspinlock_available() == 0) { // hardware spinlocks available?
neorv32_uart0_printf("[ERROR] HWSPINLOCK module not available!\n");
return -1;
}
// reset all spinlocks
neorv32_hwspinlock_clear();
// Launch application function on core 1
neorv32_uart0_printf("Launching core1...\n");
int smp_launch_rc = neorv32_smp_launch(app_main, (uint8_t*)core1_stack, sizeof(core1_stack));
if (smp_launch_rc) {
neorv32_uart0_printf("[ERROR] Launching core1 failed (%d)!\n", smp_launch_rc);
return -1;
}
// also start application function on core 0
app_main();
return 0; // return to crt0 and halt
}

View file

@ -28,39 +28,39 @@ extern "C" {
* @name IO Address Space Map - Peripheral/IO Devices
**************************************************************************/
/**@{*/
#define IO_BASE_ADDRESS (0XFFE00000U)
#define NEORV32_BOOTROM_BASE (0xFFE00000U) /**< Bootloader ROM (BOOTROM) */
//#define NEORV32_???_BASE (0xFFE10000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE20000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE30000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE40000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE50000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE60000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE70000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE80000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE90000U) /**< reserved */
#define NEORV32_TWD_BASE (0xFFEA0000U) /**< Two-Wire Device (TWD) */
#define NEORV32_CFS_BASE (0xFFEB0000U) /**< Custom Functions Subsystem (CFS) */
#define NEORV32_SLINK_BASE (0xFFEC0000U) /**< Stream Link Interface (SLINK) */
#define NEORV32_DMA_BASE (0xFFED0000U) /**< Direct Memory Access Controller (DMA) */
#define NEORV32_CRC_BASE (0xFFEE0000U) /**< Cyclic Redundancy Check Unit (DMA) */
//#define NEORV32_???_BASE (0xFFEF0000U) /**< reserved */
#define NEORV32_PWM_BASE (0xFFF00000U) /**< Pulse Width Modulation Controller (PWM) */
#define NEORV32_GPTMR_BASE (0xFFF10000U) /**< General Purpose Timer (GPTMR) */
#define NEORV32_ONEWIRE_BASE (0xFFF20000U) /**< 1-Wire Interface Controller (ONEWIRE) */
//#define NEORV32_???_BASE (0xFFF30000U) /**< reserved */
#define NEORV32_CLINT_BASE (0xFFF40000U) /**< Core Local Interruptor (CLINT) */
#define NEORV32_UART0_BASE (0xFFF50000U) /**< Primary Universal Asynchronous Receiver and Transmitter (UART0) */
#define NEORV32_UART1_BASE (0xFFF60000U) /**< Secondary Universal Asynchronous Receiver and Transmitter (UART1) */
#define NEORV32_SDI_BASE (0xFFF70000U) /**< Serial Data Interface (SDI) */
#define NEORV32_SPI_BASE (0xFFF80000U) /**< Serial Peripheral Interface Controller (SPI) */
#define NEORV32_TWI_BASE (0xFFF90000U) /**< Two-Wire Interface Controller (TWI) */
#define NEORV32_TRNG_BASE (0xFFFA0000U) /**< True Random Number Generator (TRNG) */
#define NEORV32_WDT_BASE (0xFFFB0000U) /**< Watchdog Timer (WDT) */
#define NEORV32_GPIO_BASE (0xFFFC0000U) /**< General Purpose Input/Output Port Controller (GPIO) */
#define NEORV32_NEOLED_BASE (0xFFFD0000U) /**< Smart LED Hardware Interface (NEOLED) */
#define NEORV32_SYSINFO_BASE (0xFFFE0000U) /**< System Information Memory (SYSINFO) */
#define NEORV32_DM_BASE (0xFFFF0000U) /**< On-Chip Debugger - Debug Module (OCD) */
#define IO_BASE_ADDRESS (0XFFE00000U)
#define NEORV32_BOOTROM_BASE (0xFFE00000U) /**< Bootloader ROM (BOOTROM) */
//#define NEORV32_???_BASE (0xFFE10000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE20000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE30000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE40000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE50000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE60000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE70000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE80000U) /**< reserved */
//#define NEORV32_???_BASE (0xFFE90000U) /**< reserved */
#define NEORV32_TWD_BASE (0xFFEA0000U) /**< Two-Wire Device (TWD) */
#define NEORV32_CFS_BASE (0xFFEB0000U) /**< Custom Functions Subsystem (CFS) */
#define NEORV32_SLINK_BASE (0xFFEC0000U) /**< Stream Link Interface (SLINK) */
#define NEORV32_DMA_BASE (0xFFED0000U) /**< Direct Memory Access Controller (DMA) */
#define NEORV32_CRC_BASE (0xFFEE0000U) /**< Cyclic Redundancy Check Unit (DMA) */
//#define NEORV32_???_BASE (0xFFEF0000U) /**< reserved */
#define NEORV32_PWM_BASE (0xFFF00000U) /**< Pulse Width Modulation Controller (PWM) */
#define NEORV32_GPTMR_BASE (0xFFF10000U) /**< General Purpose Timer (GPTMR) */
#define NEORV32_ONEWIRE_BASE (0xFFF20000U) /**< 1-Wire Interface Controller (ONEWIRE) */
#define NEORV32_HWSPINLOCK_BASE (0xFFF30000U) /**< Hardware spinlocks (HWSPINLOCK) */
#define NEORV32_CLINT_BASE (0xFFF40000U) /**< Core Local Interruptor (CLINT) */
#define NEORV32_UART0_BASE (0xFFF50000U) /**< Primary Universal Asynchronous Receiver and Transmitter (UART0) */
#define NEORV32_UART1_BASE (0xFFF60000U) /**< Secondary Universal Asynchronous Receiver and Transmitter (UART1) */
#define NEORV32_SDI_BASE (0xFFF70000U) /**< Serial Data Interface (SDI) */
#define NEORV32_SPI_BASE (0xFFF80000U) /**< Serial Peripheral Interface Controller (SPI) */
#define NEORV32_TWI_BASE (0xFFF90000U) /**< Two-Wire Interface Controller (TWI) */
#define NEORV32_TRNG_BASE (0xFFFA0000U) /**< True Random Number Generator (TRNG) */
#define NEORV32_WDT_BASE (0xFFFB0000U) /**< Watchdog Timer (WDT) */
#define NEORV32_GPIO_BASE (0xFFFC0000U) /**< General Purpose Input/Output Port Controller (GPIO) */
#define NEORV32_NEOLED_BASE (0xFFFD0000U) /**< Smart LED Hardware Interface (NEOLED) */
#define NEORV32_SYSINFO_BASE (0xFFFE0000U) /**< System Information Memory (SYSINFO) */
#define NEORV32_DM_BASE (0xFFFF0000U) /**< On-Chip Debugger - Debug Module (OCD) */
/**@}*/
@ -255,6 +255,7 @@ typedef union {
#include "neorv32_dma.h"
#include "neorv32_gpio.h"
#include "neorv32_gptmr.h"
#include "neorv32_hwspinlock.h"
#include "neorv32_neoled.h"
#include "neorv32_onewire.h"
#include "neorv32_pwm.h"

View file

@ -0,0 +1,48 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //
/**
* @file neorv32_hwspinlock.h
* @brief Hardware spinlock (HWSPINLOCK) HW driver header file.
*/
#ifndef NEORV32_HWSPINLOCK_H
#define NEORV32_HWSPINLOCK_H
#include <stdint.h>
/**********************************************************************//**
* @name IO Device: Hardware Spinlock (HWSPINLOCK)
**************************************************************************/
/**@{*/
/** HWSPINLOCK module prototype */
typedef volatile struct __attribute__((packed,aligned(4))) {
uint32_t LOCK[32]; /**< Binary locks */
const uint32_t STATUS; /**< State of all locks */
} neorv32_hwspinlock_t;
/** HWSPINLOCK module hardware handle (#neorv32_hwspinlock_t) */
#define NEORV32_HWSPINLOCK ((neorv32_hwspinlock_t*) (NEORV32_HWSPINLOCK_BASE))
/**@}*/
/**********************************************************************//**
* @name Prototypes
**************************************************************************/
/**@{*/
int neorv32_hwspinlock_available(void);
int neorv32_hwspinlock_acquire(int select);
void neorv32_hwspinlock_acquire_blocking(int select);
void neorv32_hwspinlock_release(int select);
int neorv32_hwspinlock_probe(int select);
void neorv32_hwspinlock_clear(void);
/**@}*/
#endif // NEORV32_HWSPINLOCK_H

View file

@ -28,7 +28,7 @@ typedef volatile struct __attribute__((packed,aligned(4))) {
const uint32_t CACHE; /**< offset 12: Cache configuration (#NEORV32_SYSINFO_CACHE_enum) */
} neorv32_sysinfo_t;
/** SYSINFO module hardware access (#neorv32_sysinfo_t) */
/** SYSINFO module hardware handle (#neorv32_sysinfo_t) */
#define NEORV32_SYSINFO ((neorv32_sysinfo_t*) (NEORV32_SYSINFO_BASE))
/** NEORV32_SYSINFO.MISC (r/-): Miscellaneous system configurations */
@ -41,37 +41,38 @@ enum NEORV32_SYSINFO_MISC_enum {
/** NEORV32_SYSINFO.SOC (r/-): Implemented processor devices/features */
enum NEORV32_SYSINFO_SOC_enum {
SYSINFO_SOC_BOOTLOADER = 0, /**< SYSINFO_SOC (0) (r/-): Bootloader implemented when 1 (via BOOT_MODE_SELECT generic) */
SYSINFO_SOC_XBUS = 1, /**< SYSINFO_SOC (1) (r/-): External bus interface implemented when 1 (via XBUS_EN generic) */
SYSINFO_SOC_MEM_INT_IMEM = 2, /**< SYSINFO_SOC (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_EN generic) */
SYSINFO_SOC_MEM_INT_DMEM = 3, /**< SYSINFO_SOC (3) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_EN generic) */
SYSINFO_SOC_OCD = 4, /**< SYSINFO_SOC (4) (r/-): On-chip debugger implemented when 1 (via OCD_EN generic) */
SYSINFO_SOC_ICACHE = 5, /**< SYSINFO_SOC (5) (r/-): Processor-internal instruction cache implemented when 1 (via ICACHE_EN generic) */
SYSINFO_SOC_DCACHE = 6, /**< SYSINFO_SOC (6) (r/-): Processor-internal instruction cache implemented when 1 (via DCACHE_EN generic) */
SYSINFO_SOC_XBUS_CACHE = 8, /**< SYSINFO_SOC (8) (r/-): External bus cache implemented when 1 (via XBUS_CACHE_EN generic) */
SYSINFO_SOC_OCD_AUTH = 11, /**< SYSINFO_SOC (11) (r/-): On-chip debugger authentication implemented when 1 (via OCD_AUTHENTICATION generic) */
SYSINFO_SOC_IMEM_ROM = 12, /**< SYSINFO_SOC (12) (r/-): Processor-internal instruction memory implemented as pre-initialized ROM when 1 (via BOOT_MODE_SELECT generic) */
SYSINFO_SOC_IO_TWD = 13, /**< SYSINFO_SOC (13) (r/-): Two-wire device implemented when 1 (via IO_TWD_EN generic) */
SYSINFO_SOC_IO_DMA = 14, /**< SYSINFO_SOC (14) (r/-): Direct memory access controller implemented when 1 (via IO_DMA_EN generic) */
SYSINFO_SOC_IO_GPIO = 15, /**< SYSINFO_SOC (15) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_EN generic) */
SYSINFO_SOC_IO_CLINT = 16, /**< SYSINFO_SOC (16) (r/-): Core local interruptor implemented when 1 (via IO_CLINT_EN generic) */
SYSINFO_SOC_IO_UART0 = 17, /**< SYSINFO_SOC (17) (r/-): Primary universal asynchronous receiver/transmitter 0 implemented when 1 (via IO_UART0_EN generic) */
SYSINFO_SOC_IO_SPI = 18, /**< SYSINFO_SOC (18) (r/-): Serial peripheral interface implemented when 1 (via IO_SPI_EN generic) */
SYSINFO_SOC_IO_TWI = 19, /**< SYSINFO_SOC (19) (r/-): Two-wire interface implemented when 1 (via IO_TWI_EN generic) */
SYSINFO_SOC_IO_PWM = 20, /**< SYSINFO_SOC (20) (r/-): Pulse-width modulation unit implemented when 1 (via IO_PWM_EN generic) */
SYSINFO_SOC_IO_WDT = 21, /**< SYSINFO_SOC (21) (r/-): Watchdog timer implemented when 1 (via IO_WDT_EN generic) */
SYSINFO_SOC_IO_CFS = 22, /**< SYSINFO_SOC (22) (r/-): Custom functions subsystem implemented when 1 (via IO_CFS_EN generic) */
SYSINFO_SOC_IO_TRNG = 23, /**< SYSINFO_SOC (23) (r/-): True random number generator implemented when 1 (via IO_TRNG_EN generic) */
SYSINFO_SOC_IO_SDI = 24, /**< SYSINFO_SOC (24) (r/-): Serial data interface implemented when 1 (via IO_SDI_EN generic) */
SYSINFO_SOC_IO_UART1 = 25, /**< SYSINFO_SOC (25) (r/-): Secondary universal asynchronous receiver/transmitter 1 implemented when 1 (via IO_UART1_EN generic) */
SYSINFO_SOC_IO_NEOLED = 26, /**< SYSINFO_SOC (26) (r/-): NeoPixel-compatible smart LED interface implemented when 1 (via IO_NEOLED_EN generic) */
SYSINFO_SOC_IO_GPTMR = 28, /**< SYSINFO_SOC (28) (r/-): General purpose timer implemented when 1 (via IO_GPTMR_EN generic) */
SYSINFO_SOC_IO_SLINK = 29, /**< SYSINFO_SOC (29) (r/-): Stream link interface implemented when 1 (via IO_SLINK_EN generic) */
SYSINFO_SOC_IO_ONEWIRE = 30, /**< SYSINFO_SOC (30) (r/-): 1-wire interface controller implemented when 1 (via IO_ONEWIRE_EN generic) */
SYSINFO_SOC_IO_CRC = 31 /**< SYSINFO_SOC (31) (r/-): Cyclic redundancy check unit implemented when 1 (via IO_CRC_EN generic) */
SYSINFO_SOC_BOOTLOADER = 0, /**< SYSINFO_SOC (0) (r/-): Bootloader implemented when 1 (via BOOT_MODE_SELECT generic) */
SYSINFO_SOC_XBUS = 1, /**< SYSINFO_SOC (1) (r/-): External bus interface implemented when 1 (via XBUS_EN generic) */
SYSINFO_SOC_MEM_INT_IMEM = 2, /**< SYSINFO_SOC (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_EN generic) */
SYSINFO_SOC_MEM_INT_DMEM = 3, /**< SYSINFO_SOC (3) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_EN generic) */
SYSINFO_SOC_OCD = 4, /**< SYSINFO_SOC (4) (r/-): On-chip debugger implemented when 1 (via OCD_EN generic) */
SYSINFO_SOC_ICACHE = 5, /**< SYSINFO_SOC (5) (r/-): Processor-internal instruction cache implemented when 1 (via ICACHE_EN generic) */
SYSINFO_SOC_DCACHE = 6, /**< SYSINFO_SOC (6) (r/-): Processor-internal instruction cache implemented when 1 (via DCACHE_EN generic) */
//SYSINFO_SOC_reserved = 7, /**< SYSINFO_SOC (7) (r/-): reserved */
SYSINFO_SOC_XBUS_CACHE = 8, /**< SYSINFO_SOC (8) (r/-): External bus cache implemented when 1 (via XBUS_CACHE_EN generic) */
//SYSINFO_SOC_reserved = 9, /**< SYSINFO_SOC (9) (r/-): reserved */
//SYSINFO_SOC_reserved = 10, /**< SYSINFO_SOC (10) (r/-): reserved */
SYSINFO_SOC_OCD_AUTH = 11, /**< SYSINFO_SOC (11) (r/-): On-chip debugger authentication implemented when 1 (via OCD_AUTHENTICATION generic) */
SYSINFO_SOC_IMEM_ROM = 12, /**< SYSINFO_SOC (12) (r/-): Processor-internal instruction memory implemented as pre-initialized ROM when 1 (via BOOT_MODE_SELECT generic) */
SYSINFO_SOC_IO_TWD = 13, /**< SYSINFO_SOC (13) (r/-): Two-wire device implemented when 1 (via IO_TWD_EN generic) */
SYSINFO_SOC_IO_DMA = 14, /**< SYSINFO_SOC (14) (r/-): Direct memory access controller implemented when 1 (via IO_DMA_EN generic) */
SYSINFO_SOC_IO_GPIO = 15, /**< SYSINFO_SOC (15) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_EN generic) */
SYSINFO_SOC_IO_CLINT = 16, /**< SYSINFO_SOC (16) (r/-): Core local interruptor implemented when 1 (via IO_CLINT_EN generic) */
SYSINFO_SOC_IO_UART0 = 17, /**< SYSINFO_SOC (17) (r/-): Primary universal asynchronous receiver/transmitter 0 implemented when 1 (via IO_UART0_EN generic) */
SYSINFO_SOC_IO_SPI = 18, /**< SYSINFO_SOC (18) (r/-): Serial peripheral interface implemented when 1 (via IO_SPI_EN generic) */
SYSINFO_SOC_IO_TWI = 19, /**< SYSINFO_SOC (19) (r/-): Two-wire interface implemented when 1 (via IO_TWI_EN generic) */
SYSINFO_SOC_IO_PWM = 20, /**< SYSINFO_SOC (20) (r/-): Pulse-width modulation unit implemented when 1 (via IO_PWM_EN generic) */
SYSINFO_SOC_IO_WDT = 21, /**< SYSINFO_SOC (21) (r/-): Watchdog timer implemented when 1 (via IO_WDT_EN generic) */
SYSINFO_SOC_IO_CFS = 22, /**< SYSINFO_SOC (22) (r/-): Custom functions subsystem implemented when 1 (via IO_CFS_EN generic) */
SYSINFO_SOC_IO_TRNG = 23, /**< SYSINFO_SOC (23) (r/-): True random number generator implemented when 1 (via IO_TRNG_EN generic) */
SYSINFO_SOC_IO_SDI = 24, /**< SYSINFO_SOC (24) (r/-): Serial data interface implemented when 1 (via IO_SDI_EN generic) */
SYSINFO_SOC_IO_UART1 = 25, /**< SYSINFO_SOC (25) (r/-): Secondary universal asynchronous receiver/transmitter 1 implemented when 1 (via IO_UART1_EN generic) */
SYSINFO_SOC_IO_NEOLED = 26, /**< SYSINFO_SOC (26) (r/-): NeoPixel-compatible smart LED interface implemented when 1 (via IO_NEOLED_EN generic) */
SYSINFO_SOC_IO_HWSPINLOCK = 27, /**< SYSINFO_SOC (27) (r/-): Hardware spinlocks implemented when 1 (via IO_HWSPINLOCK_EN generic) */
SYSINFO_SOC_IO_GPTMR = 28, /**< SYSINFO_SOC (28) (r/-): General purpose timer implemented when 1 (via IO_GPTMR_EN generic) */
SYSINFO_SOC_IO_SLINK = 29, /**< SYSINFO_SOC (29) (r/-): Stream link interface implemented when 1 (via IO_SLINK_EN generic) */
SYSINFO_SOC_IO_ONEWIRE = 30, /**< SYSINFO_SOC (30) (r/-): 1-wire interface controller implemented when 1 (via IO_ONEWIRE_EN generic) */
SYSINFO_SOC_IO_CRC = 31 /**< SYSINFO_SOC (31) (r/-): Cyclic redundancy check unit implemented when 1 (via IO_CRC_EN generic) */
};
/** NEORV32_SYSINFO.CACHE (r/-): Cache configuration */

View file

@ -520,25 +520,26 @@ void neorv32_aux_print_hw_config(void) {
// peripherals
neorv32_uart0_printf("Peripherals: ");
tmp = NEORV32_SYSINFO->SOC;
if (tmp & (1 << SYSINFO_SOC_IO_CFS)) { neorv32_uart0_printf("CFS "); }
if (tmp & (1 << SYSINFO_SOC_IO_CRC)) { neorv32_uart0_printf("CRC "); }
if (tmp & (1 << SYSINFO_SOC_IO_DMA)) { neorv32_uart0_printf("DMA "); }
if (tmp & (1 << SYSINFO_SOC_IO_GPIO)) { neorv32_uart0_printf("GPIO "); }
if (tmp & (1 << SYSINFO_SOC_IO_GPTMR)) { neorv32_uart0_printf("GPTMR "); }
if (tmp & (1 << SYSINFO_SOC_IO_CLINT)) { neorv32_uart0_printf("CLINT "); }
if (tmp & (1 << SYSINFO_SOC_IO_NEOLED)) { neorv32_uart0_printf("NEOLED "); }
if (tmp & (1 << SYSINFO_SOC_IO_ONEWIRE)) { neorv32_uart0_printf("ONEWIRE "); }
if (tmp & (1 << SYSINFO_SOC_IO_PWM)) { neorv32_uart0_printf("PWM "); }
if (tmp & (1 << SYSINFO_SOC_IO_SDI)) { neorv32_uart0_printf("SDI "); }
if (tmp & (1 << SYSINFO_SOC_IO_SLINK)) { neorv32_uart0_printf("SLINK "); }
if (tmp & (1 << SYSINFO_SOC_IO_SPI)) { neorv32_uart0_printf("SPI "); }
neorv32_uart0_printf("SYSINFO "); // always enabled
if (tmp & (1 << SYSINFO_SOC_IO_TRNG)) { neorv32_uart0_printf("TRNG "); }
if (tmp & (1 << SYSINFO_SOC_IO_TWD)) { neorv32_uart0_printf("TWD "); }
if (tmp & (1 << SYSINFO_SOC_IO_TWI)) { neorv32_uart0_printf("TWI "); }
if (tmp & (1 << SYSINFO_SOC_IO_UART0)) { neorv32_uart0_printf("UART0 "); }
if (tmp & (1 << SYSINFO_SOC_IO_UART1)) { neorv32_uart0_printf("UART1 "); }
if (tmp & (1 << SYSINFO_SOC_IO_WDT)) { neorv32_uart0_printf("WDT "); }
if (tmp & (1 << SYSINFO_SOC_IO_CFS)) { neorv32_uart0_printf("CFS "); }
if (tmp & (1 << SYSINFO_SOC_IO_CLINT)) { neorv32_uart0_printf("CLINT "); }
if (tmp & (1 << SYSINFO_SOC_IO_CRC)) { neorv32_uart0_printf("CRC "); }
if (tmp & (1 << SYSINFO_SOC_IO_DMA)) { neorv32_uart0_printf("DMA "); }
if (tmp & (1 << SYSINFO_SOC_IO_GPIO)) { neorv32_uart0_printf("GPIO "); }
if (tmp & (1 << SYSINFO_SOC_IO_GPTMR)) { neorv32_uart0_printf("GPTMR "); }
if (tmp & (1 << SYSINFO_SOC_IO_HWSPINLOCK)) { neorv32_uart0_printf("HWSPINLOCK "); }
if (tmp & (1 << SYSINFO_SOC_IO_NEOLED)) { neorv32_uart0_printf("NEOLED "); }
if (tmp & (1 << SYSINFO_SOC_IO_ONEWIRE)) { neorv32_uart0_printf("ONEWIRE "); }
if (tmp & (1 << SYSINFO_SOC_IO_PWM)) { neorv32_uart0_printf("PWM "); }
if (tmp & (1 << SYSINFO_SOC_IO_SDI)) { neorv32_uart0_printf("SDI "); }
if (tmp & (1 << SYSINFO_SOC_IO_SLINK)) { neorv32_uart0_printf("SLINK "); }
if (tmp & (1 << SYSINFO_SOC_IO_SPI)) { neorv32_uart0_printf("SPI "); }
neorv32_uart0_printf("SYSINFO "); // always enabled
if (tmp & (1 << SYSINFO_SOC_IO_TRNG)) { neorv32_uart0_printf("TRNG "); }
if (tmp & (1 << SYSINFO_SOC_IO_TWD)) { neorv32_uart0_printf("TWD "); }
if (tmp & (1 << SYSINFO_SOC_IO_TWI)) { neorv32_uart0_printf("TWI "); }
if (tmp & (1 << SYSINFO_SOC_IO_UART0)) { neorv32_uart0_printf("UART0 "); }
if (tmp & (1 << SYSINFO_SOC_IO_UART1)) { neorv32_uart0_printf("UART1 "); }
if (tmp & (1 << SYSINFO_SOC_IO_WDT)) { neorv32_uart0_printf("WDT "); }
neorv32_uart0_printf("\n\n");
}

View file

@ -0,0 +1,92 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
// SPDX-License-Identifier: BSD-3-Clause //
// ================================================================================ //
/**
* @file neorv32_hwspinlock.c
* @brief Hardware spinlock (HWSPINLOCK) HW driver source file.
*/
#include <neorv32.h>
/**********************************************************************//**
* Check if hardware spinlock module was synthesized.
*
* @return 0 if HWSPINLOCK was not synthesized, 1 if HWSPINLOCK is available.
**************************************************************************/
int neorv32_hwspinlock_available(void) {
if (NEORV32_SYSINFO->SOC & (1 << SYSINFO_SOC_IO_HWSPINLOCK)) {
return 1;
}
else {
return 0;
}
}
/**********************************************************************//**
* Try to acquire hardware spinlock.
*
* @param select Spinlock select (0..31).
* @return zero if spinlock successfully acquired, non-zero otherwise.
**************************************************************************/
int neorv32_hwspinlock_acquire(int select) {
return (int)(NEORV32_HWSPINLOCK->LOCK[select & 0x1f]);
}
/**********************************************************************//**
* Block until spinlock is acquired.
*
* @param select Spinlock select (0..31).
**************************************************************************/
void neorv32_hwspinlock_acquire_blocking(int select) {
while(1) {
if (neorv32_hwspinlock_acquire(select) == 0) {
return;
}
}
}
/**********************************************************************//**
* Release hardware spinlock.
*
* @param select Spinlock select (0..31).
**************************************************************************/
void neorv32_hwspinlock_release(int select) {
NEORV32_HWSPINLOCK->LOCK[select & 0x1f] = 0;
}
/**********************************************************************//**
* Probe state of hardware spinlock.
*
* @param select Spinlock select (0..31).
* @return State of selected spinlock (0 = unlocked, 1 = locked/acquired).
**************************************************************************/
int neorv32_hwspinlock_probe(int select) {
return (int)((NEORV32_HWSPINLOCK->STATUS >> (select & 0x1f)) & 1);
}
/**********************************************************************//**
* Clear/release all hardware spinlocks.
**************************************************************************/
void neorv32_hwspinlock_clear(void) {
int i;
for (i=0; i<32; i++) {
NEORV32_HWSPINLOCK->LOCK[i] = 0;
}
}

View file

@ -1589,6 +1589,35 @@
</registers>
</peripheral>
<!-- HWSPINLOCK -->
<!-- **************************************************************** -->
<peripheral>
<name>HWSPINLOCK</name>
<description>Hardware spinlocks</description>
<baseAddress>0xFFF30000</baseAddress>
<addressBlock>
<offset>0</offset>
<size>0x84</size>
<usage>registers</usage>
</addressBlock>
<registers>
<register>
<name>LOCK</name>
<description>32 locks, one binary spinlock per word</description>
<addressOffset>0x00</addressOffset>
<access>read-only</access>
</register>
<register>
<name>STATUS</name>
<description>Status of all 32 spinlocks</description>
<addressOffset>0x80</addressOffset>
<access>read-only</access>
</register>
</registers>
</peripheral>
<!-- SYSINFO -->
<!-- **************************************************************** -->
<peripheral>
@ -1640,7 +1669,7 @@
<field><name>SYSINFO_SOC_IO_DMA</name><bitRange>[14:14]</bitRange><description>Direct memory access controller implemented</description></field>
<field><name>SYSINFO_SOC_IO_GPIO</name><bitRange>[15:15]</bitRange><description>General purpose input/output port unit implemented</description></field>
<field><name>SYSINFO_SOC_IO_CLINT</name><bitRange>[16:16]</bitRange><description>Core local interruptor implemented</description></field>
<field><name>SYSINFO_SOC_IO_UART0</name><bitRange>[17:17]</bitRange><description>Primary universal asynchronous receiver/transmitter 0 implemented</description></field>
<field><name>SYSINFO_SOC_IO_UART0</name><bitRange>[17:17]</bitRange><description>Primary universal asynchronous receiver/transmitter implemented</description></field>
<field><name>SYSINFO_SOC_IO_SPI</name><bitRange>[18:18]</bitRange><description>Serial peripheral interface implemented</description></field>
<field><name>SYSINFO_SOC_IO_TWI</name><bitRange>[19:19]</bitRange><description>Two-wire interface implemented</description></field>
<field><name>SYSINFO_SOC_IO_PWM</name><bitRange>[20:20]</bitRange><description>Pulse-width modulation unit implemented</description></field>
@ -1648,7 +1677,8 @@
<field><name>SYSINFO_SOC_IO_CFS</name><bitRange>[22:22]</bitRange><description>Custom functions subsystem implemented</description></field>
<field><name>SYSINFO_SOC_IO_TRNG</name><bitRange>[23:23]</bitRange><description>True random number generator implemented</description></field>
<field><name>SYSINFO_SOC_IO_SDI</name><bitRange>[24:24]</bitRange><description>Serial data interface implemented</description></field>
<field><name>SYSINFO_SOC_IO_UART1</name><bitRange>[25:25]</bitRange><description>Secondary universal asynchronous receiver/transmitter 1 implemented</description></field>
<field><name>SYSINFO_SOC_IO_UART1</name><bitRange>[25:25]</bitRange><description>Secondary universal asynchronous receiver/transmitter implemented</description></field>
<field><name>SYSINFO_SOC_IO_HWSPINLOCK</name><bitRange>[27:27]</bitRange><description>Hardware spinlocks module implemented</description></field>
<field><name>SYSINFO_SOC_IO_NEOLED</name><bitRange>[26:26]</bitRange><description>NeoPixel-compatible smart LED interface implemented</description></field>
<field><name>SYSINFO_SOC_IO_GPTMR</name><bitRange>[28:28]</bitRange><description>General purpose timer implemented</description></field>
<field><name>SYSINFO_SOC_IO_SLINK</name><bitRange>[29:29]</bitRange><description>Stream link interface implemented</description></field>