back.pysim: wake up processes before ever committing any values.

Otherwise, the contract of the simulator to sync processes is not
always fulfilled.
This commit is contained in:
whitequark 2019-01-21 16:00:25 +00:00
parent 52a9f818f1
commit 12e04e4ee5
2 changed files with 16 additions and 8 deletions

View file

@ -638,13 +638,6 @@ class Simulator:
while curr_domains: while curr_domains:
domain = curr_domains.pop() domain = curr_domains.pop()
# Take the computed value (at the start of this delta cycle) of every sync signal
# in this domain and update the value for this delta cycle. This can trigger more
# synchronous logic, so record that.
for signal_slot in self._state.iter_next_dirty():
if self._domain_signals[domain][signal_slot]:
self._commit_signal(signal_slot, domains)
# Wake up any simulator processes that wait for a domain tick. # Wake up any simulator processes that wait for a domain tick.
for process, wait_domain in list(self._wait_tick.items()): for process, wait_domain in list(self._wait_tick.items()):
if domain == wait_domain: if domain == wait_domain:
@ -658,6 +651,13 @@ class Simulator:
# values from the previous clock cycle on a tick, too. # values from the previous clock cycle on a tick, too.
self._run_process(process) self._run_process(process)
# Take the computed value (at the start of this delta cycle) of every sync signal
# in this domain and update the value for this delta cycle. This can trigger more
# synchronous logic, so record that.
for signal_slot in self._state.iter_next_dirty():
if self._domain_signals[domain][signal_slot]:
self._commit_signal(signal_slot, domains)
# Unless handling synchronous logic above has triggered more synchronous logic (which # Unless handling synchronous logic above has triggered more synchronous logic (which
# can happen e.g. if a domain is clocked off a clock divisor in fabric), we're done. # can happen e.g. if a domain is clocked off a clock divisor in fabric), we're done.
# Otherwise, do one more round of updates. # Otherwise, do one more round of updates.

View file

@ -282,6 +282,9 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
self.assertEqual((yield self.count), 4) self.assertEqual((yield self.count), 4)
self.assertEqual((yield self.sync.clk), 0) self.assertEqual((yield self.sync.clk), 0)
yield yield
self.assertEqual((yield self.count), 4)
self.assertEqual((yield self.sync.clk), 1)
yield
self.assertEqual((yield self.count), 5) self.assertEqual((yield self.count), 5)
self.assertEqual((yield self.sync.clk), 1) self.assertEqual((yield self.sync.clk), 1)
for _ in range(3): for _ in range(3):
@ -317,12 +320,15 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
yield self.b.eq(1) yield self.b.eq(1)
yield yield
self.assertEqual((yield self.x), 4) self.assertEqual((yield self.x), 4)
yield
self.assertEqual((yield self.o), 6) self.assertEqual((yield self.o), 6)
yield self.s.eq(1) yield self.s.eq(1)
yield yield
yield
self.assertEqual((yield self.o), 4) self.assertEqual((yield self.o), 4)
yield self.s.eq(2) yield self.s.eq(2)
yield yield
yield
self.assertEqual((yield self.o), 0) self.assertEqual((yield self.o), 0)
sim.add_sync_process(process) sim.add_sync_process(process)
@ -487,9 +493,11 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
yield self.wrport.en.eq(1) yield self.wrport.en.eq(1)
yield self.rdport.en.eq(1) yield self.rdport.en.eq(1)
yield yield
self.assertEqual((yield self.rdport.data), 0x00)
yield
self.assertEqual((yield self.rdport.data), 0xaa) self.assertEqual((yield self.rdport.data), 0xaa)
yield Delay(1e-6) # let comb propagate yield Delay(1e-6) # let comb propagate
self.assertEqual((yield self.rdport.data), 0xaa) self.assertEqual((yield self.rdport.data), 0x33)
sim.add_clock(1e-6) sim.add_clock(1e-6)
sim.add_sync_process(process) sim.add_sync_process(process)