Skip to content

Commit 7063877

Browse files
authored
Merge pull request #345 from stnolting/rework_system_reset
[rtl] rework reset system
2 parents 47d7c99 + c5b9667 commit 7063877

File tree

9 files changed

+272
-177
lines changed

9 files changed

+272
-177
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12
3232

3333
| Date (*dd.mm.yyyy*) | Version | Comment |
3434
|:----------:|:-------:|:--------|
35+
| 11.06.2022 | 1.7.2.7 | reworked processor **reset system**; :warning: changed behavior of **watchdog's** "lock" bit; add watchdog "access password"; [#345](https://github.com/stnolting/neorv32/pull/345) |
3536
| 10.06.2022 | 1.7.2.6 | **Wishbone** interface now _gates_ all outgoing signals (= signals remain stable if there is no active Wishbone access); [#344](https://github.com/stnolting/neorv32/pull/344) |
3637
| 09.06.2022 | 1.7.2.5 | reworked **TWI** module fixing several interface timing issues; :warning: removed "START condition done interrupt" and "STOP condition done interrupt"; [#340](https://github.com/stnolting/neorv32/pull/340) |
3738
| 06.06.2022 | 1.7.2.4 | split executable images into package and body; [#338](https://github.com/stnolting/neorv32/pull/338) |

docs/datasheet/soc.adoc

+100-45
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bits/channels are hardwired to zero.
5959
[options="header",grid="rows"]
6060
|=======================
6161
| Signal | Width | Dir. | Function
62-
4+^| **Global Control**
62+
4+^| **Global Control (<<_processor_clocking>> and <<_processor_reset>>)**
6363
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
6464
| `rstn_i` | 1 | in | global reset, asynchronous, **low-active**
6565
4+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
@@ -1072,6 +1072,94 @@ See section <<_execute_in_place_module_xip>> for more information.
10721072

10731073

10741074

1075+
<<<
1076+
// ####################################################################################################################
1077+
:sectnums:
1078+
=== Processor Clocking
1079+
1080+
The processor is implemented as fully-synchronous logic design using a _single clock domain_ that is driven by the top's
1081+
`clk_i` signal. This clock signal is used by all internal registers and memories, which trigger on the rising edge of
1082+
this clock signal. External "clocks" like the OCD's JTAG clock or the TWI's serial clock are synchronized into the
1083+
processor's clock domain before being further processed.
1084+
1085+
[NOTE]
1086+
The registers of the <<_processor_reset>> system trigger on a falling clock edge.
1087+
1088+
Many processor modules like the UARTs or the timers require a programmable time base for operations. In order to simplify
1089+
the hardware, the processor implements a global "clock generator" that provides _clock enables_ for certain frequencies.
1090+
These clock enable signals are synchronous to the system's main clock and will be high for only a single cycle of this main
1091+
clock. Hence, processor modules can use these signals for sub-main-clock operations while still having a single clock domain
1092+
only.
1093+
1094+
In total, 8 sub-main-clock signals are available. All processor modules, which feature a time-based configuration, provide a
1095+
programmable three-bit prescaler select in their according control register to select one of the 8 available clocks. The
1096+
mapping of the prescaler select bits to the according clock source is shown in the table below. Here, _f_ represents the
1097+
processor main clock from the top entity's `clk_i` signal.
1098+
1099+
[cols="<3,^1,^1,^1,^1,^1,^1,^1,^1"]
1100+
[grid="rows"]
1101+
|=======================
1102+
| Prescaler bits: | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
1103+
| Resulting clock: | _f/2_ | _f/4_ | _f/8_ | _f/64_ | _f/128_ | _f/1024_| _f/2048_| _f/4096_
1104+
|=======================
1105+
1106+
The software framework provides pre-defined aliases for the prescaler select bits:
1107+
1108+
.Prescaler Aliases from `neorv32.h`
1109+
[source]
1110+
--------------------------
1111+
enum NEORV32_CLOCK_PRSC_enum {
1112+
CLK_PRSC_2 = 0, /**< CPU_CLK (from clk_i top signal) / 2 */
1113+
CLK_PRSC_4 = 1, /**< CPU_CLK (from clk_i top signal) / 4 */
1114+
CLK_PRSC_8 = 2, /**< CPU_CLK (from clk_i top signal) / 8 */
1115+
CLK_PRSC_64 = 3, /**< CPU_CLK (from clk_i top signal) / 64 */
1116+
CLK_PRSC_128 = 4, /**< CPU_CLK (from clk_i top signal) / 128 */
1117+
CLK_PRSC_1024 = 5, /**< CPU_CLK (from clk_i top signal) / 1024 */
1118+
CLK_PRSC_2048 = 6, /**< CPU_CLK (from clk_i top signal) / 2048 */
1119+
CLK_PRSC_4096 = 7 /**< CPU_CLK (from clk_i top signal) / 4096 */
1120+
};
1121+
--------------------------
1122+
1123+
[TIP]
1124+
If no peripheral modules requires a clock signal from the internal generator (all available modules disabled by clearing the
1125+
_enable_ bit in the according module's control register), it is automatically deactivated to reduce dynamic power consumption.
1126+
1127+
1128+
1129+
<<<
1130+
// ####################################################################################################################
1131+
:sectnums:
1132+
=== Processor Reset
1133+
1134+
The processor provides two reset systems: an _external_ one and an _internal_ one. The external reset is triggered by
1135+
the asynchronous, low-active `rstn_i` top entity signal. The internal reset is a synchronous, low-active reset that
1136+
can be triggered by the external reset, the <<_on_chip_debugger_ocd>> and the <<_watchdog_timer_wdt>>.
1137+
1138+
If the external hardware reset (`rstn_i`) is active it will be _asynchronously_ applied to all processor modules. An
1139+
internal shift register ensures that the system wide reset will be active for at least 4 clock cycles. After that,
1140+
the system wide reset is de-asserted _synchronously_ at a _falling_ edge of the main clock to ensure there are no
1141+
meta-stable situation (like de-asserting reset at a rising edge).
1142+
1143+
If one of the internal reset sources trigger a reset, this will be applied _synchronously_ to all processor modules
1144+
at a rising edge. This signal is also extended to be active for at least 4 clock cycles. After that, the system wide
1145+
reset is also de-asserted _synchronously_ at a _falling_ edge.
1146+
1147+
[TIP]
1148+
The EE Times provided a nice article about FPGA resets. The reset system of the NEORV32 is loosely based on this
1149+
article: https://www.eetimes.com/how-do-i-reset-my-fpga/
1150+
1151+
The system-wide reset will reset the CPU, the <<_processor_clocking>> system and the IO/peripheral devices.
1152+
1153+
[NOTE]
1154+
Note that the system reset will **NOT** reset _all_ PCU register by default. See section <<_cpu_hardware_reset>>
1155+
for more information.
1156+
1157+
[NOTE]
1158+
The system reset will only reset the control registers of each implemented IO/peripheral module. This will also
1159+
reset the according "module enable flag" to zero, which - in turn - will cause a _synchronous_ and
1160+
module-internal reset of the remaining logic.
1161+
1162+
10751163
<<<
10761164
// ####################################################################################################################
10771165
:sectnums:
@@ -1372,40 +1460,7 @@ exited as soon as the application logic has finished initializing the memory wit
13721460

13731461
Basically, the NEORV32 processor is a SoC consisting of the NEORV32 CPU, peripheral/IO devices, embedded
13741462
memories, an external memory interface and a bus infrastructure to interconnect all units. Additionally, the
1375-
system implements an internal reset generator and a global clock generator/divider.
1376-
1377-
1378-
**Internal Reset Generator**
1379-
1380-
The internal reset generator is responsible for controlling the processor-global system reset.
1381-
This system reset is either triggered via the external reset pin (`rstn_i`, low-active), by the internal
1382-
watchdog timer (if implemented) or by the on-chip debugger (if implemented). If any of those sources issues
1383-
an active reset the system reset is activated for at least 4 cycles.
1384-
1385-
1386-
**Internal Clock Divider**
1387-
1388-
An internal clock divider generates 8 clock signals derived from the processor's main clock input `clk_i`.
1389-
These derived clock signals are not actual _clock signals_. Instead, they are derived from a simple counter and
1390-
can be used as "clock enable" signal by the different processor modules. Thus, the whole processor operates using
1391-
only the main clock signal (single clock domain). Some of the processor peripherals like the Watchdog or the
1392-
UARTs can select one of the derived clock enabled signals for their internal operations.
1393-
1394-
[TIP]
1395-
If none of the peripheral modules require a clock signal from the internal divider, it is automatically deactivated
1396-
to reduce dynamic power consumption.
1397-
1398-
Peripheral devices, which feature a time-based configuration, provide a three-bit prescaler select in their
1399-
according control register to select one of the eight available clocks. The mapping of the prescaler select
1400-
bits to the according clock source is shown in the table below. Here, _f_ represents the processor main clock
1401-
from the top entity's `clk_i` signal.
1402-
1403-
[cols="<3,^1,^1,^1,^1,^1,^1,^1,^1"]
1404-
[grid="rows"]
1405-
|=======================
1406-
| Prescaler bits: | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
1407-
| Resulting clock: | _f/2_ | _f/4_ | _f/8_ | _f/64_ | _f/128_ | _f/1024_| _f/2048_| _f/4096_
1408-
|=======================
1463+
system implements an internal reset generator (-> <<_processor_reset>>) and a global clock system (-> <<_processor_clocking>>).
14091464

14101465

14111466
**Peripheral / IO Devices**
@@ -1415,7 +1470,7 @@ address _0xFFFFFE00_. A region of 512 bytes is reserved for this devices. Hence,
14151470
accessed using a memory-mapped scheme. A special linker script as well as the NEORV32 core software
14161471
library abstract the specific memory layout for the user.
14171472

1418-
.Address Space Mapping
1473+
.Module Address Space Mapping
14191474
[IMPORTANT]
14201475
The base address of each component/module has to be aligned to the
14211476
total size of the module's occupied address space! The occupied address space
@@ -1428,19 +1483,18 @@ All peripheral/IO devices can only be written in full-word mode (i.e. 32-bit). B
14281483
Processor-internal memories as well as modules connected to the external memory interface can still
14291484
be written with a byte-wide granularity.
14301485

1431-
.Unimplemented Modules
1486+
.Unimplemented Modules / "Address Holes"
14321487
[NOTE]
1433-
When accessing an IO device that hast not been implemented (disabled via the according generic), a
1434-
load or store access fault exception is triggered.
1488+
When accessing an IO device that hast not been implemented (disabled via the according generic)
1489+
or when accessing an address that is _unused_, a load or store access fault exception is raise.
14351490

14361491
.Module Reset
14371492
[NOTE]
1438-
All processor-internal modules provide a dedicated hardware reset, which can be triggered by the external reset
1439-
signal, the watchdog timer or the on-chip debugger. When active, the system-wide reset will ensure that all
1440-
**module interface register** (like the control register) are reset to all-zero. Note that this hardware reset
1441-
does not _directly_ reset the remaining module's logic - the internal logic is reset _synchronously_ when the
1493+
All processor-internal modules provide a dedicated hardware reset, which is triggered by the <<_processor_reset>>
1494+
system. When active, the system-wide reset will reset all module's _control registers_ to all-zero. Note that this
1495+
hardware reset does not _directly_ reset the remaining module's logic - the internal logic is reset _synchronously_ when the
14421496
enable bit in the according unit's control register is cleared. Software can trigger a module reset
1443-
by clearing the enable bit of the module's control register.
1497+
by clearing the enable bit of the module's control register. See section <<_processor_reset>> for more information.
14441498

14451499
.Software Access
14461500
[TIP]
@@ -1458,9 +1512,10 @@ A CMSIS-SVD-compatible **System View Description (SVD)** file including all peri
14581512
Most peripheral/IO devices provide some kind of interrupt (for example to signal available incoming data). These
14591513
interrupts are entirely mapped to the CPU's <<_custom_fast_interrupt_request_lines>>. Note that all these
14601514
interrupt lines are high-active and are permanently triggered until the IRQ-causing condition is resolved.
1515+
See section <<_processor_interrupts>> for more information.
14611516

14621517

1463-
**Nomenclature for the Peripheral / IO Devices Listing**
1518+
**Nomenclature for Peripheral / IO Devices Listing**
14641519

14651520
Each peripheral device chapter features a register map showing accessible control and data registers of the
14661521
according device including the implemented control and status bits. C-language code can directly interact with these

docs/datasheet/soc_wdt.adoc

+39-13
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,23 @@
1616

1717
**Theory of Operation**
1818

19-
The watchdog (WDT) provides a last resort for safety-critical applications. The WDT has an internal 20-bit
19+
The watchdog (WDT) provides a last resort for safety-critical applications. The WDT provides an internal 20-bit
2020
wide counter that needs to be reset every now and then by the user program. If the counter overflows, either
2121
a system reset or an interrupt is generated depending on the configured operation mode.
2222

23+
24+
**Access Password**
25+
26+
Whenever the watchdog control register `NEORV32_WDT.CTRL` shall be written the upper-most (MSB-aligned) 16 bit of the
27+
write data have to contain the "watchdog access password". If the password is incorrect the write access is entirely ignored
28+
and the watchdog hardware module will **not acknowledge** the bus write access leading to a **store access fault exception**.
29+
Read accesses are not affected by the access password at all.
30+
31+
* Watchdog access password (`write_data[31:16]`) = **`0xCA36`**
32+
33+
34+
**Timeout Configuration**
35+
2336
The watchdog is enabled by setting the control register's `WDT_CTRL_EN_ bit. The clock used to increment the
2437
internal counter is selected via the 3-bit _WDT_CTRL_CLK_SELx_ prescaler:
2538

@@ -38,27 +51,27 @@ internal counter is selected via the 3-bit _WDT_CTRL_CLK_SELx_ prescaler:
3851
|=======================
3952

4053
The _WDT_CTRL_HALF_ flag of the control register `CTRL` indicates that at least half of the maximum timeout
41-
value has already been reached. The watchdog is reset by setting the _WDT_CTRL_RESET_ bit.
54+
value has already been reached. The watchdog is "fed" by setting the _WDT_CTRL_RESET_ control register bit, which
55+
will reset the timeout counter.
56+
57+
58+
**Watchdog Action**
4259

4360
Whenever the internal counter overflows the watchdog executes one of two possible actions: either a hard
4461
processor reset is triggered or an interrupt is requested via the CPU's fast interrupt channel #0. The
45-
_WDT_CTRL_MODE_ bit defines the action to be taken on an overflow: when cleared, the Watchdog will assert an
62+
_WDT_CTRL_MODE_ bit defines the action to be taken on an overflow: when cleared, the watchdog will assert an
4663
IRQ, when set the WDT will cause a system wide reset. The configured action can also be triggered manually at
4764
any time by setting the _WDT_CTRL_FORCE_ bit.
4865

66+
The cause of the last system reset can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
67+
zero, the processor has been reset via the external reset signal (or the on-chip debugger). If this flag is set
68+
the last system reset was caused by the watchdog itself.
69+
70+
.Watchdog Interrupt
4971
[NOTE]
5072
A watchdog interrupt can only occur if the watchdog is enabled and interrupt mode is enabled.
5173
A triggered interrupt has to be cleared again by writing zero to the according <<_mip>> CSR bit.
5274

53-
The cause of the last system reset can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
54-
zero, the processor has been reset via the external reset signal. If this flag is set the last system reset was
55-
initiated by the watchdog.
56-
57-
The Watchdog control register can be locked in order to protect the current configuration. The lock is
58-
activated by setting the _WDT_CTRL_LOCK_ bit. In the locked state any write access to the configuration flags is
59-
ignored (see table below, "writable if locked"). Read accesses to the control register are not effected. The
60-
lock can only be removed by a system reset (via external reset signal or via a watchdog reset action).
61-
6275
.Watchdog Operation during Debugging
6376
[IMPORTANT]
6477
By default the watchdog stops operation when the CPU enters debug mode and will resume normal operation after
@@ -72,14 +85,25 @@ By default the watchdog keeps operating when the CPU enters sleep mode. However,
7285
the CPU is sleeping by setting the _WDT_CTRL_PAUSE_ control register bit.
7386

7487

88+
**Configuration Lock**
89+
90+
The watchdog control register can be locked to protect the current configuration from being modified. The lock is activated by
91+
setting the _WDT_CTRL_LOCK_ bit. In the locked state any write access to the control register's configuration flags is
92+
ignored (see table below, "writable if locked"). Read accesses to the control register as well as watchdog resets (_WDT_CTRL_RESET_)
93+
and forced watchdog actions (_WDT_CTRL_FORCE_) are not affected.
94+
95+
The lock is removed by a system reset, which can be triggered via the external hardware reset signal, the on-chip debugger
96+
or the watchdog itself (if _WDT_CTRL_MODE_ is set).
97+
98+
7599
**Register Map**
76100

77101
.WDT register map (`struct NEORV32_WDT`)
78102
[cols="<2,<2,<4,^1,^1,^2,<4"]
79103
[options="header",grid="all"]
80104
|=======================
81105
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
82-
.12+<| `0xffffffbc` .12+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| `0` ^| no <| watchdog enable
106+
.14+<| `0xffffffbc` .14+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| `0` ^| no <| watchdog enable
83107
<|`1` _WDT_CTRL_CLK_SEL0_ ^| r/w ^| `0` ^| no .3+<| 3-bit clock prescaler select
84108
<|`2` _WDT_CTRL_CLK_SEL1_ ^| r/w ^| `0` ^| no
85109
<|`3` _WDT_CTRL_CLK_SEL2_ ^| r/w ^| `0` ^| no
@@ -91,4 +115,6 @@ the CPU is sleeping by setting the _WDT_CTRL_PAUSE_ control register bit.
91115
<|`9` _WDT_CTRL_DBEN_ ^| r/w ^| `0` ^| no <| allow WDT to continue operation even when CPU is in debug mode
92116
<|`10` _WDT_CTRL_HALF_ ^| r/- ^| `0` ^| - <| set if at least half of the max. timeout counter value has been reached
93117
<|`11` _WDT_CTRL_PAUSE_ ^| r/w ^| `0` ^| no <| pause WDT when CPU is in sleep mode
118+
<|`15:12` - ^| r/- ^| - ^| - <| _reserved_, reads as zero
119+
<|`31:16` _WDT_CTRL_PWD_ ^| -/w ^| - ^| - <| watchdog write access password, has to be `0xCA36`, reads as zero
94120
|=======================

rtl/core/neorv32_package.vhd

+4-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ package neorv32_package is
6868
-- Architecture Constants (do not modify!) ------------------------------------------------
6969
-- -------------------------------------------------------------------------------------------
7070
constant data_width_c : natural := 32; -- native data path width - do not change!
71-
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070206"; -- NEORV32 version - no touchy!
71+
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070207"; -- NEORV32 version - no touchy!
7272
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
7373

7474
-- Check if we're inside the Matrix -------------------------------------------------------
@@ -1665,7 +1665,8 @@ package neorv32_package is
16651665
port (
16661666
-- host access --
16671667
clk_i : in std_ulogic; -- global clock line
1668-
rstn_i : in std_ulogic; -- global reset line, low-active
1668+
rstn_ext_i : in std_ulogic; -- external reset line, low-active, async
1669+
rstn_int_i : in std_ulogic; -- internal reset line, low-active, async
16691670
rden_i : in std_ulogic; -- read enable
16701671
wren_i : in std_ulogic; -- write enable
16711672
addr_i : in std_ulogic_vector(31 downto 0); -- address
@@ -1680,7 +1681,7 @@ package neorv32_package is
16801681
clkgen_i : in std_ulogic_vector(07 downto 0);
16811682
-- timeout event --
16821683
irq_o : out std_ulogic; -- timeout IRQ
1683-
rstn_o : out std_ulogic -- timeout reset, low_active, use it as async!
1684+
rstn_o : out std_ulogic -- timeout reset, low_active, sync
16841685
);
16851686
end component;
16861687

0 commit comments

Comments
 (0)