<<<
:sectnums:
==== Watchdog Timer (WDT)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_wdt.vhd | 
| Software driver file(s): | neorv32_wdt.c |
|                          | neorv32_wdt.h |
| Top entity port:         | none | 
| Configuration generics:  | _IO_WDT_EN_ | implement watchdog when _true_
| CPU interrupts:          | fast IRQ channel 0 | watchdog timeout (see <<_processor_interrupts>>)
|=======================


**Theory of Operation**

The watchdog (WDT) provides a last resort for safety-critical applications. The WDT provides a "bark and bite"
concept. The timeout counter first triggers an optional CPU interrupt ("bark") when reaching half of the programmed
interval to inform the application of the imminent timeout. When the full timeout value is reached
a system-wide hardware reset is generated ("bite"). The internal counter has to be reset explicitly by the application
program every now and then to prevent a timeout.


**Configuration**

The watchdog is enabled by setting the control register's `WDT_CTRL_EN_ bit. When this bit is cleared, the internal
timeout counter is reset to zero and no interrupt and no system reset can be triggered.

The internal 32-bit timeout counter is clocked at 1/4096th of the processor's main clock (f~WDT~[Hz] = f~main~[Hz] / 4096).
Whenever this counter reaches the programmed timeout value (_WDT_CTRL_TIMEOUT_ bits in the control register) a
hardware reset is triggered. In order to inform the application of an imminent timeout, an optional CPU interrupt is
triggered when the timeout counter reaches **half** of the programmed timeout value.

The watchdog is "fed" by writing `1` to the _WDT_CTRL_RESET_ control register bit, which
will reset the internal timeout counter back to zero.

[NOTE]
Writing all-zero to the _WDT_CTRL_TIMEOUT_ bits will immediately trigger a system-wide reset.

.Watchdog Interrupt
[NOTE]
A watchdog interrupt occurs when the watchdog is enabled and the internal counter reaches half of the programmed
timeout value. A triggered interrupt has to be explicitly cleared by writing zero to the according <<_mip>> CSR bit.

.Watchdog Operation during Debugging
[IMPORTANT]
By default the watchdog stops operation when the CPU enters debug mode and will resume normal operation after
the CPU has left debug mode again. This will prevent an unintended watchdog timeout during a debug session. However,
the watchdog can also be configured to keep operating even when the CPU is in debug mode by setting the control
register's _WDT_CTRL_DBEN_ bit.

.Watchdog Operation during CPU Sleep
[IMPORTANT]
By default the watchdog stops operating when the CPU enters sleep mode. However, the watchdog can also be configured
to keep operating even when the CPU is in sleep mode by setting the control register's _WDT_CTRL_SEN_ bit.


**Configuration Lock**

The watchdog control register can be locked to protect the current configuration from being modified. The lock is
activated by setting the _WDT_CTRL_LOCK_ bit. In the locked state any write access to the control register is entirely
ignored (see table below, "writable if locked"). Read accesses to the control register as well as watchdog resets
(by setting the _WDT_CTRL_RESET_ flag) are not affected.

The lock bit can only be set if the WDT is already enabled (_WDT_CTRL_EN_ is set).
The lock bit can only be cleared again by a system-wide hardware reset.


**Cause of last Hardware Reset**

The cause of the last system hardware reset can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
zero, the processor has been reset via the external reset signal (or the on-chip debugger). If this flag is set,
the last system reset was caused by the watchdog itself.


**Register Map**

.WDT register map (`struct NEORV32_WDT`)
[cols="<2,<2,<4,^1,^1,^2,<4"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
.8+<| `0xffffffbc` .8+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_     ^| r/w ^| `0` ^| no  <| watchdog enable
                                            <|`1  _WDT_CTRL_LOCK_   ^| r/w ^| `0` ^| no  <| lock configuration when set, clears only on system reset, can only be set if enable bit is set already
                                            <|`2` _WDT_CTRL_DBEN_   ^| r/w ^| `0` ^| no  <| set to allow WDT to continue operation even when CPU is in debug mode
                                            <|`3` _WDT_CTRL_SEN_    ^| r/w ^| `0` ^| no  <| set to allow WDT to continue operation even when CPU is in sleep mode
                                            <|`4` _WDT_CTRL_RESET_  ^| -/w ^| -   ^| yes <| reset watchdog when set, auto-clears
                                            <|`5` _WDT_CTRL_RCAUSE_ ^| r/- ^| `0` ^| -   <| cause of last system reset: `0`=caused by external reset signal, `1`=caused by watchdog
                                            <|`7:6` -               ^| r/- ^| -   ^| -   <| _reserved_, reads as zero
                                            <|`31:8` _WDT_CTRL_TIMEOUT_MSB_ : _WDT_CTRL_TIMEOUT_LSB_ ^| r/w ^| 0 ^| no <| 24-bit watchdog timeout value
|=======================
