From f512971d9e84ea56b39a87bf0621e5a347048c21 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 25 Mar 2016 13:08:39 +0100 Subject: [PATCH] gen/sim: hack to update vcd output file during simulation (allow visualizing progress directly and having a vcd file even when simulation fails or doesn't stop) --- litex/gen/sim/core.py | 9 ++++--- litex/gen/sim/vcd.py | 57 +++++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/litex/gen/sim/core.py b/litex/gen/sim/core.py index d9b7adf2..e408f997 100644 --- a/litex/gen/sim/core.py +++ b/litex/gen/sim/core.py @@ -39,7 +39,7 @@ class TimeManager: else: high = False self.clocks[k] = ClockState(high, half_period, half_period - phase) - + def tick(self): rising = set() falling = set() @@ -62,14 +62,14 @@ str2op = { "+": operator.add, "-": operator.sub, "*": operator.mul, - + ">>>": operator.rshift, "<<<": operator.lshift, - + "&": operator.and_, "^": operator.xor, "|": operator.or_, - + "<": operator.lt, "<=": operator.le, "==": operator.eq, @@ -279,6 +279,7 @@ class Simulator: signals.add(cd.rst) for memory_array in mta.replacements.values(): signals |= set(memory_array) + self.vcd.init(signals) for signal in sorted(signals, key=lambda x: x.duid): self.vcd.set(signal, signal.reset.value) diff --git a/litex/gen/sim/vcd.py b/litex/gen/sim/vcd.py index 85482f51..bef43e28 100644 --- a/litex/gen/sim/vcd.py +++ b/litex/gen/sim/vcd.py @@ -21,8 +21,7 @@ def vcd_codes(): class VCDWriter: def __init__(self, filename): self.filename = filename - self.buffer_file = tempfile.TemporaryFile( - dir=os.path.dirname(filename), mode="w+") + self.out_file = open(self.filename, "w") self.codegen = vcd_codes() self.codes = OrderedDict() self.signal_values = dict() @@ -36,45 +35,49 @@ class VCDWriter: fmtstr = "b{:0" + str(l) + "b} {}\n" else: fmtstr = "{}{}\n" - try: - code = self.codes[signal] - except KeyError: - code = next(self.codegen) - self.codes[signal] = code + code = self.codes[signal] f.write(fmtstr.format(value, code)) + def init(self, signals): + # generate codes + for signal in signals: + try: + code = self.codes[signal] + except KeyError: + code = next(self.codegen) + self.codes[signal] = code + + # write vcd header + out = self.out_file + ns = build_namespace(self.codes.keys()) + for signal, code in self.codes.items(): + name = ns.get_name(signal) + out.write("$var wire {len} {code} {name} $end\n" + .format(name=name, code=code, len=len(signal))) + out.write("$dumpvars\n") + for signal in self.codes.keys(): + self._write_value(out, signal, signal.reset.value) + out.write("$end\n") + out.write("#0\n") + def set(self, signal, value): if (signal not in self.signal_values or self.signal_values[signal] != value): - self._write_value(self.buffer_file, signal, value) + self._write_value(self.out_file, signal, value) self.signal_values[signal] = value def delay(self, delay): self.t += delay - self.buffer_file.write("#{}\n".format(self.t)) + self.out_file.write("#{}\n".format(self.t)) def close(self): - out = open(self.filename, "w") - try: - ns = build_namespace(self.codes.keys()) - for signal, code in self.codes.items(): - name = ns.get_name(signal) - out.write("$var wire {len} {code} {name} $end\n" - .format(name=name, code=code, len=len(signal))) - out.write("$dumpvars\n") - for signal in self.codes.keys(): - self._write_value(out, signal, signal.reset.value) - out.write("$end\n") - out.write("#0\n") - - self.buffer_file.seek(0) - shutil.copyfileobj(self.buffer_file, out) - self.buffer_file.close() - finally: - out.close() + self.out_file.close() class DummyVCDWriter: + def init(self): + pass + def set(self, signal, value): pass -- 2.30.2