From 3a1010f27d610818f6d1f88dc3184e43a352f30f Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 1 Jan 2019 09:50:39 +0000 Subject: [PATCH] hdl.ast: experimentally add Value._as_const. Useful for writing e.g. decoders that accept Cat, etc as argument. --- nmigen/hdl/ast.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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))) -- 2.30.2