From: whitequark Date: Tue, 7 Jul 2020 04:06:06 +0000 (+0000) Subject: back.pysim: synchronize waveform writing with cxxrtl. X-Git-Tag: 24jan2021_ls180~32 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2efeb05c;p=nmigen.git back.pysim: synchronize waveform writing with cxxrtl. --- diff --git a/nmigen/back/pysim.py b/nmigen/back/pysim.py index 9524399..98b36b8 100644 --- a/nmigen/back/pysim.py +++ b/nmigen/back/pysim.py @@ -222,8 +222,6 @@ class _SimulatorState: self.timestamp = 0.0 self.deadlines = dict() - self.waveform_writer = None - def reset(self): for signal, index in self.signals.items(): self.slots[index].curr = self.slots[index].next = signal.reset @@ -258,9 +256,6 @@ class _SimulatorState: if signal_state.commit(): if signal_state.wakeup(): converged = False - if self.waveform_writer is not None: - self.waveform_writer.update(self.timestamp, - signal_state.signal, signal_state.curr) self.pending.clear() return converged @@ -882,27 +877,22 @@ class _CoroutineProcess(_Process): class _WaveformContextManager: - def __init__(self, state, waveform_writer): - self._state = state + def __init__(self, simulator, waveform_writer): + self._simulator = simulator self._waveform_writer = waveform_writer def __enter__(self): try: - if self._state.timestamp != 0.0: + if self._simulator._state.timestamp != 0.0: raise ValueError("Cannot start writing waveforms after advancing simulation time") - if self._state.waveform_writer is not None: - raise ValueError("Already writing waveforms to {!r}" - .format(self._state.waveform_writer)) - self._state.waveform_writer = self._waveform_writer + self._simulator._waveform_writers.append(self._waveform_writer) except: self._waveform_writer.close(0) raise def __exit__(self, *args): - if self._state.waveform_writer is None: - return - self._state.waveform_writer.close(self._state.timestamp) - self._state.waveform_writer = None + self._waveform_writer.close(self._simulator._state.timestamp) + self._simulator._waveform_writers.remove(self._waveform_writer) class Simulator: @@ -912,6 +902,7 @@ class Simulator: self._fragment = Fragment.get(fragment, platform=None).prepare() self._processes = _FragmentCompiler(self._state, self._signal_names)(self._fragment) self._clocked = set() + self._waveform_writers = [] def _check_process(self, process): if not (inspect.isgeneratorfunction(process) or inspect.iscoroutinefunction(process)): @@ -1021,6 +1012,11 @@ class Simulator: process.runnable = False 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 converged = self._state.commit() @@ -1086,4 +1082,4 @@ class Simulator: """ waveform_writer = _VCDWaveformWriter(self._signal_names, vcd_file=vcd_file, gtkw_file=gtkw_file, traces=traces) - return _WaveformContextManager(self._state, waveform_writer) + return _WaveformContextManager(self, waveform_writer) diff --git a/nmigen/test/test_sim.py b/nmigen/test/test_sim.py index adc6c26..bff3051 100644 --- a/nmigen/test/test_sim.py +++ b/nmigen/test/test_sim.py @@ -777,18 +777,6 @@ class SimulatorIntegrationTestCase(FHDLTestCase): with sim.write_vcd(open(os.path.devnull, "wt")): 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): def test_bug_325(self):