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:
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.
for process, wait_domain in list(self._wait_tick.items()):
if domain == wait_domain:
@ -658,6 +651,13 @@ class Simulator:
# values from the previous clock cycle on a tick, too.
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
# 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.

View file

@ -282,6 +282,9 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
self.assertEqual((yield self.count), 4)
self.assertEqual((yield self.sync.clk), 0)
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.sync.clk), 1)
for _ in range(3):
@ -317,12 +320,15 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
yield self.b.eq(1)
yield
self.assertEqual((yield self.x), 4)
yield
self.assertEqual((yield self.o), 6)
yield self.s.eq(1)
yield
yield
self.assertEqual((yield self.o), 4)
yield self.s.eq(2)
yield
yield
self.assertEqual((yield self.o), 0)
sim.add_sync_process(process)
@ -487,9 +493,11 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
yield self.wrport.en.eq(1)
yield self.rdport.en.eq(1)
yield
self.assertEqual((yield self.rdport.data), 0x00)
yield
self.assertEqual((yield self.rdport.data), 0xaa)
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_sync_process(process)