diff --git a/amaranth/hdl/ast.py b/amaranth/hdl/ast.py index 7655d8a..8921bb8 100644 --- a/amaranth/hdl/ast.py +++ b/amaranth/hdl/ast.py @@ -184,6 +184,9 @@ class Value(metaclass=ABCMeta): super().__init__() self.src_loc = tracer.get_src_loc(1 + src_loc_at) + def __await__(self): + return (yield self) + def __bool__(self): raise TypeError("Attempted to convert Amaranth value to Python boolean") @@ -1500,6 +1503,9 @@ class Statement: def __init__(self, *, src_loc_at=0): self.src_loc = tracer.get_src_loc(1 + src_loc_at) + def __await__(self): + yield self + @staticmethod def cast(obj): if isinstance(obj, Iterable): diff --git a/amaranth/sim/core.py b/amaranth/sim/core.py index e2ec560..798f46c 100644 --- a/amaranth/sim/core.py +++ b/amaranth/sim/core.py @@ -11,7 +11,8 @@ __all__ = ["Settle", "Delay", "Tick", "Edge", "Passive", "Active", "Simulator"] class Command: - pass + def __await__(self): + yield self class Settle(Command): @@ -83,7 +84,10 @@ class Simulator: def wrapper(): # Only start a bench process after comb settling, so that the reset values are correct. yield Settle() - yield from process() + g = process() + if inspect.isawaitable(g): + g = g.__await__() + yield from g self._engine.add_coroutine_process(wrapper, default_cmd=None) def add_sync_process(self, process, *, domain="sync"): @@ -92,7 +96,10 @@ class Simulator: # Only start a sync process after the first clock edge (or reset edge, if the domain # uses an asynchronous reset). This matches the behavior of synchronous FFs. yield Tick(domain) - yield from process() + g = process() + if inspect.isawaitable(g): + g = g.__await__() + yield from g self._engine.add_coroutine_process(wrapper, default_cmd=Tick(domain)) def add_clock(self, period, *, phase=None, domain="sync", if_exists=False):