back.pysim: synchronize waveform writing with cxxrtl.

This commit is contained in:
whitequark 2020-07-07 04:06:06 +00:00
parent e012e62ade
commit 2efeb05c63
2 changed files with 13 additions and 29 deletions

View file

@ -222,8 +222,6 @@ class _SimulatorState:
self.timestamp = 0.0 self.timestamp = 0.0
self.deadlines = dict() self.deadlines = dict()
self.waveform_writer = None
def reset(self): def reset(self):
for signal, index in self.signals.items(): for signal, index in self.signals.items():
self.slots[index].curr = self.slots[index].next = signal.reset self.slots[index].curr = self.slots[index].next = signal.reset
@ -258,9 +256,6 @@ class _SimulatorState:
if signal_state.commit(): if signal_state.commit():
if signal_state.wakeup(): if signal_state.wakeup():
converged = False converged = False
if self.waveform_writer is not None:
self.waveform_writer.update(self.timestamp,
signal_state.signal, signal_state.curr)
self.pending.clear() self.pending.clear()
return converged return converged
@ -882,27 +877,22 @@ class _CoroutineProcess(_Process):
class _WaveformContextManager: class _WaveformContextManager:
def __init__(self, state, waveform_writer): def __init__(self, simulator, waveform_writer):
self._state = state self._simulator = simulator
self._waveform_writer = waveform_writer self._waveform_writer = waveform_writer
def __enter__(self): def __enter__(self):
try: try:
if self._state.timestamp != 0.0: if self._simulator._state.timestamp != 0.0:
raise ValueError("Cannot start writing waveforms after advancing simulation time") raise ValueError("Cannot start writing waveforms after advancing simulation time")
if self._state.waveform_writer is not None: self._simulator._waveform_writers.append(self._waveform_writer)
raise ValueError("Already writing waveforms to {!r}"
.format(self._state.waveform_writer))
self._state.waveform_writer = self._waveform_writer
except: except:
self._waveform_writer.close(0) self._waveform_writer.close(0)
raise raise
def __exit__(self, *args): def __exit__(self, *args):
if self._state.waveform_writer is None: self._waveform_writer.close(self._simulator._state.timestamp)
return self._simulator._waveform_writers.remove(self._waveform_writer)
self._state.waveform_writer.close(self._state.timestamp)
self._state.waveform_writer = None
class Simulator: class Simulator:
@ -912,6 +902,7 @@ class Simulator:
self._fragment = Fragment.get(fragment, platform=None).prepare() self._fragment = Fragment.get(fragment, platform=None).prepare()
self._processes = _FragmentCompiler(self._state, self._signal_names)(self._fragment) self._processes = _FragmentCompiler(self._state, self._signal_names)(self._fragment)
self._clocked = set() self._clocked = set()
self._waveform_writers = []
def _check_process(self, process): def _check_process(self, process):
if not (inspect.isgeneratorfunction(process) or inspect.iscoroutinefunction(process)): if not (inspect.isgeneratorfunction(process) or inspect.iscoroutinefunction(process)):
@ -1021,6 +1012,11 @@ class Simulator:
process.runnable = False process.runnable = False
process.run() process.run()
for waveform_writer in self._waveform_writers:
for signal_state in self._state.pending:
waveform_writer.update(self._state.timestamp,
signal_state.signal, signal_state.curr)
# 2. commit: apply every queued signal change, waking up any waiting processes # 2. commit: apply every queued signal change, waking up any waiting processes
converged = self._state.commit() converged = self._state.commit()
@ -1086,4 +1082,4 @@ class Simulator:
""" """
waveform_writer = _VCDWaveformWriter(self._signal_names, waveform_writer = _VCDWaveformWriter(self._signal_names,
vcd_file=vcd_file, gtkw_file=gtkw_file, traces=traces) vcd_file=vcd_file, gtkw_file=gtkw_file, traces=traces)
return _WaveformContextManager(self._state, waveform_writer) return _WaveformContextManager(self, waveform_writer)

View file

@ -777,18 +777,6 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
with sim.write_vcd(open(os.path.devnull, "wt")): with sim.write_vcd(open(os.path.devnull, "wt")):
pass pass
def test_vcd_wrong_twice(self):
s = Signal()
m = Module()
m.d.sync += s.eq(s)
sim = Simulator(m)
sim.add_clock(1e-6)
with self.assertRaisesRegex(ValueError,
r"^Already writing waveforms to .+$"):
with sim.write_vcd(open(os.path.devnull, "wt")):
with sim.write_vcd(open(os.path.devnull, "wt")):
pass
class SimulatorRegressionTestCase(FHDLTestCase): class SimulatorRegressionTestCase(FHDLTestCase):
def test_bug_325(self): def test_bug_325(self):