From: whitequark Date: Tue, 1 Jan 2019 09:50:39 +0000 (+0000) Subject: hdl.ast: experimentally add Value._as_const. X-Git-Tag: working~103 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ea7e19ed5c76ee809c089f3272abf97a3acd1b01;p=nmigen.git hdl.ast: experimentally add Value._as_const. Useful for writing e.g. decoders that accept Cat, etc as argument. --- diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index 7ee588d..fc6a0de 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -192,6 +192,9 @@ class Value(metaclass=ABCMeta): def _rhs_signals(self): pass # :nocov: + def _as_const(self): + raise TypeError("Value {!r} cannot be evaluated as constant".format(self)) + __hash__ = None @@ -240,6 +243,9 @@ class Const(Value): def _rhs_signals(self): return ValueSet() + def _as_const(self): + return self.value + def __repr__(self): return "(const {}'{}d{})".format(self.nbits, "s" if self.signed else "", self.value) @@ -435,13 +441,20 @@ class Cat(Value): self.parts = [Value.wrap(v) for v in flatten(args)] def shape(self): - return sum(len(op) for op in self.parts), False + return sum(len(part) for part in self.parts), False def _lhs_signals(self): - return union(op._lhs_signals() for op in self.parts) + return union(part._lhs_signals() for part in self.parts) def _rhs_signals(self): - return union(op._rhs_signals() for op in self.parts) + return union(part._rhs_signals() for part in self.parts) + + def _as_const(self): + value = 0 + for part in reversed(self.parts): + value <<= len(part) + value |= part._as_const() + return value def __repr__(self): return "(cat {})".format(" ".join(map(repr, self.parts)))