Skip to content

Commit

Permalink
add watchdog feature
Browse files Browse the repository at this point in the history
Signed-off-by: Fin Maaß <[email protected]>
  • Loading branch information
maass-hamburg committed Jun 21, 2024
1 parent 29bdf68 commit 2148ea9
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
70 changes: 70 additions & 0 deletions litex/soc/cores/watchdog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2024 Fin Maaß <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

from migen import *

from litex.gen import *
from litex.gen.genlib.misc import WaitTimer

from litex.soc.interconnect.csr import *
from litex.soc.interconnect.csr_eventmanager import *

# Watchdog --------------------------------------------------------------------------------------------

class Watchdog(LiteXModule):
"""Watchdog
Provides a generic Watchdog core.
"""

def __init__(self, width=32, crg_rst=None, reset_delay=0, halted=None):
self.enable = Signal()
self.reset_mode = Signal()
self.feed = Signal()
self.halted = Signal()

self.execute = Signal()

self._control = CSRStorage(description="Watchdog Control.", fields=[
CSRField("feed", size=1, offset=0, pulse=True, description="Watchdog feed (Write ``1`` to feed)."),
CSRField("enable", size=1, offset=8, description="Watchdog enable."),
CSRField("reset", size=1, offset=16, description="Reset SoC when watchdog times out."),
CSRField("pause_halted", size=1, offset=24, description="Pause watchdog when CPU is halted.")
])

self.comb += [
self.enable.eq(self._control.fields.enable & ~self.halted),
self.feed.eq(self._control.fields.feed),
self.reset_mode.eq(self._control.fields.reset),
]

if isinstance(halted, Signal):
self.comb += self.halted.eq(halted & self._control.fields.pause_halted)

self._cycles = cycles = CSRStorage(description="Watchdog cycles until timeout.", size=width)
self._remaining = remaining = CSRStatus(description="Watchdog cycles remaining until timeout.", size=width)

self.ev = EventManager()
self.ev.wdt = EventSourceProcess(edge="rising")
self.ev.finalize()

self.sync += [
If(self.feed,
remaining.status.eq(cycles.storage)
).Elif(self.enable,
If(remaining.status != 0,
remaining.status.eq(remaining.status - 1)
),
self.execute.eq(remaining.status == 0),
)
]

self.comb += If(self.enable, self.ev.wdt.trigger.eq(self.execute))

if isinstance(crg_rst, Signal):
self.reset_timer = WaitTimer(reset_delay)
self.comb += self.reset_timer.wait.eq(self.enable & self.execute & self.reset_mode)
self.comb += If(self.reset_timer.done, crg_rst.eq(1))
18 changes: 18 additions & 0 deletions litex/soc/integration/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,24 @@ def add_timer(self, name="timer0"):
if self.irq.enabled:
self.irq.add(name, use_loc_if_exists=True)

# Add Watchdog ---------------------------------------------------------------------------------
def add_watchdog(self, name="watchdog0", width=32, crg_rst=None, reset_delay=None):
from litex.soc.cores.watchdog import Watchdog

if crg_rst is None:
crg_rst = getattr(self.crg, "rst", None) if hasattr(self, "crg") else None
if reset_delay is None:
reset_delay = self.sys_clk_freq

halted = getattr(self.cpu, "o_halted", None) if hasattr(self, "cpu") else None

self.check_if_exists(name)
watchdog = Watchdog(width=width, crg_rst=crg_rst, reset_delay=int(reset_delay), halted=halted)
self.add_module(name=name, module=watchdog)

if self.irq.enabled:
self.irq.add(name, use_loc_if_exists=True)

# SoC finalization -----------------------------------------------------------------------------
def finalize(self):
if self.finalized:
Expand Down
13 changes: 13 additions & 0 deletions litex/soc/integration/soc_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ def __init__(self, platform, clk_freq,
# UARTBone.
with_uartbone = False,

# Watchdog.
with_watchdog = False,
watchdog_width = 32,
watchdog_reset_delay = None,

# Others.
**kwargs):

Expand Down Expand Up @@ -266,6 +271,10 @@ def __init__(self, platform, clk_freq,
if timer_uptime:
self.timer0.add_uptime()

# Add Watchdog.
if with_watchdog:
self.add_watchdog(name="watchdog0" ,width=watchdog_width, reset_delay=watchdog_reset_delay)

# Methods --------------------------------------------------------------------------------------

def add_csr(self, csr_name, csr_id=None, use_loc_if_exists=False):
Expand Down Expand Up @@ -338,6 +347,10 @@ def soc_core_args(parser):
soc_group.add_argument("--no-timer", action="store_true", help="Disable Timer.")
soc_group.add_argument("--timer-uptime", action="store_true", help="Add an uptime capability to Timer.")

# Watchdog parameters.
soc_group.add_argument("--with-watchdog", action="store_true", help="Enable Watchdog.")
soc_group.add_argument("--watchdog-width", default=32, type=auto_int, help="Watchdog width.")

# L2 Cache.
soc_group.add_argument("--l2-size", default=8192, type=auto_int, help="L2 cache size.")

Expand Down
4 changes: 4 additions & 0 deletions litex/tools/litex_json2dts_zephyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ def peripheral_handler(name, parm, csr):
'handler': i2s_handler,
'config_entry': 'I2S_LITEX'
},
'watchdog0': {
'handler': peripheral_handler,
'alias': 'wdt0',
},
'mmcm' : {
'alias': 'clock0',
'handler': peripheral_handler,
Expand Down

0 comments on commit 2148ea9

Please sign in to comment.