Skip to content

Commit eb54003

Browse files
authored
minor rtl edits and cleanups (#1273)
2 parents 96ca209 + 1ef4bfa commit eb54003

16 files changed

+152
-229
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
2929

3030
| Date | Version | Comment | Ticket |
3131
|:----:|:-------:|:--------|:------:|
32+
| 23.05.2025 | 1.11.5.2 | minor rtl edits and cleanups | [#1273](https://github.com/stnolting/neorv32/pull/1273) |
3233
| 22.05.2025 | 1.11.5.1 | :bug: fix instruction fetch `ben`/`stb` signaling (has to be all-one -> always request full 32-bit words) | [#1272](https://github.com/stnolting/neorv32/pull/1272) |
3334
| 22.05.2025 | [**:rocket:1.11.5**](https://github.com/stnolting/neorv32/releases/tag/v1.11.5) | **New release** | |
3435
| 17.05.2025 | 1.11.4.9 | :bug: fix CPU's `lock` being cleared too early during atomic read-modify-write operations; :bug: fix cache's `ben` signal generation | [#1270](https://github.com/stnolting/neorv32/pull/1270) |

docs/datasheet/soc.adoc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ clock domain also using registers. However, for ASIC implementations it is recom
7777
to all inputs and output so the synthesis tool can insert an explicit IO (boundary) scan chain.
7878

7979
.NEORV32 Processor Signal List
80-
[cols="<4,^2,^2,^2,<7"]
80+
[cols="<3,^3,^2,^2,<7"]
8181
[options="header",grid="rows"]
8282
|=======================
8383
| Name | Width | Direction | Default | Description
8484
5+^| **Global Control (<<_processor_clocking>> and <<_processor_reset>>)**
85-
| `clk_i` | 1 | in | none | global clock line, all registers triggering on rising edge
86-
| `rstn_i` | 1 | in | none | global reset, asynchronous, **low-active**
87-
| `rstn_ocd_o` | 1 | out | none | <<_on_chip_debugger_ocd>> reset output, synchronous, **low-active**
88-
| `rstn_wdt_o` | 1 | out | none | <<_watchdog_timer_wdt>> reset output, synchronous, **low-active**
85+
| `clk_i` | 1 | in | - | global clock line, all registers triggering on rising edge
86+
| `rstn_i` | 1 | in | - | global reset, asynchronous, **low-active**
87+
| `rstn_ocd_o` | 1 | out | - | <<_on_chip_debugger_ocd>> reset output, synchronous, **low-active**
88+
| `rstn_wdt_o` | 1 | out | - | <<_watchdog_timer_wdt>> reset output, synchronous, **low-active**
8989
5+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
9090
| `jtag_tck_i` | 1 | in | `'L'` | serial clock
9191
| `jtag_tdi_i` | 1 | in | `'L'` | serial data input
@@ -153,8 +153,8 @@ to all inputs and output so the synthesis tool can insert an explicit IO (bounda
153153
5+^| **<<_pulse_width_modulation_controller_pwm>>**
154154
| `pwm_o` | 16 | out | - | pulse-width modulated channels
155155
5+^| **<<_custom_functions_subsystem_cfs>>**
156-
| `cfs_in_i` | 32 | in | `'L'` | custom CFS input signal conduit
157-
| `cfs_out_o` | 32 | out | - | custom CFS output signal conduit
156+
| `cfs_in_i` | `IO_CFS_IN_SIZE` | in | `'L'` | custom CFS input signal conduit
157+
| `cfs_out_o` | `IO_CFS_OUT_SIZE` | out | - | custom CFS output signal conduit
158158
5+^| **<<_smart_led_interface_neoled>>**
159159
| `neoled_o` | 1 | out | - | asynchronous serial data output
160160
5+^| **<<_core_local_interruptor_clint>>**
@@ -290,8 +290,8 @@ The generic type "`suv(x:y)`" is an abbreviation for "`std_ulogic_vector(x downt
290290
| `IO_TRNG_FIFO` | natural | 1 | Depth of the TRNG data FIFO. Has to be a power of two, min 1, max 32768.
291291
| `IO_CFS_EN` | boolean | false | Implement the <<_custom_functions_subsystem_cfs>>.
292292
| `IO_CFS_CONFIG` | suv(31:0) | x"00000000" | "Conduit" generic to pass user-defined flags to the <<_custom_functions_subsystem_cfs>>.
293-
| `IO_CFS_IN_SIZE` | natural | 32 | Size of the <<_custom_functions_subsystem_cfs>> input signal conduit (`cfs_in_i`).
294-
| `IO_CFS_OUT_SIZE` | natural | 32 | Size of the <<_custom_functions_subsystem_cfs>> output signal conduit (`cfs_out_o`).
293+
| `IO_CFS_IN_SIZE` | natural | 32 | Size of the <<_custom_functions_subsystem_cfs>> input signal conduit (`cfs_in_i`), max 4096.
294+
| `IO_CFS_OUT_SIZE` | natural | 32 | Size of the <<_custom_functions_subsystem_cfs>> output signal conduit (`cfs_out_o`), max 4096.
295295
| `IO_NEOLED_EN` | boolean | false | Implement the <<_smart_led_interface_neoled>>.
296296
| `IO_NEOLED_TX_FIFO` | natural | 1 | TX FIFO depth of the <<_smart_led_interface_neoled>>. Has to be a power of two, min 1, max 32768.
297297
| `IO_GPTMR_EN` | boolean | false | Implement the <<_general_purpose_timer_gptmr>>.

docs/datasheet/soc_cfs.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
| | `cfs_out_o` | custom output conduit
1313
| Configuration generics: | `IO_CFS_EN` | implement CFS when `true`
1414
| | `IO_CFS_CONFIG` | custom generic conduit
15-
| | `IO_CFS_IN_SIZE` | size of `cfs_in_i`
16-
| | `IO_CFS_OUT_SIZE` | size of `cfs_out_o`
15+
| | `IO_CFS_IN_SIZE` | size of `cfs_in_i`, max 4096
16+
| | `IO_CFS_OUT_SIZE` | size of `cfs_out_o``, max 4096
1717
| CPU interrupts: | fast IRQ channel 1 | CFS interrupt (see <<_processor_interrupts>>)
1818
|=======================
1919

docs/datasheet/soc_dcache.adoc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ The data cache is implemented if `DCACHE_EN` it _true_. The total cache memory s
2727
`DCACHE_NUM_BLOCKS x CACHE_BLOCK_SIZE`. `DCACHE_NUM_BLOCKS` defines the number of cache blocks (or "cache lines")
2828
and `CACHE_BLOCK_SIZE` defines the block size in bytes; note that this configuration is global for all caches.
2929

30-
.Retrieve Cache Configuration from Software
31-
[TIP]
32-
Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register.
30+
.Burst Transfers
31+
[IMPORTANT]
32+
If the cache is activated, this also means that cache block transfers are **always executed as burst transfers**.
33+
There is no possibility to execute the cache block transfers as single bus transactions. Therefore, all devices,
34+
memories and endpoints that can be accessed by the cache must also be able to process bursts.
3335

3436
.Uncached Accesses
3537
[NOTE]
@@ -48,3 +50,7 @@ See section <<_memory_coherence>> for more information.
4850
If the cache encounters a bus error when uploading a modified block to main memory or when
4951
downloading a new block from main memory, the entire block is invalidated and a bus access
5052
error exception is raised.
53+
54+
.Retrieve Cache Configuration from Software
55+
[TIP]
56+
Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register.

docs/datasheet/soc_icache.adoc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ The instruction cache is implemented if `ICACHE_EN` it _true_. The total cache m
2727
`ICACHE_NUM_BLOCKS x CACHE_BLOCK_SIZE`. `ICACHE_NUM_BLOCKS` defines the number of cache blocks (or "cache lines")
2828
and `CACHE_BLOCK_SIZE` defines the block size in bytes; note that this configuration is global for all caches.
2929

30-
.Retrieve Cache Configuration from Software
31-
[TIP]
32-
Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register.
30+
.Burst Transfers
31+
[IMPORTANT]
32+
If the cache is activated, this also means that cache block transfers are **always executed as burst transfers**.
33+
There is no possibility to execute the cache block transfers as single bus transactions. Therefore, all devices,
34+
memories and endpoints that can be accessed by the cache must also be able to process bursts.
3335

3436
.Uncached Accesses
3537
[NOTE]
@@ -47,3 +49,7 @@ See section <<_memory_coherence>> for more information.
4749
[NOTE]
4850
If the cache encounters a bus error when downloading a new block from main memory, the
4951
entire block is invalidated and a bus access error exception is raised.
52+
53+
.Retrieve Cache Configuration from Software
54+
[TIP]
55+
Software can retrieve the cache configuration/layout from the <<_sysinfo_cache_configuration>> register.

docs/datasheet/soc_xbus.adoc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,24 @@ The external bus interface provides a **Wishbone**-compatible on-chip bus interf
3131
can be used to attach processor-external modules like memories, custom hardware accelerators or additional
3232
peripheral devices.
3333

34-
.Wishbone Specs
35-
[TIP]
36-
The official Wishbone specification scan be found online:
37-
https://wishbone-interconnect.readthedocs.io/en/latest/index.html
34+
.Burst Transfers
35+
[IMPORTANT]
36+
If any cache (<<_processor_internal_instruction_cache_icache>>, <<_processor_internal_data_cache_dcache>>) is
37+
enabled, this also means that cache block transfers are **always executed as burst transfers**. There is no
38+
possibility to execute the cache block transfers as single bus transactions. Therefore, all devices,
39+
memories and endpoints that can be accessed by the cache must also be able to process bursts.
3840

3941
.Address Mapping
4042
[NOTE]
4143
The external interface is **not** mapped to a specific address range. Instead, all CPU memory accesses that
4244
do not target a specific (and actually implemented) processor-internal address region (hence, accessing the "void";
4345
see section <<_address_space>>) are **redirected** to the external bus interface.
4446

47+
.Wishbone Specs
48+
[TIP]
49+
The official Wishbone specification scan be found online:
50+
https://wishbone-interconnect.readthedocs.io/en/latest/index.html
51+
4552
.AXI4 Interface Bridge
4653
[TIP]
4754
A bridge that converts the processor's XBUS interface into an AXI4-compatible host interface is available

rtl/core/neorv32_boot_rom.vhd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- ================================================================================ --
2-
-- NEORV32 SoC - Processor-internal bootloader ROM (BOOTROM) --
2+
-- NEORV32 SoC - Processor-Internal Bootloader ROM (BOOTROM) --
33
-- -------------------------------------------------------------------------------- --
44
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
55
-- Copyright (c) NEORV32 contributors. --
@@ -45,7 +45,9 @@ begin
4545
mem_access: process(clk_i)
4646
begin
4747
if rising_edge(clk_i) then -- no reset to infer block RAM
48-
rdata <= mem_rom_c(to_integer(unsigned(bus_req_i.addr(boot_rom_size_index_c+1 downto 2))));
48+
if (bus_req_i.stb = '1') then -- reduce switching activity when not accessed
49+
rdata <= mem_rom_c(to_integer(unsigned(bus_req_i.addr(boot_rom_size_index_c+1 downto 2))));
50+
end if;
4951
end if;
5052
end process mem_access;
5153

rtl/core/neorv32_bus.vhd

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use neorv32.neorv32_package.all;
1616

1717
entity neorv32_bus_switch is
1818
generic (
19-
ROUND_ROBIN_EN : boolean := false; -- enable round-robin arbitration
20-
PORT_A_READ_ONLY : boolean := false; -- set if port A is read-only
21-
PORT_B_READ_ONLY : boolean := false -- set if port B is read-only
19+
ROUND_ROBIN_EN : boolean := false; -- enable round-robin arbitration
20+
A_READ_ONLY : boolean := false; -- set if port A is read-only
21+
B_READ_ONLY : boolean := false -- set if port B is read-only
2222
);
2323
port (
2424
clk_i : in std_ulogic; -- global clock, rising edge
@@ -137,19 +137,19 @@ begin
137137

138138
-- Request Switch -------------------------------------------------------------------------
139139
-- -------------------------------------------------------------------------------------------
140-
x_req_o.addr <= a_req_i.addr when (sel = '0') else b_req_i.addr;
141-
x_req_o.data <= b_req_i.data when PORT_A_READ_ONLY else
142-
a_req_i.data when PORT_B_READ_ONLY else
143-
a_req_i.data when (sel = '0') else b_req_i.data;
144-
x_req_o.ben <= a_req_i.ben when (sel = '0') else b_req_i.ben;
145-
x_req_o.rw <= a_req_i.rw when (sel = '0') else b_req_i.rw;
146-
x_req_o.src <= a_req_i.src when (sel = '0') else b_req_i.src;
147-
x_req_o.priv <= a_req_i.priv when (sel = '0') else b_req_i.priv;
148-
x_req_o.debug <= a_req_i.debug when (sel = '0') else b_req_i.debug;
149-
x_req_o.amo <= a_req_i.amo when (sel = '0') else b_req_i.amo;
150-
x_req_o.amoop <= a_req_i.amoop when (sel = '0') else b_req_i.amoop;
151-
x_req_o.burst <= a_req_i.burst when (sel = '0') else b_req_i.burst;
152-
x_req_o.lock <= a_req_i.lock when (sel = '0') else b_req_i.lock;
140+
x_req_o.addr <= a_req_i.addr when (sel = '0') else b_req_i.addr;
141+
x_req_o.data <= b_req_i.data when A_READ_ONLY else
142+
a_req_i.data when B_READ_ONLY else
143+
a_req_i.data when (sel = '0') else b_req_i.data;
144+
x_req_o.ben <= a_req_i.ben when (sel = '0') else b_req_i.ben;
145+
x_req_o.rw <= a_req_i.rw when (sel = '0') else b_req_i.rw;
146+
x_req_o.src <= a_req_i.src when (sel = '0') else b_req_i.src;
147+
x_req_o.priv <= a_req_i.priv when (sel = '0') else b_req_i.priv;
148+
x_req_o.debug <= a_req_i.debug when (sel = '0') else b_req_i.debug;
149+
x_req_o.amo <= a_req_i.amo when (sel = '0') else b_req_i.amo;
150+
x_req_o.amoop <= a_req_i.amoop when (sel = '0') else b_req_i.amoop;
151+
x_req_o.burst <= a_req_i.burst when (sel = '0') else b_req_i.burst;
152+
x_req_o.lock <= a_req_i.lock when (sel = '0') else b_req_i.lock;
153153
x_req_o.fence <= a_req_i.fence or b_req_i.fence;
154154
x_req_o.stb <= stb;
155155

rtl/core/neorv32_cache.vhd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ begin
168168

169169
when S_IDLE => -- wait for request
170170
-- ------------------------------------------------------------
171-
if (host_req_i.fence = '1') or (ctrl.buf_sync = '1') then -- (pending) sync request
171+
if (ctrl.buf_sync = '1') then -- pending sync request
172172
ctrl_nxt.state <= S_CLEAR;
173173
elsif (host_req_i.stb = '1') or (ctrl.buf_req = '1') then -- (pending) access request
174174
if (unsigned(host_req_i.addr(31 downto 28)) >= unsigned(UC_BEGIN)) or -- uncached address space

rtl/core/neorv32_cfs.vhd

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
-- ================================================================================ --
22
-- NEORV32 SoC - Custom Functions Subsystem (CFS) --
33
-- -------------------------------------------------------------------------------- --
4-
-- Intended for tightly-coupled, application-specific custom co-processors. This --
5-
-- module provides up to 64x 32-bit memory-mapped interface registers, one CPU --
6-
-- interrupt request signal and custom IO conduits for processor-external or chip- --
7-
-- external interface. --
8-
-- -------------------------------------------------------------------------------- --
94
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
105
-- Copyright (c) NEORV32 contributors. --
116
-- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. --
@@ -23,8 +18,8 @@ use neorv32.neorv32_package.all;
2318
entity neorv32_cfs is
2419
generic (
2520
CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
26-
CFS_IN_SIZE : natural; -- size of CFS input conduit in bits
27-
CFS_OUT_SIZE : natural -- size of CFS output conduit in bits
21+
CFS_IN_SIZE : natural range 0 to 4096; -- size of CFS input conduit in bits
22+
CFS_OUT_SIZE : natural range 0 to 4096 -- size of CFS output conduit in bits
2823
);
2924
port (
3025
clk_i : in std_ulogic; -- global clock line
@@ -34,8 +29,8 @@ entity neorv32_cfs is
3429
clkgen_en_o : out std_ulogic; -- enable clock generator
3530
clkgen_i : in std_ulogic_vector(7 downto 0); -- "clock" inputs
3631
irq_o : out std_ulogic; -- interrupt request
37-
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs
38-
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs
32+
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs conduit
33+
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs conduit
3934
);
4035
end neorv32_cfs;
4136

@@ -71,11 +66,6 @@ begin
7166
-- -------------------------------------------------------------------------------------------
7267
-- The CFS can be reset using the global rstn_i signal. This signal should be used as asynchronous reset and is active-low.
7368
-- Note that rstn_i can be asserted by a processor-external reset, the on-chip debugger and also by the watchdog.
74-
--
75-
-- Most default peripheral devices of the NEORV32 do NOT use a dedicated hardware reset at all. Instead, these units are
76-
-- reset by writing ZERO to a specific "control register" located right at the beginning of the device's address space
77-
-- (so this register is cleared at first). The crt0 start-up code writes ZERO to every single address in the processor's
78-
-- IO space - including the CFS. Make sure that this initial clearing does not cause any unintended CFS actions.
7969

8070

8171
-- Clock System ---------------------------------------------------------------------------
@@ -84,7 +74,7 @@ begin
8474
-- Actually, these signals should not be used as direct clock signals, but as *clock enable* signals.
8575
-- clkgen_i is always synchronous to the main system clock (clk_i).
8676
--
87-
-- The following clock dividers are available:
77+
-- The following pre-scaled clock enabled are available:
8878
-- > clkgen_i(clk_div2_c) -> MAIN_CLK/2
8979
-- > clkgen_i(clk_div4_c) -> MAIN_CLK/4
9080
-- > clkgen_i(clk_div8_c) -> MAIN_CLK/8
@@ -96,9 +86,7 @@ begin
9686
--
9787
-- For instance, if you want to drive a clock process at MAIN_CLK/8 clock speed you can use the following construct:
9888
--
99-
-- if (rstn_i = '0') then -- async and low-active reset (if required at all)
100-
-- ...
101-
-- elsif rising_edge(clk_i) then -- always use the main clock for all clock processes
89+
-- if rising_edge(clk_i) then -- always use the main clock for all clock processes
10290
-- if (clkgen_i(clk_div8_c) = '1') then -- the div8 "clock" is actually a clock enable
10391
-- ...
10492
-- end if;
@@ -107,8 +95,8 @@ begin
10795
-- The clkgen_i input clocks are available when at least one IO/peripheral device (for example UART0) requires the clocks
10896
-- generated by the clock generator. The CFS can enable the clock generator by itself by setting the clkgen_en_o signal high.
10997
-- The CFS cannot ensure to deactivate the clock generator by setting the clkgen_en_o signal low as other peripherals might
110-
-- still keep the generator activated. Make sure to deactivate the CFS's clkgen_en_o if no clocks are required in here to
111-
-- reduce dynamic power consumption.
98+
-- still keep the generator activated. Make sure to deactivate the CFS's clkgen_en_o if no scaled clocks are required in here
99+
-- to reduce dynamic power consumption.
112100

113101
clkgen_en_o <= '0'; -- not used for this minimal example
114102

0 commit comments

Comments
 (0)