import migen in litex/gen
[litex.git] / litex / gen / migen / sim / vcd.py
1 from itertools import count
2
3 from migen.fhdl.namer import build_namespace
4
5
6 def vcd_codes():
7 codechars = [chr(i) for i in range(33, 127)]
8 for n in count():
9 q, r = divmod(n, len(codechars))
10 code = codechars[r]
11 while q > 0:
12 q, r = divmod(q, len(codechars))
13 code = codechars[r] + code
14 yield code
15
16
17 class VCDWriter:
18 def __init__(self, filename, signals):
19 self.fo = open(filename, "w")
20 self.codes = dict()
21 self.signal_values = dict()
22 self.t = 0
23
24 try:
25 ns = build_namespace(signals)
26 codes = vcd_codes()
27 for signal in signals:
28 name = ns.get_name(signal)
29 code = next(codes)
30 self.codes[signal] = code
31 self.fo.write("$var wire {len} {code} {name} $end\n"
32 .format(name=name, code=code, len=len(signal)))
33 self.fo.write("$dumpvars\n")
34 for signal in signals:
35 value = signal.reset.value
36 self._write_value(signal, value)
37 self.signal_values[signal] = value
38 self.fo.write("$end\n")
39 self.fo.write("#0\n")
40 except:
41 self.close()
42 raise
43
44 def _write_value(self, signal, value):
45 l = len(signal)
46 if value < 0:
47 value += 2**l
48 if l > 1:
49 fmtstr = "b{:0" + str(l) + "b} {}\n"
50 else:
51 fmtstr = "{}{}\n"
52 self.fo.write(fmtstr.format(value, self.codes[signal]))
53
54 def set(self, signal, value):
55 if self.signal_values[signal] != value:
56 self._write_value(signal, value)
57 self.signal_values[signal] = value
58
59 def delay(self, delay):
60 self.t += delay
61 self.fo.write("#{}\n".format(self.t))
62
63 def close(self):
64 self.fo.close()
65
66
67 class DummyVCDWriter:
68 def set(self, signal, value):
69 pass
70
71 def delay(self, delay):
72 pass
73
74 def close(self):
75 pass