diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64fc48aa9..f40632a35 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
+| 01.02.2025 | 1.11.0.5 | minor rtl optimizations and cleanups; :warning: remove DMA "fence" feature | [#1174](https://github.com/stnolting/neorv32/pull/1174) |
| 28.01.2025 | 1.11.0.4 | :bug: fix crt0's entry address being overridden by core0's constructors (that do not backup any registers) | [#1172](https://github.com/stnolting/neorv32/pull/1172) |
| 28.01.2025 | 1.11.0.3 | :bug: fix BOOTROM addressing (index was out-of-range) | [#1171](https://github.com/stnolting/neorv32/pull/1171) |
| 24.01.2025 | 1.11.0.2 | :warning: rename JEDEC ID generic; minor rtl edits and optimizations | [#1168](https://github.com/stnolting/neorv32/pull/1168) |
diff --git a/docs/datasheet/soc_dma.adoc b/docs/datasheet/soc_dma.adoc
index 374d03b9c..6d99b677e 100644
--- a/docs/datasheet/soc_dma.adoc
+++ b/docs/datasheet/soc_dma.adoc
@@ -119,13 +119,6 @@ The DMA transfer will start if a **rising edge** is detected on the configured F
once even if the selected FIRQ channel keeps pending.
-**Memory Barrier / Fence Operation**
-
-Optionally, the DMA can issue a FENCE request to the downstream memory system when a transfer has been completed
-without errors. This can be used to re-sync caches (flush and reload) and buffers to maintain data coherency.
-This automatic fencing is enabled by the setting the control register's `DMA_CTRL_FENCE` bit.
-
-
**DMA Interrupt**
The DMA features a single CPU interrupt that is triggered when the programmed transfer has completed. This
@@ -141,10 +134,9 @@ register).
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
-.12+<| `0xffed0000` .12+<| `CTRL` <|`0` `DMA_CTRL_EN` ^| r/w <| DMA module enable
+.11+<| `0xffed0000` .11+<| `CTRL` <|`0` `DMA_CTRL_EN` ^| r/w <| DMA module enable
<|`1` `DMA_CTRL_AUTO` ^| r/w <| Enable automatic mode (FIRQ-triggered)
- <|`2` `DMA_CTRL_FENCE` ^| r/w <| Issue a downstream FENCE operation when DMA transfer completes (without errors)
- <|`7:3` _reserved_ ^| r/- <| reserved, read as zero
+ <|`7:2` _reserved_ ^| r/- <| reserved, read as zero
<|`8` `DMA_CTRL_ERROR_RD` ^| r/- <| Error during read access, clears when starting a new transfer
<|`9` `DMA_CTRL_ERROR_WR` ^| r/- <| Error during write access, clears when starting a new transfer
<|`10` `DMA_CTRL_BUSY` ^| r/- <| DMA transfer in progress
diff --git a/rtl/core/neorv32_application_image.vhd b/rtl/core/neorv32_application_image.vhd
index ddf85babb..62ae4aac4 100644
--- a/rtl/core/neorv32_application_image.vhd
+++ b/rtl/core/neorv32_application_image.vhd
@@ -1,7 +1,7 @@
-- The NEORV32 RISC-V Processor - github.com/stnolting/neorv32
-- Auto-generated memory initialization image (for internal IMEM)
-- Source: demo_blink_led/build/main.bin
--- Built: 15.01.2025 21:11:45
+-- Built: 01.02.2025 15:17:07
library ieee;
use ieee.std_logic_1164.all;
@@ -11,7 +11,7 @@ use neorv32.neorv32_package.all;
package neorv32_application_image is
-constant application_init_size_c : natural := 1204; -- bytes
+constant application_init_size_c : natural := 1208; -- bytes
constant application_init_image_c : mem32_t := (
x"f14020f3",
x"80002217",
@@ -23,11 +23,11 @@ x"000022b7",
x"80028293",
x"30029073",
x"00000317",
-x"18830313",
+x"18c30313",
x"30531073",
x"30401073",
x"00000397",
-x"48038393",
+x"48438393",
x"80000417",
x"fc440413",
x"80000497",
@@ -36,8 +36,7 @@ x"80000517",
x"fb450513",
x"80000597",
x"fac58593",
-x"00000617",
-x"19060613",
+x"00000613",
x"00000693",
x"00000713",
x"00000793",
@@ -63,7 +62,7 @@ x"01878793",
x"30579073",
x"30446073",
x"30046073",
-x"0dc0006f",
+x"0e40006f",
x"fff40737",
x"00072223",
x"bc1026f3",
@@ -74,7 +73,7 @@ x"30200073",
x"bc102173",
x"bc102673",
x"bc171073",
-x"0540006f",
+x"05c0006f",
x"00838e63",
x"00945c63",
x"0003a783",
@@ -87,14 +86,16 @@ x"00052023",
x"00450513",
x"ff5ff06f",
x"00000417",
-x"39040413",
+x"39840413",
x"00000497",
-x"38848493",
+x"39048493",
x"00945a63",
x"00042083",
x"000080e7",
x"00440413",
x"ff1ff06f",
+x"00000617",
+x"0ac60613",
x"0ff0000f",
x"0000100f",
x"30029073",
diff --git a/rtl/core/neorv32_bootloader_image.vhd b/rtl/core/neorv32_bootloader_image.vhd
index 092bb9bfb..665022923 100644
--- a/rtl/core/neorv32_bootloader_image.vhd
+++ b/rtl/core/neorv32_bootloader_image.vhd
@@ -1,7 +1,7 @@
-- The NEORV32 RISC-V Processor - github.com/stnolting/neorv32
-- Auto-generated memory initialization image (for internal BOOTROM)
-- Source: bootloader/build/main.bin
--- Built: 15.01.2025 21:12:00
+-- Built: 01.02.2025 15:16:28
library ieee;
use ieee.std_logic_1164.all;
@@ -11,7 +11,7 @@ use neorv32.neorv32_package.all;
package neorv32_bootloader_image is
-constant bootloader_init_size_c : natural := 4028; -- bytes
+constant bootloader_init_size_c : natural := 4040; -- bytes
constant bootloader_init_image_c : mem32_t := (
x"f14020f3",
x"80200217",
@@ -23,11 +23,11 @@ x"000022b7",
x"80028293",
x"30029073",
x"00000317",
-x"0f830313",
+x"0fc30313",
x"30531073",
x"30401073",
x"00001397",
-x"f8838393",
+x"f9438393",
x"80200417",
x"fc440413",
x"80200497",
@@ -36,8 +36,7 @@ x"80200517",
x"fb450513",
x"80200597",
x"fb458593",
-x"00000617",
-x"10060613",
+x"00000613",
x"00000693",
x"00000713",
x"00000793",
@@ -47,7 +46,7 @@ x"01878793",
x"30579073",
x"30446073",
x"30046073",
-x"08c0006f",
+x"0940006f",
x"fff40737",
x"00072223",
x"bc1026f3",
@@ -58,7 +57,7 @@ x"30200073",
x"bc102173",
x"bc102673",
x"bc171073",
-x"0300006f",
+x"0380006f",
x"00838e63",
x"00945c63",
x"0003a783",
@@ -70,6 +69,8 @@ x"00b55863",
x"00052023",
x"00450513",
x"ff5ff06f",
+x"00000617",
+x"08060613",
x"0ff0000f",
x"0000100f",
x"30029073",
@@ -109,7 +110,7 @@ x"ffe017b7",
x"00112823",
x"00812623",
x"00912423",
-x"a2c78793",
+x"a3078793",
x"30579073",
x"fffe07b7",
x"0087a783",
@@ -192,54 +193,54 @@ x"30479073",
x"00800793",
x"3007a073",
x"ffe01537",
-x"da450513",
+x"db050513",
x"6b4000ef",
x"f1302573",
x"648000ef",
x"ffe01537",
-x"ddc50513",
+x"de850513",
x"6a0000ef",
x"fffe0437",
x"00042503",
x"630000ef",
x"ffe01537",
-x"de450513",
+x"df050513",
x"688000ef",
x"30102573",
x"61c000ef",
x"ffe01537",
-x"dec50513",
+x"df850513",
x"674000ef",
x"fc002573",
x"608000ef",
x"ffe01537",
-x"df450513",
+x"e0050513",
x"660000ef",
x"00842503",
x"00100493",
x"5f0000ef",
x"ffe01537",
-x"dfc50513",
+x"e0850513",
x"648000ef",
x"00444503",
x"00a49533",
x"ffc57513",
x"5d4000ef",
x"ffe01537",
-x"e0450513",
+x"e1050513",
x"62c000ef",
x"00544783",
x"00f49533",
x"ffc57513",
x"5b8000ef",
x"ffe014b7",
-x"da048513",
+x"dac48513",
x"610000ef",
x"00842783",
x"00f79713",
x"06075063",
x"ffe01537",
-x"e0c50513",
+x"e1850513",
x"5f8000ef",
x"2e0000ef",
x"00042703",
@@ -259,13 +260,13 @@ x"00f69613",
x"0a065463",
x"ffe01537",
x"00472783",
-x"e3850513",
+x"e4450513",
x"5a8000ef",
x"ffe017b7",
-x"e4478513",
+x"e5078513",
x"59c000ef",
x"ffe01537",
-x"ec450513",
+x"ed050513",
x"590000ef",
x"fff507b7",
x"0007a703",
@@ -275,14 +276,14 @@ x"0047a403",
x"0ff47413",
x"00040513",
x"4f4000ef",
-x"da048513",
+x"dac48513",
x"568000ef",
x"f9b40413",
x"0ff47413",
x"01300793",
x"2287e863",
x"ffe017b7",
-x"f4078793",
+x"f4c78793",
x"00241413",
x"00f40433",
x"00042783",
@@ -306,10 +307,10 @@ x"00b41463",
x"f2f564e3",
x"00100513",
x"6f4000ef",
-x"da048513",
+x"dac48513",
x"4ec000ef",
x"00000513",
-x"02d000ef",
+x"035000ef",
x"ffe002b7",
x"00028067",
x"00000513",
@@ -319,20 +320,20 @@ x"800007b7",
x"0047a403",
x"00041863",
x"ffe01537",
-x"ecc50513",
+x"ed850513",
x"f1dff06f",
x"ffe01537",
-x"ee850513",
+x"ef450513",
x"4ac000ef",
x"00040513",
x"440000ef",
x"ffe01537",
-x"ef050513",
+x"efc50513",
x"498000ef",
x"00400537",
x"42c000ef",
x"ffe01537",
-x"f0850513",
+x"f1450513",
x"484000ef",
x"fff507b7",
x"0007a703",
@@ -350,7 +351,7 @@ x"00050663",
x"00300513",
x"498000ef",
x"ffe01537",
-x"f1450513",
+x"f2050513",
x"43c000ef",
x"01045793",
x"00178793",
@@ -388,7 +389,7 @@ x"00850513",
x"40e005b3",
x"2a8000ef",
x"ffe01537",
-x"d8850513",
+x"d9450513",
x"e09ff06f",
x"00f12223",
x"1ec000ef",
@@ -414,14 +415,14 @@ x"800007b7",
x"0047a783",
x"e60790e3",
x"ffe01537",
-x"f2450513",
+x"f3050513",
x"da1ff06f",
x"fffe07b7",
x"0087a783",
x"2007f793",
x"00079863",
x"ffe01537",
-x"f3450513",
+x"f4050513",
x"d85ff06f",
x"00100513",
x"e35ff06f",
@@ -610,7 +611,7 @@ x"01c00493",
x"00945733",
x"ffe017b7",
x"00f77713",
-x"f9078793",
+x"f9c78793",
x"00e787b3",
x"0007c503",
x"ffc48493",
@@ -646,13 +647,13 @@ x"ff810113",
x"00812023",
x"00050413",
x"ffe01537",
-x"d3050513",
+x"d3c50513",
x"00112223",
x"f99ff0ef",
x"00241793",
x"ffe01537",
x"008787b3",
-x"fa050513",
+x"fac50513",
x"00f50533",
x"f81ff0ef",
x"00800793",
@@ -732,7 +733,7 @@ x"0087a783",
x"00e79713",
x"04075263",
x"ffe01537",
-x"d3850513",
+x"d4450513",
x"e45ff0ef",
x"00048513",
x"dd9ff0ef",
@@ -745,7 +746,7 @@ x"da9ff0ef",
x"34302573",
x"db9ff0ef",
x"ffe01537",
-x"da050513",
+x"dac50513",
x"e11ff0ef",
x"00440413",
x"34141073",
@@ -760,7 +761,7 @@ x"00a12023",
x"00f72023",
x"02f50a63",
x"ffe01537",
-x"d4450513",
+x"d5050513",
x"dd5ff0ef",
x"00000413",
x"00012503",
@@ -772,12 +773,12 @@ x"04f50a63",
x"00000513",
x"0380006f",
x"ffe01537",
-x"d6450513",
+x"d7050513",
x"da5ff0ef",
x"00400537",
x"d39ff0ef",
x"ffe01537",
-x"d8050513",
+x"d8c50513",
x"d91ff0ef",
x"fffe07b7",
x"0087a783",
@@ -802,17 +803,19 @@ x"ffc4f693",
x"00000793",
x"00000413",
x"00f605b3",
-x"04d79063",
+x"04d79463",
x"00e40433",
x"00200513",
x"fa0416e3",
x"ffe01537",
-x"d8850513",
+x"d9450513",
x"d19ff0ef",
-x"01c12083",
-x"01812403",
x"800007b7",
x"0097a223",
+x"0ff0000f",
+x"0000100f",
+x"01c12083",
+x"01812403",
x"800007b7",
x"0007a023",
x"01412483",
@@ -823,7 +826,7 @@ x"00d12823",
x"00f12623",
x"00c12423",
x"00e12223",
-x"a89ff0ef",
+x"a81ff0ef",
x"00c12783",
x"01012683",
x"00812603",
@@ -831,7 +834,7 @@ x"00a7a023",
x"00412703",
x"00a40433",
x"00478793",
-x"f89ff06f",
+x"f81ff06f",
x"ff810113",
x"00112223",
x"00812023",
@@ -842,14 +845,14 @@ x"40a00533",
x"e0400437",
x"00a47433",
x"ffe01537",
-x"d8c50513",
-x"c8dff0ef",
+x"d9850513",
+x"c85ff0ef",
x"00040513",
-x"c21ff0ef",
+x"c19ff0ef",
x"ffe01537",
-x"d9c50513",
-x"c79ff0ef",
-x"979ff0ef",
+x"da850513",
+x"c71ff0ef",
+x"971ff0ef",
x"00050663",
x"fffc07b7",
x"0007a223",
@@ -894,9 +897,9 @@ x"6f6c746f",
x"72656461",
x"0a3e3e20",
x"444c420a",
-x"4a203a56",
-x"31206e61",
-x"30322035",
+x"46203a56",
+x"20206265",
+x"30322031",
x"480a3532",
x"203a5657",
x"00000020",
@@ -989,26 +992,26 @@ x"00002e65",
x"61766e49",
x"2064696c",
x"00444d43",
-x"ffe00634",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe003e0",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0062c",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe004a4",
-x"ffe004b8",
-x"ffe0065c",
-x"ffe004ac",
-x"ffe0065c",
-x"ffe0065c",
-x"ffe0064c",
+x"ffe00638",
+x"ffe00660",
+x"ffe00660",
+x"ffe003e4",
+x"ffe00660",
+x"ffe00660",
+x"ffe00660",
+x"ffe00630",
+x"ffe00660",
+x"ffe00660",
+x"ffe00660",
+x"ffe00660",
+x"ffe00660",
+x"ffe004a8",
+x"ffe004bc",
+x"ffe00660",
+x"ffe004b0",
+x"ffe00660",
+x"ffe00660",
+x"ffe00650",
x"33323130",
x"37363534",
x"62613938",
diff --git a/rtl/core/neorv32_cpu_lsu.vhd b/rtl/core/neorv32_cpu_lsu.vhd
index 28c32c4bf..59a0907f2 100644
--- a/rtl/core/neorv32_cpu_lsu.vhd
+++ b/rtl/core/neorv32_cpu_lsu.vhd
@@ -77,7 +77,7 @@ begin
begin
if (rstn_i = '0') then
dbus_req_o.rw <= '0';
- dbus_req_o.priv <= '0';
+ dbus_req_o.priv <= priv_mode_m_c;
dbus_req_o.amo <= '0';
dbus_req_o.amoop <= (others => '0');
dbus_req_o.data <= (others => '0');
diff --git a/rtl/core/neorv32_debug_dm.vhd b/rtl/core/neorv32_debug_dm.vhd
index 237e58a3d..9d602f5df 100644
--- a/rtl/core/neorv32_debug_dm.vhd
+++ b/rtl/core/neorv32_debug_dm.vhd
@@ -6,7 +6,7 @@
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
--- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. --
+-- 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 --
-- ================================================================================ --
@@ -148,9 +148,9 @@ architecture neorv32_debug_dm_rtl of neorv32_debug_dm is
-- copied manually from 'sw/ocd-firmware/neorv32_application_image.vhd' --
type code_rom_t is array (0 to 31) of std_ulogic_vector(31 downto 0);
constant code_rom_c : code_rom_t := (
- 00 => x"f8002623",
- 01 => x"7b202473",
- 02 => x"00100073",
+ 00 => x"0ff0000f",
+ 01 => x"f8002623",
+ 02 => x"0080006f",
03 => x"00000013",
04 => x"7b241073",
05 => x"f1402473",
@@ -158,7 +158,7 @@ architecture neorv32_debug_dm_rtl of neorv32_debug_dm is
07 => x"f1402473",
08 => x"f8044403",
09 => x"00247413",
- 10 => x"02041263",
+ 10 => x"02041463",
11 => x"f1402473",
12 => x"f8044403",
13 => x"00147413",
@@ -166,11 +166,11 @@ architecture neorv32_debug_dm_rtl of neorv32_debug_dm is
15 => x"f1402473",
16 => x"f8802223",
17 => x"7b202473",
- 18 => x"7b200073",
- 19 => x"f1402473",
- 20 => x"f8802423",
- 21 => x"7b202473",
- 22 => x"0000100f",
+ 18 => x"0000100f",
+ 19 => x"7b200073",
+ 20 => x"f1402473",
+ 21 => x"f8802423",
+ 22 => x"7b202473",
23 => x"e8000067",
24 => x"00000073",
25 => x"00000073",
@@ -279,12 +279,12 @@ begin
if (dm_reg.command(17) = '1') then -- "transfer" (GPR <-> DM.data0)
if (dm_reg.command(16) = '0') then -- "write" = 0 -> read from GPR
dm_ctrl.ldsw_progbuf <= instr_sw_c;
- dm_ctrl.ldsw_progbuf(31 downto 25) <= dataaddr_c(11 downto 5); -- destination address
+ dm_ctrl.ldsw_progbuf(31 downto 25) <= dataaddr_c(11 downto 5); -- destination address = DM.data0
dm_ctrl.ldsw_progbuf(24 downto 20) <= dm_reg.command(4 downto 0); -- "regno" = source register
- dm_ctrl.ldsw_progbuf(11 downto 07) <= dataaddr_c(4 downto 0); -- destination address
+ dm_ctrl.ldsw_progbuf(11 downto 07) <= dataaddr_c(4 downto 0); -- destination address = DM.data0
else -- "write" = 1 -> write to GPR
dm_ctrl.ldsw_progbuf <= instr_lw_c;
- dm_ctrl.ldsw_progbuf(31 downto 20) <= dataaddr_c(11 downto 0); -- source address
+ dm_ctrl.ldsw_progbuf(31 downto 20) <= dataaddr_c(11 downto 0); -- source address = DM.data0
dm_ctrl.ldsw_progbuf(11 downto 07) <= dm_reg.command(4 downto 0); -- "regno" = destination register
end if;
else
diff --git a/rtl/core/neorv32_dma.vhd b/rtl/core/neorv32_dma.vhd
index aa7e5f95a..e7c9e6248 100644
--- a/rtl/core/neorv32_dma.vhd
+++ b/rtl/core/neorv32_dma.vhd
@@ -43,7 +43,6 @@ architecture neorv32_dma_rtl of neorv32_dma is
-- control and status register bits --
constant ctrl_en_c : natural := 0; -- r/w: DMA enable
constant ctrl_auto_c : natural := 1; -- r/w: enable FIRQ-triggered transfer
- constant ctrl_fence_c : natural := 2; -- r/w: issue FENCE operation when DMA is done
--
constant ctrl_error_rd_c : natural := 8; -- r/-: error during read transfer
constant ctrl_error_wr_c : natural := 9; -- r/-: error during write transfer
@@ -64,7 +63,6 @@ architecture neorv32_dma_rtl of neorv32_dma is
type cfg_t is record
enable : std_ulogic; -- DMA enabled when set
auto : std_ulogic; -- FIRQ-driven auto transfer
- fence : std_ulogic; -- issue FENCE operation when DMA is done
firq_sel : std_ulogic_vector(3 downto 0); -- FIRQ trigger select
firq_type : std_ulogic; -- trigger on FIRQ rising-edge (0) or high-level (1)
src_base : std_ulogic_vector(31 downto 0); -- source base address
@@ -115,7 +113,6 @@ begin
bus_rsp_o <= rsp_terminate_c;
cfg.enable <= '0';
cfg.auto <= '0';
- cfg.fence <= '0';
cfg.firq_sel <= (others => '0');
cfg.firq_type <= '0';
cfg.src_base <= (others => '0');
@@ -142,7 +139,6 @@ begin
if (bus_req_i.addr(3 downto 2) = "00") then -- control and status register
cfg.enable <= bus_req_i.data(ctrl_en_c);
cfg.auto <= bus_req_i.data(ctrl_auto_c);
- cfg.fence <= bus_req_i.data(ctrl_fence_c);
cfg.done <= '0'; -- clear on write access
cfg.firq_type <= bus_req_i.data(ctrl_firq_type_c);
cfg.firq_sel <= bus_req_i.data(ctrl_firq_sel_msb_c downto ctrl_firq_sel_lsb_c);
@@ -166,7 +162,6 @@ begin
when "00" => -- control and status register
bus_rsp_o.data(ctrl_en_c) <= cfg.enable;
bus_rsp_o.data(ctrl_auto_c) <= cfg.auto;
- bus_rsp_o.data(ctrl_fence_c) <= cfg.fence;
bus_rsp_o.data(ctrl_error_rd_c) <= engine.err_rd;
bus_rsp_o.data(ctrl_error_wr_c) <= engine.err_wr;
bus_rsp_o.data(ctrl_busy_c) <= engine.busy;
@@ -305,12 +300,12 @@ begin
engine.busy <= '0' when (engine.state = S_IDLE) else '1';
-- bus output --
- dma_req_o.priv <= priv_mode_m_c; -- DMA accesses are always privileged
- dma_req_o.src <= '0'; -- source = data access
dma_req_o.addr <= engine.src_addr when (engine.state = S_READ) else engine.dst_addr;
+ dma_req_o.src <= '0'; -- source = data access
+ dma_req_o.priv <= priv_mode_m_c; -- DMA accesses are always privileged
dma_req_o.amo <= '0'; -- no atomic memory operation possible
dma_req_o.amoop <= (others => '0'); -- no atomic memory operation possible
- dma_req_o.fence <= cfg.enable and cfg.fence and engine.done; -- issue FENCE operation when transfer is done
+ dma_req_o.fence <= '0'; -- no fences
dma_req_o.sleep <= '1' when (engine.state = S_IDLE) else '0'; -- idle = sleep mode
dma_req_o.debug <= '0'; -- can never ever be in debug mode
diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd
index 9e176df03..347dd4f02 100644
--- a/rtl/core/neorv32_package.vhd
+++ b/rtl/core/neorv32_package.vhd
@@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
- constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110004"; -- hardware version
+ constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110005"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width
diff --git a/rtl/core/neorv32_xbus.vhd b/rtl/core/neorv32_xbus.vhd
index 1a287b08e..0afd83d2b 100644
--- a/rtl/core/neorv32_xbus.vhd
+++ b/rtl/core/neorv32_xbus.vhd
@@ -27,7 +27,6 @@ entity neorv32_xbus is
rstn_i : in std_ulogic; -- global reset line, low-active
bus_req_i : in bus_req_t; -- bus request
bus_rsp_o : out bus_rsp_t; -- bus response
- --
xbus_adr_o : out std_ulogic_vector(31 downto 0); -- address
xbus_dat_i : in std_ulogic_vector(31 downto 0); -- read data
xbus_dat_o : out std_ulogic_vector(31 downto 0); -- write data
diff --git a/rtl/system_integration/neorv32_vivado_ip.tcl b/rtl/system_integration/neorv32_vivado_ip.tcl
index 4658cdc6f..61075e516 100644
--- a/rtl/system_integration/neorv32_vivado_ip.tcl
+++ b/rtl/system_integration/neorv32_vivado_ip.tcl
@@ -174,7 +174,7 @@ proc setup_ip_gui {} {
}
set_property widget {comboBox} [ipgui::get_guiparamspec -name "DUAL_CORE_EN" -component [ipx::current_core] ]
set_property value_validation_type pairs [ipx::get_user_parameters DUAL_CORE_EN -of_objects [ipx::current_core]]
- set_property value_validation_pairs {{Single-core} false {SMP dual-core} true} [ipx::get_user_parameters DUAL_CORE_EN -of_objects [ipx::current_core]]
+ set_property value_validation_pairs {{Single-core} false {Dual-core (SMP)} true} [ipx::get_user_parameters DUAL_CORE_EN -of_objects [ipx::current_core]]
set group [add_group $page {Boot Configuration}]
add_params $group {
@@ -188,7 +188,7 @@ proc setup_ip_gui {} {
set group [add_group $page {On-Chip Debugger (OCD)}]
add_params $group {
{ OCD_EN {Enable OCD} {Implement JTAG-based on-chip debugger} }
- { OCD_AUTHENTICATION {OCD Authentication} {Implement Debug Authentication module} {$OCD_EN} {$OCD_EN ? $OCD_AUTHENTICATION : false}}
+ { OCD_AUTHENTICATION {OCD authentication} {Implement Debug Authentication module} {$OCD_EN} {$OCD_EN ? $OCD_AUTHENTICATION : false}}
{ OCD_JEDEC_ID {JEDEC ID} {JTAG tap identification} {$OCD_EN}}
}
@@ -200,114 +200,114 @@ proc setup_ip_gui {} {
set sub_group [add_group $group {XBUS Cache}]
add_params $sub_group {
- { XBUS_CACHE_EN {Enable XBUS Cache} {} {$XBUS_EN} {$XBUS_EN ? $XBUS_CACHE_EN : false}}
- { XBUS_CACHE_NUM_BLOCKS {Number of Blocks} {} {$XBUS_CACHE_EN} }
- { XBUS_CACHE_BLOCK_SIZE {Block Size} {In bytes (use a power of two)} {$XBUS_CACHE_EN} }
+ { XBUS_CACHE_EN {Enable XBUS cache} {} {$XBUS_EN} {$XBUS_EN ? $XBUS_CACHE_EN : false}}
+ { XBUS_CACHE_NUM_BLOCKS {Number of blocks} {} {$XBUS_CACHE_EN} }
+ { XBUS_CACHE_BLOCK_SIZE {Block size} {In bytes (use a power of two)} {$XBUS_CACHE_EN} }
}
set group [add_group $page {Stream Link Interface (SLINK / AXI4-Stream Source & Sink)}]
add_params $group {
{ IO_SLINK_EN {Enable SLINK} {} }
- { IO_SLINK_RX_FIFO {RX FIFO Depth} {Number of entries (use a power of two)} {$IO_SLINK_EN} }
- { IO_SLINK_TX_FIFO {TX FIFO Depth} {Number of entries (use a power of two)} {$IO_SLINK_EN} }
+ { IO_SLINK_RX_FIFO {RX FIFO depth} {Number of entries (use a power of two)} {$IO_SLINK_EN} }
+ { IO_SLINK_TX_FIFO {TX FIFO depth} {Number of entries (use a power of two)} {$IO_SLINK_EN} }
}
# **************************************************************
# GUI Page: CPU
# **************************************************************
- set page [add_page {CPU Configuration}]
+ set page [add_page {CPU}]
set isa_note "Make sure to set the same ISA configuration for the RISC-V GCC ISA string."
- ipgui::add_static_text -name {ISA note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "CPU Configuration" -component [ipx::current_core] ] -text $isa_note
+ ipgui::add_static_text -name {ISA note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "CPU" -component [ipx::current_core] ] -text $isa_note
set group [add_group $page {RISC-V ISA Extensions}]
add_params $group {
- { RISCV_ISA_C {C} {16-bit compressed instructions} }
- { RISCV_ISA_E {E} {Reduced register file size (16 registers only)} }
- { RISCV_ISA_M {M} {Integer multiplication and division hardware} }
- { RISCV_ISA_U {U} {Less-privileged user-mode} }
- { RISCV_ISA_Zaamo {Zaamo} {Atomic memory operations (read-modify-write)} }
- { RISCV_ISA_Zba {Zba} {Shifted-add bit-manipulation instructions} }
- { RISCV_ISA_Zbb {Zbb} {Basic bit-manipulation instructions} }
- { RISCV_ISA_Zbkb {Zbkb} {Bit manipulation instructions for cryptography} }
- { RISCV_ISA_Zbkc {Zbkc} {Carry-less multiply instructions for cryptography} }
- { RISCV_ISA_Zbkx {Zbkx} {Scalar cryptographic - crossbar permutations} }
- { RISCV_ISA_Zbs {Zbs} {Single-bit bit-manipulation instructions} }
- { RISCV_ISA_Zfinx {Zfinx} {Embedded FPU (using integer registers)} }
- { RISCV_ISA_Zicntr {Zicntr} {Base counters (cycles and instructions)} }
- { RISCV_ISA_Zicond {Zicond} {Conditional-move instructions} }
- { RISCV_ISA_Zihpm {Zihpm} {Hardware performance monitors (HPMs)} }
- { HPM_CNT_WIDTH {HPM Width} {Counter width in bits} {$RISCV_ISA_Zihpm}}
- { HPM_NUM_CNTS {HPM Counters} {Numer of hardware performance monitor counters} {$RISCV_ISA_Zihpm}}
- { RISCV_ISA_Zknd {Zknd} {Scalar cryptographic - NIST AES decryption} }
- { RISCV_ISA_Zkne {Zkne} {Scalar cryptographic - NIST AES encryption} }
- { RISCV_ISA_Zknh {Zknh} {Scalar cryptographic - NIST hash functions} }
- { RISCV_ISA_Zksed {Zksed} {Scalar cryptographic - ShangMi block cyphers} }
- { RISCV_ISA_Zksh {Zksh} {Scalar cryptographic - ShangMi hash functions} }
- { RISCV_ISA_Zmmul {Zmmul} {Integer multiplication-only hardware} }
- { RISCV_ISA_Zxcfu {Zxcfu} {NEORV32-specifc custom-instructions unit (user-defined)} }
+ { RISCV_ISA_C {C - 16-bit compressed instructions} {} }
+ { RISCV_ISA_E {E - Reduced register file size (16 registers only)} {} }
+ { RISCV_ISA_M {M - Integer multiplication and division hardware} {} }
+ { RISCV_ISA_U {U - Less-privileged user-mode} {} }
+ { RISCV_ISA_Zaamo {Zaamo - Atomic memory operations (read-modify-write)} {} }
+ { RISCV_ISA_Zba {Zba - Shifted-add bit-manipulation instructions} {} }
+ { RISCV_ISA_Zbb {Zbb - Basic bit-manipulation instructions} {} }
+ { RISCV_ISA_Zbkb {Zbkb - Bit manipulation instructions for cryptography} {} }
+ { RISCV_ISA_Zbkc {Zbkc - Carry-less multiply instructions for cryptography} {} }
+ { RISCV_ISA_Zbkx {Zbkx - Crossbar permutations for cryptography} {} }
+ { RISCV_ISA_Zbs {Zbs - Single-bit bit-manipulation instructions} {} }
+ { RISCV_ISA_Zfinx {Zfinx - Embedded FPU (using integer register file)} {} }
+ { RISCV_ISA_Zicntr {Zicntr - Base counters (cycles and instructions)} {} }
+ { RISCV_ISA_Zicond {Zicond - Conditional-move instructions} {} }
+ { RISCV_ISA_Zihpm {Zihpm - Hardware performance monitors (HPMs)} {} }
+ { HPM_CNT_WIDTH {HPM Width} {Counter width in bits} {$RISCV_ISA_Zihpm} }
+ { HPM_NUM_CNTS {HPM Counters} {Numer of HPM counters} {$RISCV_ISA_Zihpm} }
+ { RISCV_ISA_Zknd {Zknd - Scalar cryptographic - NIST AES decryption} {} }
+ { RISCV_ISA_Zkne {Zkne - Scalar cryptographic - NIST AES encryption} {} }
+ { RISCV_ISA_Zknh {Zknh - Scalar cryptographic - NIST hash functions} {} }
+ { RISCV_ISA_Zksed {Zksed - Scalar cryptographic - ShangMi block cyphers} {} }
+ { RISCV_ISA_Zksh {Zksh - Scalar cryptographic - ShangMi hash functions} {} }
+ { RISCV_ISA_Zmmul {Zmmul - Integer multiplication-only hardware} {} {!$RISCV_ISA_M} {$RISCV_ISA_M ? false : $RISCV_ISA_Zksh} }
+ { RISCV_ISA_Zxcfu {Zxcfu - Custom-instructions unit (user-defined)} {} }
}
set group [add_group $page {Physical Memory Protection (PMP)}]
add_params $group {
- { PMP_NUM_REGIONS {PMP Regions} {Number of physical memory protection regions} }
- { PMP_MIN_GRANULARITY {PMP Minimal Granularity} {Minimal region granularity in bytes. Has to be a power of two.} {$PMP_NUM_REGIONS > 0} }
- { PMP_TOR_MODE_EN {Enable PMP TOR Mode} {Implement support for top-of-region (TOR) mode} {$PMP_NUM_REGIONS > 0} }
- { PMP_NAP_MODE_EN {Enable PMP NAPOT and NA4 Modes} {Implement support for naturally-aligned power-of-two (NAPOT & NA4) modes} {$PMP_NUM_REGIONS > 0} }
+ { PMP_NUM_REGIONS {PMP regions} {Number of physical memory protection regions} }
+ { PMP_MIN_GRANULARITY {PMP minimal granularity} {Minimal region granularity in bytes. Has to be a power of two.} {$PMP_NUM_REGIONS > 0} }
+ { PMP_TOR_MODE_EN {Enable PMP TOR mode} {Implement support for top-of-region (TOR) mode} {$PMP_NUM_REGIONS > 0} }
+ { PMP_NAP_MODE_EN {Enable PMP NAPOT and NA4 modes} {Implement support for naturally-aligned power-of-two (NAPOT & NA4) modes} {$PMP_NUM_REGIONS > 0} }
}
set_property value_validation_range_minimum 4 [ipx::get_user_parameters PMP_MIN_GRANULARITY -of_objects [ipx::current_core]]
set group [add_group $page {Tuning Options}]
add_params $group {
- { CPU_FAST_MUL_EN {DSP-Based Multiplier} }
- { CPU_FAST_SHIFT_EN {Barrel Shifter} }
- { CPU_RF_HW_RST_EN {Full HW Reset for Register File} {Implement register file with FFs instead of BRAM to allow full hardware reset} }
+ { CPU_FAST_MUL_EN {DSP-based multiplier} }
+ { CPU_FAST_SHIFT_EN {Barrel shifter} }
+ { CPU_RF_HW_RST_EN {Full HW reset for register file} {Implement register file with FFs instead of BRAM to allow full hardware reset} }
}
# **************************************************************
- # GUI Page: Memory System
+ # GUI Page: Memory
# **************************************************************
- set page [add_page {Memory System}]
- set mem_note "The memory sizes need to be exported to the linker via dedicated symbols."
+ set page [add_page {Memory}]
+ set mem_note "The memory sizes need to be exported to the linker via dedicated symbols. Example:"
set imem_note "IMEM size (32kB): -Wl,--defsym,__neorv32_rom_size=32k"
set dmem_note "DMEM size (16kB): -Wl,--defsym,__neorv32_ram_size=16k"
- ipgui::add_static_text -name {MEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory System" -component [ipx::current_core] ] -text $mem_note
- ipgui::add_static_text -name {IMEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory System" -component [ipx::current_core] ] -text $imem_note
- ipgui::add_static_text -name {DMEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory System" -component [ipx::current_core] ] -text $dmem_note
+ ipgui::add_static_text -name {MEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory" -component [ipx::current_core] ] -text $mem_note
+ ipgui::add_static_text -name {IMEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory" -component [ipx::current_core] ] -text $imem_note
+ ipgui::add_static_text -name {DMEM note} -component [ipx::current_core] -parent [ipgui::get_pagespec -name "Memory" -component [ipx::current_core] ] -text $dmem_note
set group [add_group $page {Internal Instruction Memory (IMEM)}]
add_params $group {
- { MEM_INT_IMEM_EN {Enable IMEM} }
- { MEM_INT_IMEM_SIZE {IMEM Size} {In bytes (use a power of two)} {$MEM_INT_IMEM_EN} }
+ { MEM_INT_IMEM_EN {Enable internal IMEM} }
+ { MEM_INT_IMEM_SIZE {IMEM size} {In bytes (use a power of two)} {$MEM_INT_IMEM_EN} }
}
set group [add_group $page {Internal Data Memory (DMEM)}]
add_params $group {
- { MEM_INT_DMEM_EN {Enbale DMEM} }
- { MEM_INT_DMEM_SIZE {DMEM Size} {In bytes (use a power of two)} {$MEM_INT_DMEM_EN} }
+ { MEM_INT_DMEM_EN {Enbale internal DMEM} }
+ { MEM_INT_DMEM_SIZE {DMEM size} {In bytes (use a power of two)} {$MEM_INT_DMEM_EN} }
}
set group [add_group $page {CPU Instruction Cache (ICACHE)}]
add_params $group {
- { ICACHE_EN {Enable ICACHE} }
- { ICACHE_NUM_BLOCKS {Number of Blocks} {} {$ICACHE_EN} }
- { ICACHE_BLOCK_SIZE {Block Size} {In bytes (use a power of two)} {$ICACHE_EN} }
+ { ICACHE_EN {Enable ICACHE} }
+ { ICACHE_NUM_BLOCKS {Number of blocks} {} {$ICACHE_EN} }
+ { ICACHE_BLOCK_SIZE {Block size} {In bytes (use a power of two)} {$ICACHE_EN} }
}
set group [add_group $page {CPU Data Cache (DCACHE)}]
add_params $group {
- { DCACHE_EN {Enable DCACHE} }
- { DCACHE_NUM_BLOCKS {Number of Blocks} {} {$DCACHE_EN} }
- { DCACHE_BLOCK_SIZE {Block Size} {In bytes (use a power of two)} {$DCACHE_EN} }
+ { DCACHE_EN {Enable DCACHE} }
+ { DCACHE_NUM_BLOCKS {Number of blocks} {} {$DCACHE_EN} }
+ { DCACHE_BLOCK_SIZE {Block size} {In bytes (use a power of two)} {$DCACHE_EN} }
}
set group [add_group $page {Execute In-Place Module (XIP)}]
add_params $group {
{ XIP_EN {Enable XIP} }
- { XIP_CACHE_EN {Enable XIP Cache} {} {$XIP_EN} {$XIP_EN ? $XIP_CACHE_EN : false} }
- { XIP_CACHE_NUM_BLOCKS {Cache Blocks} {} {$XIP_CACHE_EN} }
- { XIP_CACHE_BLOCK_SIZE {Cache Block Size} {In bytes (use a power of two)} {$XIP_CACHE_EN} }
+ { XIP_CACHE_EN {Enable XIP cache} {} {$XIP_EN} {$XIP_EN ? $XIP_CACHE_EN : false} }
+ { XIP_CACHE_NUM_BLOCKS {Cache blocks} {} {$XIP_CACHE_EN} }
+ { XIP_CACHE_BLOCK_SIZE {Cache block size} {In bytes (use a power of two)} {$XIP_CACHE_EN} }
}
@@ -319,57 +319,57 @@ proc setup_ip_gui {} {
set group [add_group $page {General-Purpose Input/Output Controller (GPIO)}]
add_params $group {
{ IO_GPIO_EN {Enable GPIO} }
- { IO_GPIO_IN_NUM {Number of Inputs} {Interrupt-capable} {$IO_GPIO_EN} }
- { IO_GPIO_OUT_NUM {Number of Outputs} {} {$IO_GPIO_EN} }
+ { IO_GPIO_IN_NUM {Number of inputs (IRQ capable)} {Interrupt-capable} {$IO_GPIO_EN} }
+ { IO_GPIO_OUT_NUM {Number of outputs} {} {$IO_GPIO_EN} }
}
set group [add_group $page {Core Local Interruptor (CLINT)}]
add_params $group {
- { IO_CLINT_EN {Enable Core Local Interruptor} }
+ { IO_CLINT_EN {Enable core-local interruptor} }
}
set group [add_group $page {Primary UART (UART0)}]
add_params $group {
{ IO_UART0_EN {Enable UART0} }
- { IO_UART0_RX_FIFO {RX FIFO Depth} {Number of entries (use a power of two)} {$IO_UART0_EN} }
- { IO_UART0_TX_FIFO {TX FIFO Depth} {Number of entries (use a power of two)} {$IO_UART0_EN} }
+ { IO_UART0_RX_FIFO {RX FIFO depth} {Number of entries (use a power of two)} {$IO_UART0_EN} }
+ { IO_UART0_TX_FIFO {TX FIFO depth} {Number of entries (use a power of two)} {$IO_UART0_EN} }
}
set group [add_group $page {Secondary UART (UART1)}]
add_params $group {
{ IO_UART1_EN {Enable UART1} }
- { IO_UART1_RX_FIFO {RX FIFO Depth} {Number of entries (use a power of two)} {$IO_UART1_EN} }
- { IO_UART1_TX_FIFO {TX FIFO Depth} {Number of entries (use a power of two)} {$IO_UART1_EN} }
+ { IO_UART1_RX_FIFO {RX FIFO depth} {Number of entries (use a power of two)} {$IO_UART1_EN} }
+ { IO_UART1_TX_FIFO {TX FIFO depth} {Number of entries (use a power of two)} {$IO_UART1_EN} }
}
set group [add_group $page {SPI Host Controller (SPI)}]
add_params $group {
{ IO_SPI_EN {Enable SPI} }
- { IO_SPI_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_SPI_EN} }
+ { IO_SPI_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_SPI_EN} }
}
set group [add_group $page {SPI Device Controller (SDI)}]
add_params $group {
{ IO_SDI_EN {Enable SDI} }
- { IO_SDI_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_SDI_EN} }
+ { IO_SDI_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_SDI_EN} }
}
set group [add_group $page {Two-Wire/I2C Host (TWI)}]
add_params $group {
{ IO_TWI_EN {Enable TWI} }
- { IO_TWI_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_TWI_EN} }
+ { IO_TWI_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_TWI_EN} }
}
set group [add_group $page {Two-Wire/I2C Device (TWD)}]
add_params $group {
{ IO_TWD_EN {Enable TWD} }
- { IO_TWD_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_TWD_EN} }
+ { IO_TWD_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_TWD_EN} }
}
set group [add_group $page {Pulse-Width Modulation Controller (PWM)}]
add_params $group {
{ IO_PWM_EN {Enable PWM} }
- { IO_PWM_NUM_CH {Number of Channels} {} {$IO_PWM_EN} }
+ { IO_PWM_NUM_CH {Number of channels} {} {$IO_PWM_EN} }
}
set group [add_group $page {Watchdog Timer (WDT)}]
@@ -380,21 +380,21 @@ proc setup_ip_gui {} {
set group [add_group $page {True Random-Number Generator (TRNG)}]
add_params $group {
{ IO_TRNG_EN {Enable TRNG} }
- { IO_TRNG_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_TRNG_EN} }
+ { IO_TRNG_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_TRNG_EN} }
}
set group [add_group $page {Custom Functions Subsystem (CFS)}]
add_params $group {
{ IO_CFS_EN {Enable CFS} }
- { IO_CFS_CONFIG {Configuration Word} {} {$IO_CFS_EN} }
- { IO_CFS_IN_SIZE {Input Port Width} {} {$IO_CFS_EN} }
- { IO_CFS_OUT_SIZE {Output Port Width} {} {$IO_CFS_EN} }
+ { IO_CFS_CONFIG {Configuration word} {} {$IO_CFS_EN} }
+ { IO_CFS_IN_SIZE {Input port width} {} {$IO_CFS_EN} }
+ { IO_CFS_OUT_SIZE {Output port width} {} {$IO_CFS_EN} }
}
set group [add_group $page {Smart LED Interface (NEOLED)}]
add_params $group {
{ IO_NEOLED_EN {Enable NEOLED} }
- { IO_NEOLED_TX_FIFO {FIFO Depth} {Number of entries (use a power of two)} {$IO_NEOLED_EN} }
+ { IO_NEOLED_TX_FIFO {FIFO depth} {Number of entries (use a power of two)} {$IO_NEOLED_EN} }
}
set group [add_group $page {General Purpose Timer (GPTMR)}]
@@ -412,7 +412,7 @@ proc setup_ip_gui {} {
{ IO_DMA_EN {Enable DMA} }
}
- set group [add_group $page {Cyclic Redundancy Check (CRC)}]
+ set group [add_group $page {Cyclic Redundancy Check Unit (CRC)}]
add_params $group {
{ IO_CRC_EN {Enable CRC} }
}
diff --git a/rtl/system_integration/neorv32_vivado_ip.vhd b/rtl/system_integration/neorv32_vivado_ip.vhd
index 9d4352977..da679e7f4 100644
--- a/rtl/system_integration/neorv32_vivado_ip.vhd
+++ b/rtl/system_integration/neorv32_vivado_ip.vhd
@@ -275,7 +275,6 @@ architecture neorv32_vivado_ip_rtl of neorv32_vivado_ip is
xbus_we_i : in std_ulogic;
xbus_sel_i : in std_ulogic_vector(3 downto 0);
xbus_stb_i : in std_ulogic;
- xbus_cyc_i : in std_ulogic;
xbus_ack_o : out std_ulogic;
xbus_err_o : out std_ulogic;
xbus_dat_o : out std_ulogic_vector(31 downto 0);
@@ -336,7 +335,6 @@ architecture neorv32_vivado_ip_rtl of neorv32_vivado_ip is
signal xbus_we : std_ulogic; -- read/write
signal xbus_sel : std_ulogic_vector(3 downto 0); -- byte enable
signal xbus_stb : std_ulogic; -- strobe
- signal xbus_cyc : std_ulogic; -- valid cycle
signal xbus_di : std_ulogic_vector(31 downto 0); -- read data
signal xbus_ack : std_ulogic; -- transfer acknowledge
signal xbus_err : std_ulogic; -- transfer error
@@ -474,7 +472,7 @@ begin
xbus_we_o => xbus_we,
xbus_sel_o => xbus_sel,
xbus_stb_o => xbus_stb,
- xbus_cyc_o => xbus_cyc,
+ xbus_cyc_o => open,
xbus_dat_i => xbus_di,
xbus_ack_i => xbus_ack,
xbus_err_i => xbus_err,
@@ -614,7 +612,7 @@ begin
end generate;
- -- Wishbone-to-AXI4-Lite Bridge -----------------------------------------------------------
+ -- XBUS-to-AXI4-Lite Bridge ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
axi4_bridge:
if XBUS_EN generate
@@ -630,7 +628,6 @@ begin
xbus_we_i => xbus_we,
xbus_sel_i => xbus_sel,
xbus_stb_i => xbus_stb,
- xbus_cyc_i => xbus_cyc,
xbus_ack_o => xbus_ack,
xbus_err_o => xbus_err,
xbus_dat_o => xbus_di,
diff --git a/rtl/system_integration/xbus2ahblite_bridge.vhd b/rtl/system_integration/xbus2ahblite_bridge.vhd
index b297fc583..f9417c307 100644
--- a/rtl/system_integration/xbus2ahblite_bridge.vhd
+++ b/rtl/system_integration/xbus2ahblite_bridge.vhd
@@ -1,5 +1,5 @@
-- ================================================================================ --
--- NEORV32 SoC - XBUS to AHB3-Lite Bridge (single non-overlapping transfers only) --
+-- NEORV32 SoC - XBUS to AHB3-Lite Bridge --
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
@@ -10,14 +10,13 @@
library ieee;
use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
entity xbus2ahblite_bridge is
port (
- -- global control --
+ -- Global control --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active, use as async
- -- xbus device interface --
+ -- XBUS device interface --
xbus_adr_i : in std_ulogic_vector(31 downto 0); -- address
xbus_dat_i : in std_ulogic_vector(31 downto 0); -- write data
xbus_tag_i : in std_ulogic_vector(2 downto 0); -- access tag
@@ -28,7 +27,7 @@ entity xbus2ahblite_bridge is
xbus_ack_o : out std_ulogic; -- transfer acknowledge
xbus_err_o : out std_ulogic; -- transfer error
xbus_dat_o : out std_ulogic_vector(31 downto 0); -- read data
- -- ahb-lite host interface --
+ -- AHB3-Lite host interface --
ahb_haddr_o : out std_ulogic_vector(31 downto 0); -- address
ahb_hwdata_o : out std_ulogic_vector(31 downto 0); -- write data
ahb_hwrite_o : out std_ulogic; -- read/write
@@ -100,9 +99,13 @@ begin
xbus_dat_o <= ahb_hrdata_i;
-- data quantity --
- with xbus_sel_i select ahb_hsize_o <=
- "000" when "1000" | "0100" | "0010" | "0001", -- byte
- "001" when "1100" | "0011", -- half-word (aligned only)
- "010" when others; -- word
+ data_size: process(xbus_sel_i)
+ begin
+ case xbus_sel_i is
+ when "1000" | "0100" | "0010" | "0001" => ahb_hsize_o <= "000"; -- byte
+ when "1100" | "0011" => ahb_hsize_o <= "001" -- half-word
+ when others => ahb_hsize_o <= "010"; -- word
+ end case;
+ end process data_size;
end xbus2ahblite_bridge_rtl;
diff --git a/rtl/system_integration/xbus2axi4lite_bridge.vhd b/rtl/system_integration/xbus2axi4lite_bridge.vhd
index 71f22be76..bae873899 100644
--- a/rtl/system_integration/xbus2axi4lite_bridge.vhd
+++ b/rtl/system_integration/xbus2axi4lite_bridge.vhd
@@ -23,7 +23,6 @@ entity xbus2axi4lite_bridge is
xbus_we_i : in std_ulogic;
xbus_sel_i : in std_ulogic_vector(3 downto 0);
xbus_stb_i : in std_ulogic;
- xbus_cyc_i : in std_ulogic;
xbus_ack_o : out std_ulogic;
xbus_err_o : out std_ulogic;
xbus_dat_o : out std_ulogic_vector(31 downto 0);
@@ -56,7 +55,7 @@ end entity;
architecture xbus2axi4lite_bridge_rtl of xbus2axi4lite_bridge is
- signal arvalid, awvalid, wvalid, xbus_rd_ack, xbus_rd_err, xbus_wr_ack, xbus_wr_err : std_ulogic;
+ signal arvalid, awvalid, wvalid, rready, bready, xbus_rd_ack, xbus_rd_err, xbus_wr_ack, xbus_wr_err : std_ulogic;
begin
@@ -67,11 +66,14 @@ begin
arvalid <= '0';
awvalid <= '0';
wvalid <= '0';
+ rready <= '0';
+ bready <= '0';
elsif rising_edge(clk) then
- -- /------------- Set ------------\ /-------- Hold -------\ /---------- Clear ----------\
- arvalid <= (xbus_stb_i and (not xbus_we_i)) or (arvalid and xbus_cyc_i and std_ulogic(not m_axi_arready));
- awvalid <= (xbus_stb_i and ( xbus_we_i)) or (awvalid and xbus_cyc_i and std_ulogic(not m_axi_awready));
- wvalid <= (xbus_stb_i and ( xbus_we_i)) or (wvalid and xbus_cyc_i and std_ulogic(not m_axi_wready));
+ arvalid <= (xbus_stb_i and (not xbus_we_i)) or (arvalid and std_ulogic(not m_axi_arready));
+ awvalid <= (xbus_stb_i and ( xbus_we_i)) or (awvalid and std_ulogic(not m_axi_awready));
+ wvalid <= (xbus_stb_i and ( xbus_we_i)) or (wvalid and std_ulogic(not m_axi_wready));
+ rready <= (xbus_stb_i and (not xbus_we_i)) or (rready and std_ulogic(not m_axi_rvalid));
+ bready <= (xbus_stb_i and ( xbus_we_i)) or (bready and std_ulogic(not m_axi_bvalid));
end if;
end process axi_handshake;
@@ -81,10 +83,10 @@ begin
m_axi_arvalid <= std_logic(arvalid);
-- AXI read data channel --
- m_axi_rready <= '1';
+ m_axi_rready <= std_logic(rready);
+ xbus_rd_ack <= '1' when (rready = '1') and (m_axi_rvalid = '1') and (m_axi_rresp = "00") else '0';
+ xbus_rd_err <= '1' when (rready = '1') and (m_axi_rvalid = '1') and (m_axi_rresp /= "00") else '0';
xbus_dat_o <= std_ulogic_vector(m_axi_rdata);
- xbus_rd_ack <= '1' when (m_axi_rvalid = '1') and (m_axi_rresp = "00") else '0';
- xbus_rd_err <= '1' when (m_axi_rvalid = '1') and (m_axi_rresp /= "00") else '0';
-- AXI write address channel --
m_axi_awaddr <= std_logic_vector(xbus_adr_i);
@@ -97,12 +99,12 @@ begin
m_axi_wvalid <= std_logic(wvalid);
-- AXI write response channel --
- m_axi_bready <= '1';
- xbus_wr_ack <= '1' when (m_axi_bvalid = '1') and (m_axi_bresp = "00") else '0';
- xbus_wr_err <= '1' when (m_axi_bvalid = '1') and (m_axi_bresp /= "00") else '0';
+ m_axi_bready <= std_logic(bready);
+ xbus_wr_ack <= '1' when (bready = '1') and (m_axi_bvalid = '1') and (m_axi_bresp = "00") else '0';
+ xbus_wr_err <= '1' when (bready = '1') and (m_axi_bvalid = '1') and (m_axi_bresp /= "00") else '0';
-- XBUS response --
- xbus_ack_o <= xbus_rd_ack or xbus_wr_ack;
- xbus_err_o <= xbus_rd_err or xbus_wr_err;
+ xbus_ack_o <= xbus_rd_ack or xbus_wr_ack;
+ xbus_err_o <= xbus_rd_err or xbus_wr_err;
end architecture xbus2axi4lite_bridge_rtl;
diff --git a/sim/neorv32_tb.vhd b/sim/neorv32_tb.vhd
index 2873873dc..4026f12d4 100644
--- a/sim/neorv32_tb.vhd
+++ b/sim/neorv32_tb.vhd
@@ -41,7 +41,7 @@ entity neorv32_tb is
RISCV_ISA_Zknd : boolean := true; -- implement cryptography NIST AES decryption extension
RISCV_ISA_Zkne : boolean := true; -- implement cryptography NIST AES encryption extension
RISCV_ISA_Zknh : boolean := true; -- implement cryptography NIST hash extension
- RISCV_ISA_Zksed : boolean := true; -- implement ShangMi block cypher extension
+ RISCV_ISA_Zksed : boolean := true; -- implement ShangMi block cipher extension
RISCV_ISA_Zksh : boolean := true; -- implement ShangMi hash extension
RISCV_ISA_Zmmul : boolean := true; -- implement multiply-only M sub-extension
RISCV_ISA_Zxcfu : boolean := true; -- implement custom (instr.) functions unit
@@ -63,11 +63,13 @@ entity neorv32_tb is
EXT_MEM_A_EN : boolean := false; -- enable memory
EXT_MEM_A_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address, has to be word-aligned
EXT_MEM_A_SIZE : natural := 64; -- memory size in bytes, min 4
+ EXT_MEM_A_LATE : natural range 1 to 4096 := 20; -- access latency cycles
EXT_MEM_A_FILE : string := ""; -- memory initialization file (plain HEX), no initialization if empty
-- external memory B --
EXT_MEM_B_EN : boolean := false; -- enable memory
EXT_MEM_B_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address, has to be word-aligned
EXT_MEM_B_SIZE : natural := 64; -- memory size in bytes, min 4
+ EXT_MEM_B_LATE : natural range 1 to 4096 := 40; -- access latency cycles
EXT_MEM_B_FILE : string := "" -- memory initialization file (plain HEX), no initialization if empty
);
end neorv32_tb;
@@ -178,16 +180,11 @@ begin
DCACHE_BLOCK_SIZE => DCACHE_BLOCK_SIZE,
-- External bus interface --
XBUS_EN => true,
- XBUS_TIMEOUT => 256,
+ XBUS_TIMEOUT => 0,
XBUS_REGSTAGE_EN => true,
XBUS_CACHE_EN => true,
XBUS_CACHE_NUM_BLOCKS => 4,
- XBUS_CACHE_BLOCK_SIZE => 32,
- -- Execute in-place module (XIP) --
- XIP_EN => true,
- XIP_CACHE_EN => true,
- XIP_CACHE_NUM_BLOCKS => 4,
- XIP_CACHE_BLOCK_SIZE => 256,
+ XBUS_CACHE_BLOCK_SIZE => 64,
-- Processor peripherals --
IO_GPIO_NUM => 32,
IO_CLINT_EN => true,
@@ -257,11 +254,6 @@ begin
slink_tx_val_o => slink_tx.valid,
slink_tx_lst_o => slink_tx.last,
slink_tx_rdy_i => slink_tx.ready,
- -- XIP --
- xip_csn_o => open,
- xip_clk_o => open,
- xip_dat_i => '0',
- xip_dat_o => open,
-- GPIO --
gpio_o => gpio,
gpio_i => gpio,
@@ -415,6 +407,8 @@ begin
DEV_3_EN => true, DEV_3_SIZE => 4, DEV_3_BASE => x"FF000000"
)
port map (
+ clk_i => clk_gen,
+ rstn_i => rst_gen,
-- host port --
host_req_i => xbus_core_req,
host_rsp_o => xbus_core_rsp,
@@ -433,7 +427,7 @@ begin
xbus_external_memory_a: entity work.xbus_memory
generic map (
MEM_SIZE => EXT_MEM_A_SIZE,
- MEM_LATE => 1,
+ MEM_LATE => EXT_MEM_A_LATE,
MEM_FILE => EXT_MEM_A_FILE
)
port map (
@@ -457,7 +451,7 @@ begin
xbus_external_memory_b: entity work.xbus_memory
generic map (
MEM_SIZE => EXT_MEM_B_SIZE,
- MEM_LATE => 1,
+ MEM_LATE => EXT_MEM_B_LATE,
MEM_FILE => EXT_MEM_B_FILE
)
port map (
@@ -478,7 +472,7 @@ begin
-- -------------------------------------------------------------------------------------------
xbus_mmio: entity work.xbus_memory
generic map (
- MEM_SIZE => 64,
+ MEM_SIZE => 8,
MEM_LATE => 32,
MEM_FILE => "" -- no initialization
)
diff --git a/sim/xbus_gateway.vhd b/sim/xbus_gateway.vhd
index 451564b90..8521913f9 100644
--- a/sim/xbus_gateway.vhd
+++ b/sim/xbus_gateway.vhd
@@ -3,7 +3,7 @@
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
--- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. --
+-- 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 --
-- ================================================================================ --
@@ -24,6 +24,8 @@ entity xbus_gateway is
DEV_3_EN : boolean := false; DEV_3_SIZE : natural := 0; DEV_3_BASE : std_ulogic_vector(31 downto 0) := (others => '0')
);
port (
+ clk_i : in std_ulogic;
+ rstn_i : in std_ulogic;
-- host port --
host_req_i : in xbus_req_t;
host_rsp_o : out xbus_rsp_t;
@@ -54,8 +56,9 @@ architecture xbus_gateway_rtl of xbus_gateway is
signal dev_req : dev_req_t;
signal dev_rsp : dev_rsp_t;
- -- access enable --
- signal acc_en : std_ulogic_vector(num_devs_c-1 downto 0);
+ -- device access --
+ signal acc_en : std_ulogic_vector(num_devs_c-1 downto 0);
+ signal acc_err : std_ulogic;
begin
@@ -73,6 +76,16 @@ begin
(unsigned(host_req_i.addr) < (unsigned(dev_base_list_c(i)) + dev_size_list_c(i))) else '0';
end generate;
+ -- invalid access address --
+ err_gen: process(rstn_i, clk_i)
+ begin
+ if (rstn_i = '0') then
+ acc_err <= '0';
+ elsif rising_edge(clk_i) then
+ acc_err <= host_req_i.stb and host_req_i.cyc and (not or_reduce_f(acc_en));
+ end if;
+ end process err_gen;
+
-- request --
bus_request_gen:
for i in 0 to num_devs_c-1 generate
@@ -88,12 +101,12 @@ begin
end generate;
-- response --
- bus_response: process(dev_rsp, acc_en)
+ bus_response: process(acc_err, dev_rsp, acc_en)
variable tmp_v : xbus_rsp_t;
begin
tmp_v.data := (others => '0');
tmp_v.ack := '0';
- tmp_v.err := '0';
+ tmp_v.err := acc_err;
for i in 0 to num_devs_c-1 loop -- OR all enabled response buses
if (acc_en(i) = '1') and dev_en_list_c(i) then
tmp_v.data := tmp_v.data or dev_rsp(i).data;
diff --git a/sim/xbus_memory.vhd b/sim/xbus_memory.vhd
index cf22ad35e..99dec09bd 100644
--- a/sim/xbus_memory.vhd
+++ b/sim/xbus_memory.vhd
@@ -56,15 +56,25 @@ architecture xbus_memory_rtl of xbus_memory is
readline(hex_file, hex_line_v); -- read one line from file
for i in 7 downto 0 loop -- get full 32-bit word in 'word_v'; no VHDL2008 required
read(hex_line_v, hex_char_v);
- if (hex_char_v >= '0') and (hex_char_v <= '9') then
- tmp_v := 0 + (character'pos(hex_char_v) - character'pos('0'));
- elsif (hex_char_v >= 'a') and (hex_char_v <= 'f') then
- tmp_v := 10 + (character'pos(hex_char_v) - character'pos('a'));
- elsif (hex_char_v >= 'A') and (hex_char_v <= 'F') then
- tmp_v := 10 + (character'pos(hex_char_v) - character'pos('A'));
- else -- invalid character
- tmp_v := 0;
- end if;
+ case hex_char_v is
+ when '0' => tmp_v := 0;
+ when '1' => tmp_v := 1;
+ when '2' => tmp_v := 2;
+ when '3' => tmp_v := 3;
+ when '4' => tmp_v := 4;
+ when '5' => tmp_v := 5;
+ when '6' => tmp_v := 6;
+ when '7' => tmp_v := 7;
+ when '8' => tmp_v := 8;
+ when '9' => tmp_v := 9;
+ when 'a' | 'A' => tmp_v := 10;
+ when 'b' | 'B' => tmp_v := 11;
+ when 'c' | 'C' => tmp_v := 12;
+ when 'd' | 'D' => tmp_v := 13;
+ when 'e' | 'E' => tmp_v := 14;
+ when 'f' | 'F' => tmp_v := 15;
+ when others => tmp_v := 0;
+ end case;
word_v(i*4+3 downto i*4+0) := to_bitvector(std_ulogic_vector((to_unsigned(tmp_v, 4))));
end loop;
mem_v(index_v) := word_v(byte_sel*8+7 downto byte_sel*8+0); -- extract desired byte
diff --git a/sw/bootloader/bootloader.c b/sw/bootloader/bootloader.c
index 376057999..0ca472a6e 100644
--- a/sw/bootloader/bootloader.c
+++ b/sw/bootloader/bootloader.c
@@ -576,7 +576,7 @@ void get_exe(int src) {
if (src == EXE_STREAM_FLASH) {
addr = (uint32_t)SPI_BOOT_BASE_ADDR;
}
-
+
// get image from UART?
if (src == EXE_STREAM_UART) {
@@ -634,7 +634,11 @@ void get_exe(int src) {
exe_available = size; // store exe size
}
- getting_exe = 0; // to inform trap handler we are done getting an executable
+ // we might have caches so the executable might not yet have fully arrived in main memory yet
+ asm volatile ("fence"); // flush data caches to main memory
+ asm volatile ("fence.i"); // re-sync instruction fetch to updated main memory
+
+ getting_exe = 0; // inform trap handler that we are done getting an executable
}
@@ -1046,9 +1050,9 @@ uint32_t twi_read_addr(uint32_t addr) {
#error "Unsupported TWI_ADDR_BYTES configuration!"
#endif
-
+
/***********************
- * Set address to read
+ * Set address to read
***********************/
neorv32_twi_generate_start();
@@ -1071,7 +1075,7 @@ uint32_t twi_read_addr(uint32_t addr) {
#endif
/***********************
- * Read data
+ * Read data
***********************/
neorv32_twi_generate_start();
@@ -1097,7 +1101,7 @@ uint32_t twi_read_addr(uint32_t addr) {
transfer = 0xFF;
neorv32_twi_trans(&transfer, 0); // NACK by master
data.uint8[3] = transfer;
-
+
neorv32_twi_generate_stop();
return data.uint32;
diff --git a/sw/common/crt0.S b/sw/common/crt0.S
index a091d3882..4875d1a31 100644
--- a/sw/common/crt0.S
+++ b/sw/common/crt0.S
@@ -158,8 +158,8 @@ __crt0_constructors_end:
// ************************************************************************************************
la x12, main // primary core's (core0) entry point (#1169)
__crt0_main_entry:
- fence // reload data cache
- fence.i // reload instruction cache
+ fence // synchronize loads/stores
+ fence.i // synchronize instruction fetch
csrw mstatus, x5 // re-initialize
addi x10, zero, 0 // x10 = a0 = argc = 0
diff --git a/sw/example/demo_dma/main.c b/sw/example/demo_dma/main.c
index 2e14bc7d2..a8cde7d68 100644
--- a/sw/example/demo_dma/main.c
+++ b/sw/example/demo_dma/main.c
@@ -1,7 +1,7 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
-// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
+// 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 //
// ================================================================================ //
@@ -71,10 +71,6 @@ int main() {
// enable DMA
neorv32_dma_enable();
- // issue a FENCE operation when the DMA transfer completes (without errors); this
- // will re-sync / flush and reload) all **DOWNSTREAM** caches
- neorv32_dma_fence_enable();
-
// initialize and data arrays
dma_src[0] = 0x66778899UL;
dma_src[1] = 0x22334455UL;
diff --git a/sw/example/eclipse/.cproject b/sw/example/eclipse/.cproject
index c7c62ddbe..b556b4e0c 100644
--- a/sw/example/eclipse/.cproject
+++ b/sw/example/eclipse/.cproject
@@ -224,6 +224,21 @@
true
true
+
+ ${cross_make}
+ asm
+ true
+ true
+ true
+
+
+ ${cross_make}
+
+ elf_info
+ true
+ true
+ true
+
\ No newline at end of file
diff --git a/sw/example/processor_check/main.c b/sw/example/processor_check/main.c
index 5ba451869..ee47ba02f 100644
--- a/sw/example/processor_check/main.c
+++ b/sw/example/processor_check/main.c
@@ -1448,7 +1448,6 @@ int main() {
// enable DMA, auto-fencing and according FIRQ channel
neorv32_dma_enable();
- neorv32_dma_fence_enable();
neorv32_cpu_csr_write(CSR_MIE, 1 << DMA_FIRQ_ENABLE);
// setup source data
diff --git a/sw/lib/include/neorv32_dma.h b/sw/lib/include/neorv32_dma.h
index 170a7b5f2..6b1451ffa 100644
--- a/sw/lib/include/neorv32_dma.h
+++ b/sw/lib/include/neorv32_dma.h
@@ -1,7 +1,7 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
-// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
+// 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 //
// ================================================================================ //
@@ -9,10 +9,6 @@
/**
* @file neorv32_dma.h
* @brief Direct Memory Access Controller (DMA) HW driver header file.
- *
- * @note These functions should only be used if the DMA controller was synthesized (IO_DMA_EN = true).
- *
- * @see https://stnolting.github.io/neorv32/sw/files.html
*/
#ifndef neorv32_dma_h
@@ -40,7 +36,6 @@ typedef volatile struct __attribute__((packed,aligned(4))) {
enum NEORV32_DMA_CTRL_enum {
DMA_CTRL_EN = 0, /**< DMA control register(0) (r/w): DMA enable */
DMA_CTRL_AUTO = 1, /**< DMA control register(1) (r/w): Automatic trigger mode enable */
- DMA_CTRL_FENCE = 2, /**< DMA control register(2) (r/w): Issue FENCE downstream operation when DMA transfer is completed */
DMA_CTRL_ERROR_RD = 8, /**< DMA control register(8) (r/-): Error during read access; SRC_BASE shows the faulting address */
DMA_CTRL_ERROR_WR = 9, /**< DMA control register(9) (r/-): Error during write access; DST_BASE shows the faulting address */
@@ -103,8 +98,6 @@ enum NEORV32_DMA_STATUS_enum {
int neorv32_dma_available(void);
void neorv32_dma_enable(void);
void neorv32_dma_disable(void);
-void neorv32_dma_fence_enable(void);
-void neorv32_dma_fence_disable(void);
void neorv32_dma_transfer(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config);
void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, int firq_sel, int firq_type);
int neorv32_dma_status(void);
diff --git a/sw/lib/source/neorv32_dma.c b/sw/lib/source/neorv32_dma.c
index a56370fe0..1157a6181 100644
--- a/sw/lib/source/neorv32_dma.c
+++ b/sw/lib/source/neorv32_dma.c
@@ -1,7 +1,7 @@
// ================================================================================ //
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
// Copyright (c) NEORV32 contributors. //
-// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
+// 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 //
// ================================================================================ //
@@ -9,10 +9,6 @@
/**
* @file neorv32_wdt.c
* @brief Direct Memory Access Controller (DMA) HW driver source file.
- *
- * @note These functions should only be used if the DMA controller was synthesized (IO_DMA_EN = true).
- *
- * @see https://stnolting.github.io/neorv32/sw/files.html
*/
#include
@@ -52,25 +48,6 @@ void neorv32_dma_disable(void) {
}
-/**********************************************************************//**
- * Enable memory barrier (fence): issue a FENCE operation when DMA transfer
- * completes without errors.
- **************************************************************************/
-void neorv32_dma_fence_enable(void) {
-
- NEORV32_DMA->CTRL |= (uint32_t)(1 << DMA_CTRL_FENCE);
-}
-
-
-/**********************************************************************//**
- * Disable memory barrier (fence).
- **************************************************************************/
-void neorv32_dma_fence_disable(void) {
-
- NEORV32_DMA->CTRL &= ~((uint32_t)(1 << DMA_CTRL_FENCE));
-}
-
-
/**********************************************************************//**
* Trigger manual DMA transfer.
*
diff --git a/sw/ocd-firmware/park_loop.S b/sw/ocd-firmware/park_loop.S
index 5b2b41e61..ab4edce04 100644
--- a/sw/ocd-firmware/park_loop.S
+++ b/sw/ocd-firmware/park_loop.S
@@ -38,9 +38,9 @@ _ocd_start:
// BASE + 0: exception entry - exeption during program buffer execution
entry_exception:
+ fence // debug-mode is bypassing the caches so make sure they're sync with main memory
sw zero, (DM_SREG_BASE+ACK_EXC)(zero) // send exception-acknowledge (no need for a hart ID)
- csrr x8, dscratch0 // restore x8 from dscratch0 (might be changed during PBUF execution)
- ebreak // re-enter debug mode (at "entry_park" entry point)
+ j entry_park // enter park loop
nop // dummy to align the address of "entry_park"
// BASE + 16: normal entry - halt CPU: ebreak in debug-mode, halt request or return from single-stepped instruction
@@ -54,7 +54,7 @@ park_loop:
csrr x8, mhartid // get hart ID
lbu x8, DM_SREG_BASE(x8) // read hart-specific byte from request register
andi x8, x8, 1 << REQ_EXE // execute-request bit set?
- bnez x8, execute
+ bnez x8, exit_execute
csrr x8, mhartid // get hart ID
lbu x8, DM_SREG_BASE(x8) // read hart-specific byte from request register
@@ -62,22 +62,22 @@ park_loop:
beqz x8, park_loop
// resume normal operation
-resume:
+exit_resume:
csrr x8, mhartid // get hart ID
sw x8, (DM_SREG_BASE+ACK_RES)(zero) // send resume-acknowledge
csrr x8, dscratch0 // restore x8 from dscratch0
+ fence.i // reload caches in case we have modified (main) memory
dret // exit debug mode
// execute program buffer (implicit ebreak at the end of the buffer will bring us back to "entry_park")
-execute:
+exit_execute:
csrr x8, mhartid // get hart ID
sw x8, (DM_SREG_BASE+ACK_EXE)(zero) // send execute-acknowledge
csrr x8, dscratch0 // restore x8 from dscratch0
- fence.i // synchronize instruction fetch with memory-mapped PBUF
jalr zero, zero, %lo(DM_PBUF_BASE) // jump to beginning of program buffer (PBUF)
-// fill remaining ROM space with instructions that cause a debug-mode-internal exception
-unused: // should never be reached
+// fill remaining ROM space with instructions that cause a debug-mode-internal exception; this should never be reached
+terminate:
ecall
ecall
ecall
diff --git a/sw/svd/neorv32.svd b/sw/svd/neorv32.svd
index d9117d4c0..adb65c5f6 100644
--- a/sw/svd/neorv32.svd
+++ b/sw/svd/neorv32.svd
@@ -412,11 +412,6 @@
[1:1]
Enable automatic transfer trigger (FIRQ-triggered)
-
- DMA_CTRL_FENCE
- [2:2]
- Issue a downstream FENCE operation when DMA transfer completes (without errors)
-
DMA_CTRL_ERROR_RD
[8:8]