From: Florent Kermarrec Date: Sat, 28 May 2016 08:25:48 +0000 (+0200) Subject: gen/sim/vcd: allow continous update of vcd file and dynamic signals X-Git-Tag: 24jan2021_ls180~1940 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a35337a095eb023190f99cf82510b43634102c5;p=litex.git gen/sim/vcd: allow continous update of vcd file and dynamic signals With continous update, VCD header needs to be writen at the beginning of the simulation. When a new signal is created, we rewrite the header and the content. --- diff --git a/litex/gen/sim/vcd.py b/litex/gen/sim/vcd.py index bef43e28..db369a6d 100644 --- a/litex/gen/sim/vcd.py +++ b/litex/gen/sim/vcd.py @@ -21,13 +21,16 @@ def vcd_codes(): class VCDWriter: def __init__(self, filename): self.filename = filename - self.out_file = open(self.filename, "w") + self.out_file = None + self.buffer_file = tempfile.TemporaryFile( + dir=os.path.dirname(filename), mode="w+") + self.initialized = False self.codegen = vcd_codes() self.codes = OrderedDict() self.signal_values = dict() self.t = 0 - def _write_value(self, f, signal, value): + def _write_value(self, signal, value): l = len(signal) if value < 0: value += 2**l @@ -35,10 +38,22 @@ class VCDWriter: fmtstr = "b{:0" + str(l) + "b} {}\n" else: fmtstr = "{}{}\n" - code = self.codes[signal] - f.write(fmtstr.format(value, code)) + try: + code = self.codes[signal] + except KeyError: + code = next(self.codegen) + self.codes[signal] = code + self.init(self.codes.keys()) + + return fmtstr.format(value, code) + + def _write(self, s): + self.out_file.write(s) + self.buffer_file.write(s) def init(self, signals): + self.out_file = open(self.filename, "w") + # generate codes for signal in signals: try: @@ -48,30 +63,40 @@ class VCDWriter: self.codes[signal] = code # write vcd header - out = self.out_file + header = "" 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") + header += "$var wire {len} {code} {name} $end\n".format(name=name, code=code, len=len(signal)) + header += "$dumpvars\n" for signal in self.codes.keys(): - self._write_value(out, signal, signal.reset.value) - out.write("$end\n") - out.write("#0\n") + header += self._write_value(signal, signal.reset.value) + header += "$end\n" + self.out_file.write(header) + + if self.initialized: + self.buffer_file.seek(0) + shutil.copyfileobj(self.buffer_file, self.out_file) + self.buffer_file.seek(0, 2) + else: + # init time + self._write("#0\n") + + self.initialized = True def set(self, signal, value): if (signal not in self.signal_values or self.signal_values[signal] != value): - self._write_value(self.out_file, signal, value) + self._write(self._write_value(signal, value)) self.signal_values[signal] = value def delay(self, delay): self.t += delay - self.out_file.write("#{}\n".format(self.t)) + self._write("#{}\n".format(self.t)) def close(self): self.out_file.close() + self.buffer_file.close() class DummyVCDWriter: