f4250266c827d42d05cd4262f644a02a4df9d48b
1 import builtins
as _builtins
2 import collections
as _collections
4 from migen
.fhdl
import tracer
as _tracer
5 from migen
.util
.misc
import flat_iteration
as _flat_iteration
9 """Deterministic Unique IDentifier"""
12 self
.duid
= DUID
.__next
_uid
17 """Base class for operands
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).
24 Values created from integers have the minimum bit width to necessary to
25 represent the integer.
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
== "==":
32 if isinstance(a
, Constant
) and isinstance(b
, Constant
):
33 return a
.value
== b
.value
34 if isinstance(a
, Signal
) and isinstance(b
, Signal
):
36 if (isinstance(a
, Constant
) and isinstance(b
, Signal
)
37 or isinstance(a
, Signal
) and isinstance(a
, Constant
)):
39 raise TypeError("Attempted to convert Migen value to boolean")
42 return _Operator("~", [self
])
44 return _Operator("-", [self
])
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
])
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
])
93 from migen
.fhdl
.bitcontainer
import value_bits_sign
94 return value_bits_sign(self
)[0]
96 def __getitem__(self
, key
):
98 if isinstance(key
, int):
103 return _Slice(self
, key
, key
+1)
104 elif isinstance(key
, slice):
105 start
, stop
, step
= key
.indices(n
)
107 return Cat(self
[i
] for i
in range(start
, stop
, step
))
108 return _Slice(self
, start
, stop
)
118 Value to be assigned.
123 Assignment statement that can be used in combinatorial or
126 return _Assign(self
, r
)
129 raise TypeError("unhashable type: '{}'".format(type(self
).__name
__))
133 """Ensures that the passed object is a Migen value. Booleans and integers
134 are automatically wrapped into ``Constant``."""
135 if isinstance(value
, (bool, int)):
136 value
= Constant(value
)
137 if not isinstance(value
, _Value
):
138 raise TypeError("Object is not a Migen value")
142 class _Operator(_Value
):
143 def __init__(self
, op
, operands
):
144 _Value
.__init
__(self
)
146 self
.operands
= [wrap(o
) for o
in operands
]
149 def Mux(sel
, val1
, val0
):
150 """Multiplex between two values
163 Output `_Value`. If `sel` is asserted, the Mux returns
166 return _Operator("m", [sel
, val1
, val0
])
169 class _Slice(_Value
):
170 def __init__(self
, value
, start
, stop
):
171 _Value
.__init
__(self
)
172 if not isinstance(start
, int) or not isinstance(stop
, int):
173 raise TypeError("Slice boundaries must be integers")
174 self
.value
= wrap(value
)
180 """Concatenate values
182 Form a compound `_Value` from several smaller ones by concatenation.
183 The first argument occupies the lower bits of the result.
184 The return value can be used on either side of an assignment, that
185 is, the concatenated value can be used as an argument on the RHS or
186 as a target on the LHS. If it is used on the LHS, it must solely
187 consist of `Signal` s, slices of `Signal` s, and other concatenations
188 meeting these properties. The bit length of the return value is the sum of
189 the bit lengths of the arguments::
191 len(Cat(args)) == sum(len(arg) for arg in args)
195 *args : _Values or iterables of _Values, inout
196 `_Value` s to be concatenated.
201 Resulting `_Value` obtained by concatentation.
203 def __init__(self
, *args
):
204 _Value
.__init
__(self
)
205 self
.l
= [wrap(v
) for v
in _flat_iteration(args
)]
208 class Replicate(_Value
):
211 An input value is replicated (repeated) several times
212 to be used on the RHS of assignments::
214 len(Replicate(s, n)) == len(s)*n
219 Input value to be replicated.
221 Number of replications.
228 def __init__(self
, v
, n
):
229 _Value
.__init
__(self
)
230 if not isinstance(n
, int) or n
< 0:
231 raise TypeError("Replication count must be a positive integer")
236 class Constant(_Value
):
237 """A constant, HDL-literal integer `_Value`
242 bits_sign : int or tuple or None
243 Either an integer `bits` or a tuple `(bits, signed)`
244 specifying the number of bits in this `Constant` and whether it is
245 signed (can represent negative values). `bits_sign` defaults
246 to the minimum width and signedness of `value`.
248 def __init__(self
, value
, bits_sign
=None):
249 from migen
.fhdl
.bitcontainer
import bits_for
251 _Value
.__init
__(self
)
253 self
.value
= int(value
)
254 if bits_sign
is None:
255 bits_sign
= bits_for(self
.value
), self
.value
< 0
256 elif isinstance(bits_sign
, int):
257 bits_sign
= bits_sign
, self
.value
< 0
258 self
.nbits
, self
.signed
= bits_sign
259 if not isinstance(self
.nbits
, int) or self
.nbits
<= 0:
260 raise TypeError("Width must be a strictly positive integer")
266 C
= Constant
# shorthand
269 class Signal(_Value
):
270 """A `_Value` that can change
272 The `Signal` object represents a value that is expected to change
273 in the circuit. It does exactly what Verilog's `wire` and
274 `reg` and VHDL's `signal` do.
276 A `Signal` can be indexed to access a subset of its bits. Negative
277 indices (`signal[-1]`) and the extended Python slicing notation
278 (`signal[start:stop:step]`) are supported.
279 The indices 0 and -1 are the least and most significant bits
284 bits_sign : int or tuple
285 Either an integer `bits` or a tuple `(bits, signed)`
286 specifying the number of bits in this `Signal` and whether it is
287 signed (can represent negative values). `signed` defaults to
290 Name hint for this signal. If `None` (default) the name is
291 inferred from the variable name this `Signal` is assigned to.
292 Name collisions are automatically resolved by prepending
293 names of objects that contain this `Signal` and by
294 appending integer sequences.
298 Reset (synchronous) or default (combinatorial) value.
299 When this `Signal` is assigned to in synchronous context and the
300 corresponding clock domain is reset, the `Signal` assumes the
301 given value. When this `Signal` is unassigned in combinatorial
302 context (due to conditional assignments not being taken),
303 the `Signal` assumes its `reset` value. Defaults to 0.
304 name_override : str or None
305 Do not use the inferred name but the given one.
308 If `bits_sign` is `None`, the signal bit width and signedness are
309 determined by the integer range given by `min` (inclusive,
310 defaults to 0) and `max` (exclusive, defaults to 2).
311 related : Signal or None
313 def __init__(self
, bits_sign
=None, name
=None, variable
=False, reset
=0, name_override
=None, min=None, max=None, related
=None):
314 from migen
.fhdl
.bitcontainer
import bits_for
316 _Value
.__init
__(self
)
318 # determine number of bits and signedness
319 if bits_sign
is None:
324 max -= 1 # make both bounds inclusive
326 self
.signed
= min < 0 or max < 0
327 self
.nbits
= _builtins
.max(bits_for(min, self
.signed
), bits_for(max, self
.signed
))
329 assert(min is None and max is None)
330 if isinstance(bits_sign
, tuple):
331 self
.nbits
, self
.signed
= bits_sign
333 self
.nbits
, self
.signed
= bits_sign
, False
334 if not isinstance(self
.nbits
, int) or self
.nbits
<= 0:
335 raise ValueError("Signal width must be a strictly positive integer")
337 self
.variable
= variable
# deprecated
339 self
.name_override
= name_override
340 self
.backtrace
= _tracer
.trace_back(name
)
341 self
.related
= related
343 def __setattr__(self
, k
, v
):
346 _Value
.__setattr
__(self
, k
, v
)
349 return "<Signal " + (self
.backtrace
[-1][0] or "anonymous") + " at " + hex(id(self
)) + ">"
352 def like(cls
, other
, **kwargs
):
353 """Create Signal based on another.
358 Object to base this Signal on.
360 See `migen.fhdl.bitcontainer.value_bits_sign` for details.
362 from migen
.fhdl
.bitcontainer
import value_bits_sign
363 return cls(bits_sign
=value_bits_sign(other
), **kwargs
)
369 class ClockSignal(_Value
):
370 """Clock signal for a given clock domain
372 `ClockSignal` s for a given clock domain can be retrieved multiple
373 times. They all ultimately refer to the same signal.
378 Clock domain to obtain a clock signal for. Defaults to `"sys"`.
380 def __init__(self
, cd
="sys"):
381 _Value
.__init
__(self
)
382 if not isinstance(cd
, str):
383 raise TypeError("Argument of ClockSignal must be a string")
387 class ResetSignal(_Value
):
388 """Reset signal for a given clock domain
390 `ResetSignal` s for a given clock domain can be retrieved multiple
391 times. They all ultimately refer to the same signal.
396 Clock domain to obtain a reset signal for. Defaults to `"sys"`.
397 allow_reset_less : bool
398 If the clock domain is resetless, return 0 instead of reporting an
401 def __init__(self
, cd
="sys", allow_reset_less
=False):
402 _Value
.__init
__(self
)
403 if not isinstance(cd
, str):
404 raise TypeError("Argument of ResetSignal must be a string")
406 self
.allow_reset_less
= allow_reset_less
416 class _Assign(_Statement
):
417 def __init__(self
, l
, r
):
422 def _check_statement(s
):
423 if isinstance(s
, _collections
.Iterable
):
424 return all(_check_statement(ss
) for ss
in s
)
426 return isinstance(s
, _Statement
)
429 class If(_Statement
):
430 """Conditional execution of statements
437 Statements to execute if `cond` is asserted.
453 def __init__(self
, cond
, *t
):
454 if not _check_statement(t
):
455 raise TypeError("Not all test body objects are Migen statements")
456 self
.cond
= wrap(cond
)
461 """Add an `else` conditional block
466 Statements to execute if all previous conditions fail.
468 if not _check_statement(f
):
469 raise TypeError("Not all test body objects are Migen statements")
470 _insert_else(self
, list(f
))
473 def Elif(self
, cond
, *t
):
474 """Add an `else if` conditional block
481 Statements to execute if previous conditions fail and `cond`
484 _insert_else(self
, [If(cond
, *t
)])
488 def _insert_else(obj
, clause
):
491 assert(len(o
.f
) == 1)
492 assert(isinstance(o
.f
[0], If
))
497 class Case(_Statement
):
498 """Case/Switch statement
503 Selector value used to decide which block to execute
505 Dictionary of cases. The keys are numeric constants to compare
506 with `test`. The values are statements to be executed the
507 corresponding key matches `test`. The dictionary may contain a
508 string key `"default"` to mark a fall-through case that is
509 executed if no other key matches.
518 ... "default": b.eq(0),
521 def __init__(self
, test
, cases
):
522 self
.test
= wrap(test
)
524 for k
, v
in cases
.items():
525 if isinstance(k
, (bool, int)):
527 if (not isinstance(k
, Constant
)
528 and not (isinstance(k
, str) and k
== "default")):
529 raise TypeError("Case object is not a Migen constant")
530 if not isinstance(v
, _collections
.Iterable
):
532 if not _check_statement(v
):
533 raise TypeError("Not all objects for case {} "
534 "are Migen statements".format(k
))
537 def makedefault(self
, key
=None):
538 """Mark a key as the default case
540 Deletes/substitutes any previously existing default case.
545 Key to use as default case if no other key matches.
546 By default, the largest key is the default key.
549 for choice
in self
.cases
.keys():
550 if key
is None or choice
.value
> key
.value
:
552 self
.cases
["default"] = self
.cases
[key
]
560 class _ArrayProxy(_Value
):
561 def __init__(self
, choices
, key
):
562 _Value
.__init
__(self
)
565 if isinstance(c
, (bool, int)):
567 self
.choices
.append(c
)
570 def __getattr__(self
, attr
):
571 return _ArrayProxy([getattr(choice
, attr
) for choice
in self
.choices
],
574 def __getitem__(self
, key
):
575 return _ArrayProxy([choice
.__getitem
__(key
) for choice
in self
.choices
],
580 """Addressable multiplexer
582 An array is created from an iterable of values and indexed using the
583 usual Python simple indexing notation (no negative indices or
584 slices). It can be indexed by numeric constants, `_Value` s, or
587 The result of indexing the array is a proxy for the entry at the
588 given index that can be used on either RHS or LHS of assignments.
590 An array can be indexed multiple times.
592 Multidimensional arrays are supported by packing inner arrays into
597 values : iterable of ints, _Values, Signals
598 Entries of the array. Each entry can be a numeric constant, a
599 `Signal` or a `Record`.
603 >>> a = Array(range(10))
604 >>> b = Signal(max=10)
605 >>> c = Signal(max=10)
608 def __getitem__(self
, key
):
609 if isinstance(key
, Constant
):
610 return list.__getitem
__(self
, key
.value
)
611 elif isinstance(key
, _Value
):
612 return _ArrayProxy(self
, key
)
614 return list.__getitem
__(self
, key
)
618 """Synchronous domain
623 Domain name. If None (the default) the name is inferred from the
624 variable name this `ClockDomain` is assigned to (stripping any
627 The domain does not use a reset signal. Registers within this
628 domain are still all initialized to their reset state once, e.g.
629 through Verilog `"initial"` statements.
634 The clock for this domain. Can be driven or used to drive other
635 signals (preferably in combinatorial context).
636 rst : Signal or None, inout
637 Reset signal for this domain. Can be driven or used to drive.
639 def __init__(self
, name
=None, reset_less
=False):
640 self
.name
= _tracer
.get_obj_var_name(name
)
641 if self
.name
is None:
642 raise ValueError("Cannot extract clock domain name from code, need to specify.")
643 if self
.name
.startswith("cd_"):
644 self
.name
= self
.name
[3:]
645 if self
.name
[0].isdigit():
646 raise ValueError("Clock domain name cannot start with a number.")
647 self
.clk
= Signal(name_override
=self
.name
+ "_clk")
651 self
.rst
= Signal(name_override
=self
.name
+ "_rst")
653 def rename(self
, new_name
):
654 """Rename the clock domain
662 self
.clk
.name_override
= new_name
+ "_clk"
663 if self
.rst
is not None:
664 self
.rst
.name_override
= new_name
+ "_rst"
667 class _ClockDomainList(list):
668 def __getitem__(self
, key
):
669 if isinstance(key
, str):
675 return list.__getitem
__(self
, key
)
678 (SPECIAL_INPUT
, SPECIAL_OUTPUT
, SPECIAL_INOUT
) = range(3)
682 def __init__(self
, comb
=None, sync
=None, specials
=None, clock_domains
=None):
683 if comb
is None: comb
= []
684 if sync
is None: sync
= dict()
685 if specials
is None: specials
= set()
686 if clock_domains
is None: clock_domains
= _ClockDomainList()
690 self
.specials
= specials
691 self
.clock_domains
= _ClockDomainList(clock_domains
)
693 def __add__(self
, other
):
694 newsync
= _collections
.defaultdict(list)
695 for k
, v
in self
.sync
.items():
697 for k
, v
in other
.sync
.items():
699 return _Fragment(self
.comb
+ other
.comb
, newsync
,
700 self
.specials | other
.specials
,
701 self
.clock_domains
+ other
.clock_domains
)
703 def __iadd__(self
, other
):
704 newsync
= _collections
.defaultdict(list)
705 for k
, v
in self
.sync
.items():
707 for k
, v
in other
.sync
.items():
709 self
.comb
+= other
.comb
711 self
.specials |
= other
.specials
712 self
.clock_domains
+= other
.clock_domains