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:
parent
0ef1d44c44
commit
f512971d9e
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue