Skip to content

Commit

Permalink
sim: awaken all processes waiting on changed() at time 0.
Browse files Browse the repository at this point in the history
  • Loading branch information
wanda-phi authored and whitequark committed Jun 14, 2024
1 parent f3bcdf4 commit 3d2cd15
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
8 changes: 8 additions & 0 deletions amaranth/sim/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,10 +749,18 @@ def reset(self):
self.critical = not self.background
self.waits_on = None
self.coroutine = self.constructor(self.context)
self.first_await = True

def run(self):
try:
self.waits_on = self.coroutine.send(None)
# Special case to make combination logic replacement work correctly: ensure that
# a process looping over `changed()` always gets awakened at least once at time 0,
# to see the initial values.
if self.first_await and self.waits_on.initial_eligible():
self.waits_on.compute_result()
self.waits_on = self.coroutine.send(None)
self.first_await = False
except StopIteration:
self.critical = False
self.waits_on = None
Expand Down
10 changes: 9 additions & 1 deletion amaranth/sim/pysim.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ def activate(self):
else:
self._broken = True

def run(self):
def compute_result(self):
result = []
for trigger in self._combination._triggers:
if isinstance(trigger, (SampleTrigger, ChangedTrigger)):
Expand All @@ -570,12 +570,20 @@ def run(self):
assert False # :nocov:
self._result = tuple(result)

def run(self):
self.compute_result()
self._combination._process.runnable = True
self._combination._process.waits_on = None
self._triggers_hit.clear()
for waker, interval_fs in self._delay_wakers.items():
self._engine.state.set_delay_waker(interval_fs, waker)

def initial_eligible(self):
return not self._oneshot and any(
isinstance(trigger, ChangedTrigger)
for trigger in self._combination._triggers
)

def __await__(self):
self._result = None
if self._broken:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,22 @@ def test_comb_clock_conflict(self):
r"^Clock signal is already driven by combinational logic$"):
sim.add_clock(1e-6)

def test_initial(self):
a = Signal(4, init=3)
m = Module()
sim = Simulator(m)
fired = 0

async def process(ctx):
nonlocal fired
async for val_a, in ctx.changed(a):
self.assertEqual(val_a, 3)
fired += 1

sim.add_process(process)
sim.run()
self.assertEqual(fired, 1)

def test_sample(self):
m = Module()
m.domains.sync = cd_sync = ClockDomain()
Expand Down

0 comments on commit 3d2cd15

Please sign in to comment.