sim: awaken all processes waiting on changed()
at time 0.
This commit is contained in:
parent
f3bcdf4782
commit
3d2cd15435
|
@ -749,10 +749,18 @@ class AsyncProcess(BaseProcess):
|
|||
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
|
||||
|
|
|
@ -555,7 +555,7 @@ class _PyTriggerState:
|
|||
else:
|
||||
self._broken = True
|
||||
|
||||
def run(self):
|
||||
def compute_result(self):
|
||||
result = []
|
||||
for trigger in self._combination._triggers:
|
||||
if isinstance(trigger, (SampleTrigger, ChangedTrigger)):
|
||||
|
@ -570,12 +570,20 @@ class _PyTriggerState:
|
|||
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:
|
||||
|
|
|
@ -1506,6 +1506,22 @@ class SimulatorRegressionTestCase(FHDLTestCase):
|
|||
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()
|
||||
|
|
Loading…
Reference in a new issue