class Value(metaclass=ABCMeta):
@staticmethod
- def wrap(obj):
- """Ensures that the passed object is an nMigen value. Booleans and integers
- are automatically wrapped into ``Const``."""
+ def cast(obj):
+ """Converts ``obj`` to an nMigen value.
+
+ Booleans and integers are wrapped into a :class:`Const`. Enumerations whose members are
+ all integers are converted to a :class:`Const` with a shape that fits every member.
+ """
if isinstance(obj, Value):
return obj
elif isinstance(obj, (bool, int)):
elif isinstance(obj, Enum):
return Const(obj.value, _enum_shape(type(obj)))
else:
- raise TypeError("Object '{!r}' is not an nMigen value".format(obj))
+ raise TypeError("Object {!r} is not an nMigen value".format(obj))
+
+ # TODO(nmigen-0.2): remove this
+ @classmethod
+ @deprecated("instead of `Value.wrap`, use `Value.cast`")
+ def wrap(cls, obj):
+ return cls.cast(obj)
def __init__(self, *, src_loc_at=0):
super().__init__()
# completely by prohibiting such division operations.
raise NotImplementedError("Division by a signed value is not supported")
def __mod__(self, other):
- other = Value.wrap(other)
+ other = Value.cast(other)
other.__check_divisor()
return Operator("%", [self, other])
def __rmod__(self, other):
self.__check_divisor()
return Operator("%", [other, self])
def __floordiv__(self, other):
- other = Value.wrap(other)
+ other = Value.cast(other)
other.__check_divisor()
return Operator("//", [self, other])
def __rfloordiv__(self, other):
def __init__(self, op, operands, *, src_loc_at=0):
super().__init__(src_loc_at=1 + src_loc_at)
self.op = op
- self.operands = [Value.wrap(o) for o in operands]
+ self.operands = [Value.cast(o) for o in operands]
@staticmethod
def _bitwise_binary_shape(a_shape, b_shape):
Value, out
Output ``Value``. If ``sel`` is asserted, the Mux returns ``val1``, else ``val0``.
"""
- sel = Value.wrap(sel)
+ sel = Value.cast(sel)
if len(sel) != 1:
sel = sel.bool()
return Operator("m", [sel, val1, val0])
raise IndexError("Slice start {} must be less than slice end {}".format(start, end))
super().__init__(src_loc_at=src_loc_at)
- self.value = Value.wrap(value)
+ self.value = Value.cast(value)
self.start = start
self.end = end
super().__init__(src_loc_at=src_loc_at)
self.value = value
- self.offset = Value.wrap(offset)
+ self.offset = Value.cast(offset)
self.width = width
self.stride = stride
"""
def __init__(self, *args, src_loc_at=0):
super().__init__(src_loc_at=src_loc_at)
- self.parts = [Value.wrap(v) for v in flatten(args)]
+ self.parts = [Value.cast(v) for v in flatten(args)]
def shape(self):
return sum(len(part) for part in self.parts), False
.format(count))
super().__init__(src_loc_at=src_loc_at)
- self.value = Value.wrap(value)
+ self.value = Value.cast(value)
self.count = count
def shape(self):
new_name = other.name + str(name_suffix)
else:
new_name = tracer.get_var_name(depth=2 + src_loc_at, default="$like")
- kw = dict(shape=cls.wrap(other).shape(), name=new_name)
+ kw = dict(shape=cls.cast(other).shape(), name=new_name)
if isinstance(other, cls):
kw.update(reset=other.reset, reset_less=other.reset_less,
attrs=other.attrs, decoder=other.decoder)
def __init__(self, elems, index, *, src_loc_at=0):
super().__init__(src_loc_at=1 + src_loc_at)
self.elems = elems
- self.index = Value.wrap(index)
+ self.index = Value.cast(index)
def __getattr__(self, attr):
return ArrayProxy([getattr(elem, attr) for elem in self.elems], self.index)
return ArrayProxy([ elem[index] for elem in self.elems], self.index)
def _iter_as_values(self):
- return (Value.wrap(elem) for elem in self.elems)
+ return (Value.cast(elem) for elem in self.elems)
def shape(self):
width, signed = 0, False
def _lazy_lower(self):
if self.__lowered is None:
- self.__lowered = Value.wrap(self.lower())
+ self.__lowered = Value.cast(self.lower())
return self.__lowered
def shape(self):
"""
def __init__(self, expr, clocks, domain, *, src_loc_at=0):
super().__init__(src_loc_at=1 + src_loc_at)
- self.value = Value.wrap(expr)
+ self.value = Value.cast(expr)
self.clocks = int(clocks)
self.domain = domain
if not isinstance(self.value, (Const, Signal, ClockSignal, ResetSignal, Initial)):
class Assign(Statement):
def __init__(self, lhs, rhs, *, src_loc_at=0):
super().__init__(src_loc_at=src_loc_at)
- self.lhs = Value.wrap(lhs)
- self.rhs = Value.wrap(rhs)
+ self.lhs = Value.cast(lhs)
+ self.rhs = Value.cast(rhs)
def _lhs_signals(self):
return self.lhs._lhs_signals()
class Property(Statement):
def __init__(self, test, *, _check=None, _en=None, src_loc_at=0):
super().__init__(src_loc_at=src_loc_at)
- self.test = Value.wrap(test)
+ self.test = Value.cast(test)
self._check = _check
self._en = _en
if self._check is None:
# be automatically traced, so whatever constructs a Switch may optionally provide it.
self.case_src_locs = {}
- self.test = Value.wrap(test)
+ self.test = Value.cast(test)
self.cases = OrderedDict()
for orig_keys, stmts in cases.items():
# Map: None -> (); key -> (key,); (key...) -> (key...)
class ValueKey:
def __init__(self, value):
- self.value = Value.wrap(value)
+ self.value = Value.cast(value)
if isinstance(self.value, Const):
self._hash = hash(self.value.value)
elif isinstance(self.value, (Signal, AnyValue)):
class ValueTestCase(FHDLTestCase):
- def test_wrap(self):
- self.assertIsInstance(Value.wrap(0), Const)
- self.assertIsInstance(Value.wrap(True), Const)
+ def test_cast(self):
+ self.assertIsInstance(Value.cast(0), Const)
+ self.assertIsInstance(Value.cast(True), Const)
c = Const(0)
- self.assertIs(Value.wrap(c), c)
+ self.assertIs(Value.cast(c), c)
with self.assertRaises(TypeError,
- msg="Object ''str'' is not an nMigen value"):
- Value.wrap("str")
+ msg="Object 'str' is not an nMigen value"):
+ Value.cast("str")
- def test_wrap_enum(self):
- e1 = Value.wrap(UnsignedEnum.FOO)
+ def test_cast_enum(self):
+ e1 = Value.cast(UnsignedEnum.FOO)
self.assertIsInstance(e1, Const)
self.assertEqual(e1.shape(), (2, False))
- e2 = Value.wrap(SignedEnum.FOO)
+ e2 = Value.cast(SignedEnum.FOO)
self.assertIsInstance(e2, Const)
self.assertEqual(e2.shape(), (2, True))
- def test_wrap_enum_wrong(self):
+ def test_cast_enum_wrong(self):
with self.assertRaises(TypeError,
msg="Only enumerations with integer values can be converted to nMigen values"):
- Value.wrap(StringEnum.FOO)
+ Value.cast(StringEnum.FOO)
def test_bool(self):
with self.assertRaises(TypeError,