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