⚠️ [wdt] remove "halt if sleep or debug"

This commit is contained in:
stnolting 2025-02-02 19:16:22 +01:00
parent 76ec64d708
commit ca60ea7437
5 changed files with 21 additions and 67 deletions

View file

@ -33,17 +33,9 @@ hardware reset is triggered.
The watchdog's timeout counter is reset ("feeding the watchdog") by writing the reset **PASSWORD** to the `RESET` register.
The password is hardwired to hexadecimal `0x709D1AB3`.
.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.
Once enabled, the watchdog keeps operating even if the CPU is in <<_sleep_mode>> or if the processor is being
debugged via the <<_on_chip_debugger_ocd>>.
**Configuration Lock**
@ -91,12 +83,10 @@ processor's main reset signal is active (even if the watchdog is deactivated or
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
.8+<| `0xfffb0000` .8+<| `CTRL` <|`0` `WDT_CTRL_EN` ^| r/w ^| `0` ^| no <| watchdog enable
.6+<| `0xfffb0000` .6+<| `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_STRICT` ^| r/w ^| `0` ^| no <| set to enable strict mode (force hardware reset if reset password is incorrect or if write access to locked CTRL register)
<|`6:5` `WDT_CTRL_RCAUSE_HI : WDT_CTRL_RCAUSE_LO` ^| r/- ^| `0` ^| - <| cause of last system reset; 0=external reset, 1=ocd-reset, 2=watchdog reset
<|`2` `WDT_CTRL_STRICT` ^| r/w ^| `0` ^| no <| set to enable strict mode (force hardware reset if reset password is incorrect or if write access to locked CTRL register)
<|`4:3` `WDT_CTRL_RCAUSE_HI : WDT_CTRL_RCAUSE_LO` ^| r/- ^| `0` ^| - <| cause of last system reset; 0=external reset, 1=ocd-reset, 2=watchdog reset
<|`7` - ^| r/- ^| - ^| - <| _reserved_, reads as zero
<|`31:8` `WDT_CTRL_TIMEOUT_MSB : WDT_CTRL_TIMEOUT_LSB` ^| r/w ^| 0 ^| no <| 24-bit watchdog timeout value
| `0xfffb0004` | `RESET` |`31:0` | -/w | - | yes | Write _PASSWORD_ to reset WDT timeout counter

View file

