gen/sim/vcd: allow continous update of vcd file and dynamic signals
[litex.git] / litex / gen / fhdl / structure.py
1 import builtins as _builtins
2 import collections as _collections
3
4 from litex.gen.fhdl import tracer as _tracer
5 from litex.gen.util.misc import flat_iteration as _flat_iteration
6
7
8 class DUID:
9 """Deterministic Unique IDentifier"""
10 __next_uid = 0
11 def __init__(self):
12 self.duid = DUID.__next_uid
13 DUID.__next_uid += 1
14
15
16 class _Value(DUID):
17 """Base class for operands
18
19 Instances of `_Value` or its subclasses can be operands to
20 arithmetic, comparison, bitwise, and logic operators.
21 They can be assigned (:meth:`eq`) or indexed/sliced (using the usual
22 Python indexing and slicing notation).
23
24 Values created from integers have the minimum bit width to necessary to
25 represent the integer.
26 """
27 def __bool__(self):
28 # Special case: Constants and Signals are part of a set or used as
29 # dictionary keys, and Python needs to check for equality.
30 if isinstance(self, _Operator) and self.op == "==":
31 a, b = self.operands
32 if isinstance(a, Constant) and isinstance(b, Constant):
33 return a.value == b.value
34 if isinstance(a, Signal) and isinstance(b, Signal):
35 return a is b
36 if (isinstance(a, Constant) and isinstance(b, Signal)
37 or isinstance(a, Signal) and isinstance(b, Constant)):
38 return False
39 raise TypeError("Attempted to convert Migen value to boolean")
40
41 def __invert__(self):
42 return _Operator("~", [self])
43 def __neg__(self):
44 return _Operator("-", [self])
45
46 def __add__(self, other):
47 return _Operator("+", [self, other])
48 def __radd__(self, other):
49 return _Operator("+", [other, self])
50 def __sub__(self, other):
51 return _Operator("-", [self, other])
52 def __rsub__(self, other):
53 return _Operator("-", [other, self])
54 def __mul__(self, other):
55 return _Operator("*", [self, other])
56 def __rmul__(self, other):
57 return _Operator("*", [other, self])
58 def __lshift__(self, other):
59 return _Operator("<<<", [self, other])
60 def __rlshift__(self, other):
61 return _Operator("<<<", [other, self])
62 def __rshift__(self, other):
63 return _Operator(">>>", [self, other])
64 def __rrshift__(self, other):
65 return _Operator(">>>", [other, self])
66 def __and__(self, other):
67 return _Operator("&", [self, other])
68 def __rand__(self, other):
69 return _Operator("&", [other, self])
70 def __xor__(self, other):
71 return _Operator("^", [self, other])
72 def __rxor__(self, other):
73 return _Operator("^", [other, self])
74 def __or__(self, other):
75 return _Operator("|", [self, other])
76 def __ror__(self, other):
77 return _Operator("|", [other, self])
78
79 def __lt__(self, other):
80 return _Operator("<", [self, other])
81 def __le__(self, other):
82 return _Operator("<=", [self, other])
83 def __eq__(self, other):
84 return _Operator("==", [self, other])
85 def __ne__(self, other):
86 return _Operator("!=", [self, other])
87 def __gt__(self, other):
88 return _Operator(">", [self, other])
89 def __ge__(self, other):
90 return _Operator(">=", [self, other])
91
92 def __len__(self):
93 from litex.gen.fhdl.bitcontainer import value_bits_sign
94 return value_bits_sign(self)[0]
95
96 def __getitem__(self, key):
97 n = len(self)
98 if isinstance(key, int):
99 if key >= n:
100 raise IndexError
101 if key < 0:
102 key += n
103 return _Slice(self, key, key+1)
104 elif isinstance(key, slice):
105 start, stop, step = key.indices(n)
106 if step != 1:
107 return Cat(self[i] for i in range(start, stop, step))
108 return _Slice(self, start, stop)
109 else:
110 raise TypeError("Cannot use type {} ({}) as key".format(
111 type(key), repr(key)))
112
113 def eq(self, r):
114 """Assignment
115
116 Parameters
117 ----------
118 r : _Value, in
119 Value to be assigned.
120
121 Returns
122 -------
123 _Assign
124 Assignment statement that can be used in combinatorial or
125 synchronous context.
126 """
127 return _Assign(self, r)
128
129 def __hash__(self):
130 raise TypeError("unhashable type: '{}'".format(type(self).__name__))
131
132
133 def wrap(value):
134 """Ensures that the passed object is a Migen value. Booleans and integers
135 are automatically wrapped into ``Constant``."""
136 if isinstance(value, (bool, int)):
137 value = Constant(value)
138 if not isinstance(value, _Value):
139 raise TypeError("Object is not a Migen value")
140 return value
141
142
143 class _Operator(_Value):
144 def __init__(self, op, operands):
145 _Value.__init__(self)
146 self.op = op
147 self.operands = [wrap(o) for o in operands]
148
149
150 def Mux(sel, val1, val0):
151 """Multiplex between two values
152
153 Parameters
154 ----------
155 sel : _Value(1), in
156 Selector.
157 val1 : _Value(N), in
158 val0 : _Value(N), in
159 Input values.
160
161 Returns
162 -------
163 _Value(N), out
164 Output `_Value`. If `sel` is asserted, the Mux returns
165 `val1`, else `val0`.
166 """
167 return _Operator("m", [sel, val1, val0])
168
169
170 class _Slice(_Value):
171 def __init__(self, value, start, stop):
172 _Value.__init__(self)
173 if not isinstance(start, int) or not isinstance(stop, int):
174 raise TypeError("Slice boundaries must be integers")
175 self.value = wrap(value)
176 self.start = start
177 self.stop = stop
178
179
180 class Cat(_Value):
181 """Concatenate values
182
183 Form a compound `_Value` from several smaller ones by concatenation.
184 The first argument occupies the lower bits of the result.
185 The return value can be used on either side of an assignment, that
186 is, the concatenated value can be used as an argument on the RHS or
187 as a target on the LHS. If it is used on the LHS, it must solely
188 consist of `Signal` s, slices of `Signal` s, and other concatenations
189 meeting these properties. The bit length of the return value is the sum of
190 the bit lengths of the arguments::
191
192 len(Cat(args)) == sum(len(arg) for arg in args)
193
194 Parameters
195 ----------
196 *args : _Values or iterables of _Values, inout
197 `_Value` s to be concatenated.
198
199 Returns
200 -------
201 Cat, inout
202 Resulting `_Value` obtained by concatentation.
203 """
204 def __init__(self, *args):
205 _Value.__init__(self)
206 self.l = [wrap(v) for v in _flat_iteration(args)]
207
208
209 class Replicate(_Value):
210 """Replicate a value
211
212 An input value is replicated (repeated) several times
213 to be used on the RHS of assignments::
214
215 len(Replicate(s, n)) == len(s)*n
216
217 Parameters
218 ----------
219 v : _Value, in
220 Input value to be replicated.
221 n : int
222 Number of replications.
223
224 Returns
225 -------
226 Replicate, out
227 Replicated value.
228 """
229 def __init__(self, v, n):
230 _Value.__init__(self)
231 if not isinstance(n, int) or n < 0:
232 raise TypeError("Replication count must be a positive integer")
233 self.v = wrap(v)
234 self.n = n
235
236
237 class Constant(_Value):
238 """A constant, HDL-literal integer `_Value`
239
240 Parameters
241 ----------
242 value : int
243 bits_sign : int or tuple or None
244 Either an integer `bits` or a tuple `(bits, signed)`
245 specifying the number of bits in this `Constant` and whether it is
246 signed (can represent negative values). `bits_sign` defaults
247 to the minimum width and signedness of `value`.
248 """
249 def __init__(self, value, bits_sign=None):
250 from litex.gen.fhdl.bitcontainer import bits_for
251
252 _Value.__init__(self)
253
254 self.value = int(value)
255 if bits_sign is None:
256 bits_sign = bits_for(self.value), self.value < 0
257 elif isinstance(bits_sign, int):
258 bits_sign = bits_sign, self.value < 0
259 self.nbits, self.signed = bits_sign
260 if not isinstance(self.nbits, int) or self.nbits <= 0:
261 raise TypeError("Width must be a strictly positive integer")
262
263 def __hash__(self):
264 return self.value
265
266
267 C = Constant # shorthand
268
269
270 class Signal(_Value):
271 """A `_Value` that can change
272
273 The `Signal` object represents a value that is expected to change
274 in the circuit. It does exactly what Verilog's `wire` and
275 `reg` and VHDL's `signal` do.
276
277 A `Signal` can be indexed to access a subset of its bits. Negative
278 indices (`signal[-1]`) and the extended Python slicing notation
279 (`signal[start:stop:step]`) are supported.
280 The indices 0 and -1 are the least and most significant bits
281 respectively.
282
283 Parameters
284 ----------
285 bits_sign : int or tuple
286 Either an integer `bits` or a tuple `(bits, signed)`
287 specifying the number of bits in this `Signal` and whether it is
288 signed (can represent negative values). `signed` defaults to
289 `False`.
290 name : str or None
291 Name hint for this signal. If `None` (default) the name is
292 inferred from the variable name this `Signal` is assigned to.
293 Name collisions are automatically resolved by prepending
294 names of objects that contain this `Signal` and by
295 appending integer sequences.
296 variable : bool
297 Deprecated.
298 reset : int
299 Reset (synchronous) or default (combinatorial) value.
300 When this `Signal` is assigned to in synchronous context and the
301 corresponding clock domain is reset, the `Signal` assumes the
302 given value. When this `Signal` is unassigned in combinatorial
303 context (due to conditional assignments not being taken),
304 the `Signal` assumes its `reset` value. Defaults to 0.
305 name_override : str or None
306 Do not use the inferred name but the given one.
307 min : int or None
308 max : int or None
309 If `bits_sign` is `None`, the signal bit width and signedness are
310 determined by the integer range given by `min` (inclusive,
311 defaults to 0) and `max` (exclusive, defaults to 2).
312 related : Signal or None
313 """
314 def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None, attribute=""):
315 from litex.gen.fhdl.bitcontainer import bits_for
316
317 _Value.__init__(self)
318
319 # determine number of bits and signedness
320 if bits_sign is None:
321 if min is None:
322 min = 0
323 if max is None:
324 max = 2
325 max -= 1 # make both bounds inclusive
326 assert(min < max)
327 self.signed = min < 0 or max < 0
328 self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed))
329 else:
330 assert(min is None and max is None)
331 if isinstance(bits_sign, tuple):
332 self.nbits, self.signed = bits_sign
333 else:
334 self.nbits, self.signed = bits_sign, False
335 if not isinstance(self.nbits, int) or self.nbits <= 0:
336 raise ValueError("Signal width must be a strictly positive integer")
337
338 self.variable = variable # deprecated
339 self.reset = reset
340 self.name_override = name_override
341 self.backtrace = _tracer.trace_back(name)
342 self.related = related
343 self.attribute = attribute
344
345 def __setattr__(self, k, v):
346 if k == "reset":
347 v = wrap(v)
348 _Value.__setattr__(self, k, v)
349
350 def __repr__(self):
351 return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
352
353 @classmethod
354 def like(cls, other, **kwargs):
355 """Create Signal based on another.
356
357 Parameters
358 ----------
359 other : _Value
360 Object to base this Signal on.
361
362 See `migen.fhdl.bitcontainer.value_bits_sign` for details.
363 """
364 from litex.gen.fhdl.bitcontainer import value_bits_sign
365 return cls(bits_sign=value_bits_sign(other), **kwargs)
366
367 def __hash__(self):
368 return self.duid
369
370
371 class ClockSignal(_Value):
372 """Clock signal for a given clock domain
373
374 `ClockSignal` s for a given clock domain can be retrieved multiple
375 times. They all ultimately refer to the same signal.
376
377 Parameters
378 ----------
379 cd : str
380 Clock domain to obtain a clock signal for. Defaults to `"sys"`.
381 """
382 def __init__(self, cd="sys"):
383 _Value.__init__(self)
384 if not isinstance(cd, str):
385 raise TypeError("Argument of ClockSignal must be a string")
386 self.cd = cd
387
388
389 class ResetSignal(_Value):
390 """Reset signal for a given clock domain
391
392 `ResetSignal` s for a given clock domain can be retrieved multiple
393 times. They all ultimately refer to the same signal.
394
395 Parameters
396 ----------
397 cd : str
398 Clock domain to obtain a reset signal for. Defaults to `"sys"`.
399 allow_reset_less : bool
400 If the clock domain is resetless, return 0 instead of reporting an
401 error.
402 """
403 def __init__(self, cd="sys", allow_reset_less=False):
404 _Value.__init__(self)
405 if not isinstance(cd, str):
406 raise TypeError("Argument of ResetSignal must be a string")
407 self.cd = cd
408 self.allow_reset_less = allow_reset_less
409
410
411 # statements
412
413
414 class _Statement:
415 pass
416
417
418 class _Assign(_Statement):
419 def __init__(self, l, r):
420 self.l = wrap(l)
421 self.r = wrap(r)
422
423
424 def _check_statement(s):
425 if isinstance(s, _collections.Iterable):
426 return all(_check_statement(ss) for ss in s)
427 else:
428 return isinstance(s, _Statement)
429
430
431 class If(_Statement):
432 """Conditional execution of statements
433
434 Parameters
435 ----------
436 cond : _Value(1), in
437 Condition
438 *t : Statements
439 Statements to execute if `cond` is asserted.
440
441 Examples
442 --------
443 >>> a = Signal()
444 >>> b = Signal()
445 >>> c = Signal()
446 >>> d = Signal()
447 >>> If(a,
448 ... b.eq(1)
449 ... ).Elif(c,
450 ... b.eq(0)
451 ... ).Else(
452 ... b.eq(d)
453 ... )
454 """
455 def __init__(self, cond, *t):
456 if not _check_statement(t):
457 raise TypeError("Not all test body objects are Migen statements")
458 self.cond = wrap(cond)
459 self.t = list(t)
460 self.f = []
461
462 def Else(self, *f):
463 """Add an `else` conditional block
464
465 Parameters
466 ----------
467 *f : Statements
468 Statements to execute if all previous conditions fail.
469 """
470 if not _check_statement(f):
471 raise TypeError("Not all test body objects are Migen statements")
472 _insert_else(self, list(f))
473 return self
474
475 def Elif(self, cond, *t):
476 """Add an `else if` conditional block
477
478 Parameters
479 ----------
480 cond : _Value(1), in
481 Condition
482 *t : Statements
483 Statements to execute if previous conditions fail and `cond`
484 is asserted.
485 """
486 _insert_else(self, [If(cond, *t)])
487 return self
488
489
490 def _insert_else(obj, clause):
491 o = obj
492 while o.f:
493 assert(len(o.f) == 1)
494 assert(isinstance(o.f[0], If))
495 o = o.f[0]
496 o.f = clause
497
498
499 class Case(_Statement):
500 """Case/Switch statement
501
502 Parameters
503 ----------
504 test : _Value, in
505 Selector value used to decide which block to execute
506 cases : dict
507 Dictionary of cases. The keys are numeric constants to compare
508 with `test`. The values are statements to be executed the
509 corresponding key matches `test`. The dictionary may contain a
510 string key `"default"` to mark a fall-through case that is
511 executed if no other key matches.
512
513 Examples
514 --------
515 >>> a = Signal()
516 >>> b = Signal()
517 >>> Case(a, {
518 ... 0: b.eq(1),
519 ... 1: b.eq(0),
520 ... "default": b.eq(0),
521 ... })
522 """
523 def __init__(self, test, cases):
524 self.test = wrap(test)
525 self.cases = dict()
526 for k, v in cases.items():
527 if isinstance(k, (bool, int)):
528 k = Constant(k)
529 if (not isinstance(k, Constant)
530 and not (isinstance(k, str) and k == "default")):
531 raise TypeError("Case object is not a Migen constant")
532 if not isinstance(v, _collections.Iterable):
533 v = [v]
534 if not _check_statement(v):
535 raise TypeError("Not all objects for case {} "
536 "are Migen statements".format(k))
537 self.cases[k] = v
538
539 def makedefault(self, key=None):
540 """Mark a key as the default case
541
542 Deletes/substitutes any previously existing default case.
543
544 Parameters
545 ----------
546 key : int, Constant or None
547 Key to use as default case if no other key matches.
548 By default, the largest key is the default key.
549 """
550 if key is None:
551 for choice in self.cases.keys():
552 if (key is None
553 or (isinstance(choice, str) and choice == "default")
554 or choice.value > key.value):
555 key = choice
556 if not isinstance(key, str) or key != "default":
557 key = wrap(key)
558 stmts = self.cases[key]
559 del self.cases[key]
560 self.cases["default"] = stmts
561 return self
562
563
564 # arrays
565
566
567 class _ArrayProxy(_Value):
568 def __init__(self, choices, key):
569 _Value.__init__(self)
570 self.choices = []
571 for c in choices:
572 if isinstance(c, (bool, int)):
573 c = Constant(c)
574 self.choices.append(c)
575 self.key = key
576
577 def __getattr__(self, attr):
578 return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
579 self.key)
580
581 def __getitem__(self, key):
582 return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
583 self.key)
584
585
586 class Array(list):
587 """Addressable multiplexer
588
589 An array is created from an iterable of values and indexed using the
590 usual Python simple indexing notation (no negative indices or
591 slices). It can be indexed by numeric constants, `_Value` s, or
592 `Signal` s.
593
594 The result of indexing the array is a proxy for the entry at the
595 given index that can be used on either RHS or LHS of assignments.
596
597 An array can be indexed multiple times.
598
599 Multidimensional arrays are supported by packing inner arrays into
600 outer arrays.
601
602 Parameters
603 ----------
604 values : iterable of ints, _Values, Signals
605 Entries of the array. Each entry can be a numeric constant, a
606 `Signal` or a `Record`.
607
608 Examples
609 --------
610 >>> a = Array(range(10))
611 >>> b = Signal(max=10)
612 >>> c = Signal(max=10)
613 >>> b.eq(a[9 - c])
614 """
615 def __getitem__(self, key):
616 if isinstance(key, Constant):
617 return list.__getitem__(self, key.value)
618 elif isinstance(key, _Value):
619 return _ArrayProxy(self, key)
620 else:
621 return list.__getitem__(self, key)
622
623
624 class ClockDomain:
625 """Synchronous domain
626
627 Parameters
628 ----------
629 name : str or None
630 Domain name. If None (the default) the name is inferred from the
631 variable name this `ClockDomain` is assigned to (stripping any
632 `"cd_"` prefix).
633 reset_less : bool
634 The domain does not use a reset signal. Registers within this
635 domain are still all initialized to their reset state once, e.g.
636 through Verilog `"initial"` statements.
637
638 Attributes
639 ----------
640 clk : Signal, inout
641 The clock for this domain. Can be driven or used to drive other
642 signals (preferably in combinatorial context).
643 rst : Signal or None, inout
644 Reset signal for this domain. Can be driven or used to drive.
645 """
646 def __init__(self, name=None, reset_less=False):
647 self.name = _tracer.get_obj_var_name(name)
648 if self.name is None:
649 raise ValueError("Cannot extract clock domain name from code, need to specify.")
650 if self.name.startswith("cd_"):
651 self.name = self.name[3:]
652 if self.name[0].isdigit():
653 raise ValueError("Clock domain name cannot start with a number.")
654 self.clk = Signal(name_override=self.name + "_clk")
655 if reset_less:
656 self.rst = None
657 else:
658 self.rst = Signal(name_override=self.name + "_rst")
659
660 def rename(self, new_name):
661 """Rename the clock domain
662
663 Parameters
664 ----------
665 new_name : str
666 New name
667 """
668 self.name = new_name
669 self.clk.name_override = new_name + "_clk"
670 if self.rst is not None:
671 self.rst.name_override = new_name + "_rst"
672
673
674 class _ClockDomainList(list):
675 def __getitem__(self, key):
676 if isinstance(key, str):
677 for cd in self:
678 if cd.name == key:
679 return cd
680 raise KeyError(key)
681 else:
682 return list.__getitem__(self, key)
683
684
685 (SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
686
687
688 class _Fragment:
689 def __init__(self, comb=None, sync=None, specials=None, clock_domains=None):
690 if comb is None: comb = []
691 if sync is None: sync = dict()
692 if specials is None: specials = set()
693 if clock_domains is None: clock_domains = _ClockDomainList()
694
695 self.comb = comb
696 self.sync = sync
697 self.specials = specials
698 self.clock_domains = _ClockDomainList(clock_domains)
699
700 def __add__(self, other):
701 newsync = _collections.defaultdict(list)
702 for k, v in self.sync.items():
703 newsync[k] = v[:]
704 for k, v in other.sync.items():
705 newsync[k].extend(v)
706 return _Fragment(self.comb + other.comb, newsync,
707 self.specials | other.specials,
708 self.clock_domains + other.clock_domains)
709
710 def __iadd__(self, other):
711 newsync = _collections.defaultdict(list)
712 for k, v in self.sync.items():
713 newsync[k] = v[:]
714 for k, v in other.sync.items():
715 newsync[k].extend(v)
716 self.comb += other.comb
717 self.sync = newsync
718 self.specials |= other.specials
719 self.clock_domains += other.clock_domains
720 return self
721
722 class Display(_Statement):
723 def __init__(self, s, *args):
724 self.s = s
725 self.args = args