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)

This commit is contained in:
Florent Kermarrec 2016-03-25 13:08:39 +01:00
parent 0ef1d44c44
commit f512971d9e
2 changed files with 35 additions and 31 deletions

View File

@ -39,7 +39,7 @@ class TimeManager:
else: else:
high = False high = False
self.clocks[k] = ClockState(high, half_period, half_period - phase) self.clocks[k] = ClockState(high, half_period, half_period - phase)
def tick(self): def tick(self):
rising = set() rising = set()
falling = set() falling = set()
@ -62,14 +62,14 @@ str2op = {
"+": operator.add, "+": operator.add,
"-": operator.sub, "-": operator.sub,
"*": operator.mul, "*": operator.mul,
">>>": operator.rshift, ">>>": operator.rshift,
"<<<": operator.lshift, "<<<": operator.lshift,
"&": operator.and_, "&": operator.and_,
"^": operator.xor, "^": operator.xor,
"|": operator.or_, "|": operator.or_,
"<": operator.lt, "<": operator.lt,
"<=": operator.le, "<=": operator.le,
"==": operator.eq, "==": operator.eq,
@ -279,6 +279,7 @@ class Simulator:
signals.add(cd.rst) signals.add(cd.rst)
for memory_array in mta.replacements.values(): for memory_array in mta.replacements.values():
signals |= set(memory_array) signals |= set(memory_array)
self.vcd.init(signals)
for signal in sorted(signals, key=lambda x: x.duid): for signal in sorted(signals, key=lambda x: x.duid):
self.vcd.set(signal, signal.reset.value) self.vcd.set(signal, signal.reset.value)

View File

@ -21,8 +21,7 @@ def vcd_codes():
class VCDWriter: class VCDWriter:
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
self.buffer_file = tempfile.TemporaryFile( self.out_file = open(self.filename, "w")
dir=os.path.dirname(filename), mode="w+")
self.codegen = vcd_codes() self.codegen = vcd_codes()
self.codes = OrderedDict() self.codes = OrderedDict()
self.signal_values = dict() self.signal_values = dict()
@ -36,45 +35,49 @@ class VCDWriter:
fmtstr = "b{:0" + str(l) + "b} {}\n" fmtstr = "b{:0" + str(l) + "b} {}\n"
else: else:
fmtstr = "{}{}\n" fmtstr = "{}{}\n"
try: code = self.codes[signal]
code = self.codes[signal]
except KeyError:
code = next(self.codegen)
self.codes[signal] = code
f.write(fmtstr.format(value, code)) 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): def set(self, signal, value):
if (signal not in self.signal_values if (signal not in self.signal_values
or self.signal_values[signal] != value): 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 self.signal_values[signal] = value
def delay(self, delay): def delay(self, delay):
self.t += delay self.t += delay
self.buffer_file.write("#{}\n".format(self.t)) self.out_file.write("#{}\n".format(self.t))
def close(self): def close(self):
out = open(self.filename, "w") self.out_file.close()
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()
class DummyVCDWriter: class DummyVCDWriter:
def init(self):
pass
def set(self, signal, value): def set(self, signal, value):
pass pass