@ -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 --
-- ================================================================================ --
@ -37,12 +37,10 @@ architecture neorv32_wdt_rtl of neorv32_wdt is
-- Control register bits --
constant ctrl_enable_c : natural := 0; -- r/w: WDT enable
constant ctrl_lock_c : natural := 1; -- r/w: lock write access to control register when set
constant ctrl_dben_c : natural := 2; -- r/w: allow WDT to continue operation even when CPU is in debug mode
constant ctrl_sen_c : natural := 3; -- r/w: allow WDT to continue operation even when CPU is in sleep mode
constant ctrl_strict_c : natural := 4; -- r/w: force hardware reset if reset password is incorrect or if access to locked config
constant ctrl_rcause_lo_c : natural := 5; -- r/-: cause of last system reset - low
constant ctrl_rcause_hi_c : natural := 6; -- r/-: cause of last system reset - high
--constant ctrl_reserved_c : natural := 7; -- r/-: reserved
constant ctrl_strict_c : natural := 2; -- r/w: force hardware reset if reset password is incorrect or if access to locked config
constant ctrl_rcause_lo_c : natural := 3; -- r/-: cause of last system reset - low
constant ctrl_rcause_hi_c : natural := 4; -- r/-: cause of last system reset - high
--
constant ctrl_timeout_lsb_c : natural := 8; -- r/w: timeout value LSB
constant ctrl_timeout_msb_c : natural := 31; -- r/w: timeout value MSB
@ -50,8 +48,6 @@ architecture neorv32_wdt_rtl of neorv32_wdt is
type ctrl_t is record
enable : std_ulogic;
lock : std_ulogic;
dben : std_ulogic;
sen : std_ulogic;
strict : std_ulogic;
timeout : std_ulogic_vector(23 downto 0);
end record;
@ -61,7 +57,6 @@ architecture neorv32_wdt_rtl of neorv32_wdt is
signal cnt : std_ulogic_vector(23 downto 0); -- timeout counter
signal cnt_started : std_ulogic; -- set when timeout counter has started
signal cnt_inc : std_ulogic; -- increment counter when set
signal cnt_inc_ff : std_ulogic;
signal cnt_timeout : std_ulogic; -- counter matches programmed timeout value
signal reset_cause : std_ulogic_vector(1 downto 0); -- cause of last reset
signal hw_rst_timeout : std_ulogic; -- trigger reset because of timeout
@ -79,8 +74,6 @@ begin
bus_rsp_o <= rsp_terminate_c;
ctrl.enable <= '0'; -- disable WDT after reset
ctrl.lock <= '0'; -- unlock after reset
ctrl.dben <= '0';
ctrl.sen <= '0';
ctrl.strict <= '0';
ctrl.timeout <= (others => '0');
reset_wdt <= '0';
@ -100,8 +93,6 @@ begin
if (ctrl.lock = '0') then -- update configuration only if not locked
ctrl.enable <= bus_req_i.data(ctrl_enable_c);
ctrl.lock <= bus_req_i.data(ctrl_lock_c) and ctrl.enable; -- lock only if already enabled
ctrl.dben <= bus_req_i.data(ctrl_dben_c);
ctrl.sen <= bus_req_i.data(ctrl_sen_c);
ctrl.strict <= bus_req_i.data(ctrl_strict_c);
ctrl.timeout <= bus_req_i.data(ctrl_timeout_msb_c downto ctrl_timeout_lsb_c);
else -- write access attempt to locked CTRL register
@ -117,8 +108,6 @@ begin
else -- read access
bus_rsp_o.data(ctrl_enable_c) <= ctrl.enable;
bus_rsp_o.data(ctrl_lock_c) <= ctrl.lock;
bus_rsp_o.data(ctrl_dben_c) <= ctrl.dben;
bus_rsp_o.data(ctrl_sen_c) <= ctrl.sen;
bus_rsp_o.data(ctrl_rcause_hi_c downto ctrl_rcause_lo_c) <= reset_cause;
bus_rsp_o.data(ctrl_strict_c) <= ctrl.strict;
bus_rsp_o.data(ctrl_timeout_msb_c downto ctrl_timeout_lsb_c) <= ctrl.timeout;
@ -133,15 +122,15 @@ begin
wdt_counter: process(rstn_sys_i, clk_i)
begin
if (rstn_sys_i = '0') then
cnt_inc_ff <= '0';
cnt_inc <= '0';
cnt_started <= '0';
cnt <= (others => '0');
elsif rising_edge(clk_i) then
cnt_inc_ff <= cnt_inc;
cnt_inc <= prsc_tick and cnt_started; -- clock tick and started
cnt_started <= ctrl.enable and (cnt_started or prsc_tick); -- start with next clock tick
if (ctrl.enable = '0') or (reset_wdt = '1') then -- watchdog disabled or reset with correct password
cnt <= (others => '0');
elsif (cnt_inc_ff = '1') then
elsif (cnt_inc = '1') then
cnt <= std_ulogic_vector(unsigned(cnt) + 1);
end if;
end if;
@ -151,11 +140,6 @@ begin
clkgen_en_o <= ctrl.enable; -- enable clock generator
prsc_tick <= clkgen_i(clk_div4096_c); -- clock enable tick
-- valid counter increment? --
cnt_inc <= '1' when ((prsc_tick = '1') and (cnt_started = '1')) and -- clock tick and started
((bus_req_i.debug = '0') or (ctrl.dben = '1')) and -- not in debug mode or allowed to run in debug mode
((bus_req_i.sleep = '0') or (ctrl.sen = '1')) else '0'; -- not in sleep mode or allowed to run in sleep mode
-- timeout detector --
cnt_timeout <= '1' when (cnt_started = '1') and (cnt = ctrl.timeout) else '0';

View file

@ -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.h
* @brief Watchdog Timer (WDT) HW driver header file.
*
* @note These functions should only be used if the WDT unit was synthesized (IO_WDT_EN = true).
*
* @see https://stnolting.github.io/neorv32/sw/files.html
*/
#ifndef neorv32_wdt_h
@ -38,11 +34,9 @@ typedef volatile struct __attribute__((packed,aligned(4))) {
enum NEORV32_WDT_CTRL_enum {
WDT_CTRL_EN = 0, /**< WDT control register(0) (r/w): Watchdog enable */
WDT_CTRL_LOCK = 1, /**< WDT control register(1) (r/w): Lock write access to control register, clears on reset only */
WDT_CTRL_DBEN = 2, /**< WDT control register(2) (r/w): Allow WDT to continue operation even when CPU is in debug mode */
WDT_CTRL_SEN = 3, /**< WDT control register(3) (r/w): Allow WDT to continue operation even when CPU is in sleep mode */
WDT_CTRL_STRICT = 4, /**< WDT control register(4) (r/w): Force hardware reset if reset password is incorrect or if write attempt to locked CTRL register */
WDT_CTRL_RCAUSE_LO = 5, /**< WDT control register(5) (r/-): Cause of last system reset - low */
WDT_CTRL_RCAUSE_HI = 6, /**< WDT control register(5) (r/-): Cause of last system reset - high */
WDT_CTRL_STRICT = 2, /**< WDT control register(2) (r/w): Force hardware reset if reset password is incorrect or if write attempt to locked CTRL register */
WDT_CTRL_RCAUSE_LO = 3, /**< WDT control register(3) (r/-): Cause of last system reset - low */
WDT_CTRL_RCAUSE_HI = 4, /**< WDT control register(4) (r/-): Cause of last system reset - high */
WDT_CTRL_TIMEOUT_LSB = 8, /**< WDT control register(8) (r/w): Timeout value, LSB */
WDT_CTRL_TIMEOUT_MSB = 31 /**< WDT control register(31) (r/w): Timeout value, MSB */
@ -72,7 +66,7 @@ enum NEORV32_WDT_RCAUSE_enum {
**************************************************************************/
/**@{*/
int neorv32_wdt_available(void);
void neorv32_wdt_setup(uint32_t timeout, int lock, int debug_en, int sleep_en, int strict);
void neorv32_wdt_setup(uint32_t timeout, int lock, int strict);
int neorv32_wdt_disable(void);
void neorv32_wdt_feed(uint32_t password);
int neorv32_wdt_get_cause(void);

View file

@ -38,11 +38,9 @@ int neorv32_wdt_available(void) {
* @param[in] timeout 24-bit timeout value. A WDT IRQ is triggered when the internal counter reaches
* 'timeout/2'. A system hardware reset is triggered when the internal counter reaches 'timeout'.
* @param[in] lock Control register will be locked when 1 (until next reset).
* @param[in] debug_en Allow watchdog to continue operation even when CPU is in debug mode.
* @param[in] sleep_en Allow watchdog to continue operation even when CPU is in sleep mode.
* @param[in] strict Force hardware reset if reset password is incorrect or if trying to alter a locked configuration.
**************************************************************************/
void neorv32_wdt_setup(uint32_t timeout, int lock, int debug_en, int sleep_en, int strict) {
void neorv32_wdt_setup(uint32_t timeout, int lock, int strict) {
NEORV32_WDT->CTRL = 0; // reset and disable
@ -50,8 +48,6 @@ void neorv32_wdt_setup(uint32_t timeout, int lock, int debug_en, int sleep_en, i
uint32_t ctrl = 0;
ctrl |= ((uint32_t)(1)) << WDT_CTRL_EN;
ctrl |= ((uint32_t)(timeout & 0xffffffU)) << WDT_CTRL_TIMEOUT_LSB;
ctrl |= ((uint32_t)(debug_en & 0x1U)) << WDT_CTRL_DBEN;
ctrl |= ((uint32_t)(sleep_en & 0x1U)) << WDT_CTRL_SEN;
ctrl |= ((uint32_t)(strict & 0x1U)) << WDT_CTRL_STRICT;
NEORV32_WDT->CTRL = ctrl;

View file

@ -1404,24 +1404,14 @@
<bitRange>[1:1]</bitRange>
<description>Lock write access to control register, clears on reset (HW or WDT) only</description>
</field>
<field>
<name>WDT_CTRL_DBEN</name>
<bitRange>[2:2]</bitRange>
<description>Allow WDT to continue operation even when in debug mode</description>
</field>
<field>
<name>WDT_CTRL_SEN</name>
<bitRange>[3:3]</bitRange>
<description>Allow WDT to continue operation even when in sleep mode</description>
</field>
<field>
<name>WDT_CTRL_STRICT</name>
<bitRange>[4:4]</bitRange>
<bitRange>[2:2]</bitRange>
<description>Force hardware reset if reset password is incorrect or if write attempt to locked CTRL register</description>
</field>
<field>
<name>WDT_CTRL_RCAUSE</name>
<bitRange>[6:5]</bitRange>
<bitRange>[4:3]</bitRange>
<access>read-only</access>
<description>Cause of last system reset: 0=external reset, 1=OCD reset, 2=WDT reset, 3=WDT access violation</description>
</field>