parent
9fe27a15ad
commit
d72d4a55fd
|
@ -13,9 +13,9 @@ __all__ = ["DUID", "wrap", "Mux", "Cat", "Replicate", "Constant", "C", "Signal",
|
||||||
"SPECIAL_INPUT", "SPECIAL_OUTPUT", "SPECIAL_INOUT"]
|
"SPECIAL_INPUT", "SPECIAL_OUTPUT", "SPECIAL_INOUT"]
|
||||||
|
|
||||||
|
|
||||||
@deprecated("instead of `wrap`, use `Value.wrap`")
|
@deprecated("instead of `wrap`, use `Value.cast`")
|
||||||
def wrap(v):
|
def wrap(v):
|
||||||
return Value.wrap(v)
|
return Value.cast(v)
|
||||||
|
|
||||||
|
|
||||||
@extend(_Slice)
|
@extend(_Slice)
|
||||||
|
@ -52,14 +52,14 @@ def choices(self):
|
||||||
class If(ast.Switch):
|
class If(ast.Switch):
|
||||||
@deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`")
|
@deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`")
|
||||||
def __init__(self, cond, *stmts):
|
def __init__(self, cond, *stmts):
|
||||||
cond = Value.wrap(cond)
|
cond = Value.cast(cond)
|
||||||
if len(cond) != 1:
|
if len(cond) != 1:
|
||||||
cond = cond.bool()
|
cond = cond.bool()
|
||||||
super().__init__(cond, {("1",): ast.Statement.wrap(stmts)})
|
super().__init__(cond, {("1",): ast.Statement.wrap(stmts)})
|
||||||
|
|
||||||
@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
|
@deprecated("instead of `.Elif(cond, ...)`, use `with m.Elif(cond): ...`")
|
||||||
def Elif(self, cond, *stmts):
|
def Elif(self, cond, *stmts):
|
||||||
cond = Value.wrap(cond)
|
cond = Value.cast(cond)
|
||||||
if len(cond) != 1:
|
if len(cond) != 1:
|
||||||
cond = cond.bool()
|
cond = cond.bool()
|
||||||
self.cases = OrderedDict((("-" + k,), v) for (k,), v in self.cases.items())
|
self.cases = OrderedDict((("-" + k,), v) for (k,), v in self.cases.items())
|
||||||
|
|
|
@ -47,9 +47,12 @@ def _enum_to_bits(enum_value):
|
||||||
|
|
||||||
class Value(metaclass=ABCMeta):
|
class Value(metaclass=ABCMeta):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def wrap(obj):
|
def cast(obj):
|
||||||
"""Ensures that the passed object is an nMigen value. Booleans and integers
|
"""Converts ``obj`` to an nMigen value.
|
||||||
are automatically wrapped into ``Const``."""
|
|
||||||
|
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):
|
if isinstance(obj, Value):
|
||||||
return obj
|
return obj
|
||||||
elif isinstance(obj, (bool, int)):
|
elif isinstance(obj, (bool, int)):
|
||||||
|
@ -57,7 +60,13 @@ class Value(metaclass=ABCMeta):
|
||||||
elif isinstance(obj, Enum):
|
elif isinstance(obj, Enum):
|
||||||
return Const(obj.value, _enum_shape(type(obj)))
|
return Const(obj.value, _enum_shape(type(obj)))
|
||||||
else:
|
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):
|
def __init__(self, *, src_loc_at=0):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -93,14 +102,14 @@ class Value(metaclass=ABCMeta):
|
||||||
# completely by prohibiting such division operations.
|
# completely by prohibiting such division operations.
|
||||||
raise NotImplementedError("Division by a signed value is not supported")
|
raise NotImplementedError("Division by a signed value is not supported")
|
||||||
def __mod__(self, other):
|
def __mod__(self, other):
|
||||||
other = Value.wrap(other)
|
other = Value.cast(other)
|
||||||
other.__check_divisor()
|
other.__check_divisor()
|
||||||
return Operator("%", [self, other])
|
return Operator("%", [self, other])
|
||||||
def __rmod__(self, other):
|
def __rmod__(self, other):
|
||||||
self.__check_divisor()
|
self.__check_divisor()
|
||||||
return Operator("%", [other, self])
|
return Operator("%", [other, self])
|
||||||
def __floordiv__(self, other):
|
def __floordiv__(self, other):
|
||||||
other = Value.wrap(other)
|
other = Value.cast(other)
|
||||||
other.__check_divisor()
|
other.__check_divisor()
|
||||||
return Operator("//", [self, other])
|
return Operator("//", [self, other])
|
||||||
def __rfloordiv__(self, other):
|
def __rfloordiv__(self, other):
|
||||||
|
@ -452,7 +461,7 @@ class Operator(Value):
|
||||||
def __init__(self, op, operands, *, src_loc_at=0):
|
def __init__(self, op, operands, *, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=1 + src_loc_at)
|
super().__init__(src_loc_at=1 + src_loc_at)
|
||||||
self.op = op
|
self.op = op
|
||||||
self.operands = [Value.wrap(o) for o in operands]
|
self.operands = [Value.cast(o) for o in operands]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _bitwise_binary_shape(a_shape, b_shape):
|
def _bitwise_binary_shape(a_shape, b_shape):
|
||||||
|
@ -540,7 +549,7 @@ def Mux(sel, val1, val0):
|
||||||
Value, out
|
Value, out
|
||||||
Output ``Value``. If ``sel`` is asserted, the Mux returns ``val1``, else ``val0``.
|
Output ``Value``. If ``sel`` is asserted, the Mux returns ``val1``, else ``val0``.
|
||||||
"""
|
"""
|
||||||
sel = Value.wrap(sel)
|
sel = Value.cast(sel)
|
||||||
if len(sel) != 1:
|
if len(sel) != 1:
|
||||||
sel = sel.bool()
|
sel = sel.bool()
|
||||||
return Operator("m", [sel, val1, val0])
|
return Operator("m", [sel, val1, val0])
|
||||||
|
@ -567,7 +576,7 @@ class Slice(Value):
|
||||||
raise IndexError("Slice start {} must be less than slice end {}".format(start, end))
|
raise IndexError("Slice start {} must be less than slice end {}".format(start, end))
|
||||||
|
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
super().__init__(src_loc_at=src_loc_at)
|
||||||
self.value = Value.wrap(value)
|
self.value = Value.cast(value)
|
||||||
self.start = start
|
self.start = start
|
||||||
self.end = end
|
self.end = end
|
||||||
|
|
||||||
|
@ -594,7 +603,7 @@ class Part(Value):
|
||||||
|
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
super().__init__(src_loc_at=src_loc_at)
|
||||||
self.value = value
|
self.value = value
|
||||||
self.offset = Value.wrap(offset)
|
self.offset = Value.cast(offset)
|
||||||
self.width = width
|
self.width = width
|
||||||
self.stride = stride
|
self.stride = stride
|
||||||
|
|
||||||
|
@ -639,7 +648,7 @@ class Cat(Value):
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args, src_loc_at=0):
|
def __init__(self, *args, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
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):
|
def shape(self):
|
||||||
return sum(len(part) for part in self.parts), False
|
return sum(len(part) for part in self.parts), False
|
||||||
|
@ -688,7 +697,7 @@ class Repl(Value):
|
||||||
.format(count))
|
.format(count))
|
||||||
|
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
super().__init__(src_loc_at=src_loc_at)
|
||||||
self.value = Value.wrap(value)
|
self.value = Value.cast(value)
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
def shape(self):
|
def shape(self):
|
||||||
|
@ -857,7 +866,7 @@ class Signal(Value, DUID):
|
||||||
new_name = other.name + str(name_suffix)
|
new_name = other.name + str(name_suffix)
|
||||||
else:
|
else:
|
||||||
new_name = tracer.get_var_name(depth=2 + src_loc_at, default="$like")
|
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):
|
if isinstance(other, cls):
|
||||||
kw.update(reset=other.reset, reset_less=other.reset_less,
|
kw.update(reset=other.reset, reset_less=other.reset_less,
|
||||||
attrs=other.attrs, decoder=other.decoder)
|
attrs=other.attrs, decoder=other.decoder)
|
||||||
|
@ -1052,7 +1061,7 @@ class ArrayProxy(Value):
|
||||||
def __init__(self, elems, index, *, src_loc_at=0):
|
def __init__(self, elems, index, *, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=1 + src_loc_at)
|
super().__init__(src_loc_at=1 + src_loc_at)
|
||||||
self.elems = elems
|
self.elems = elems
|
||||||
self.index = Value.wrap(index)
|
self.index = Value.cast(index)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
return ArrayProxy([getattr(elem, attr) for elem in self.elems], self.index)
|
return ArrayProxy([getattr(elem, attr) for elem in self.elems], self.index)
|
||||||
|
@ -1061,7 +1070,7 @@ class ArrayProxy(Value):
|
||||||
return ArrayProxy([ elem[index] for elem in self.elems], self.index)
|
return ArrayProxy([ elem[index] for elem in self.elems], self.index)
|
||||||
|
|
||||||
def _iter_as_values(self):
|
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):
|
def shape(self):
|
||||||
width, signed = 0, False
|
width, signed = 0, False
|
||||||
|
@ -1113,7 +1122,7 @@ class UserValue(Value):
|
||||||
|
|
||||||
def _lazy_lower(self):
|
def _lazy_lower(self):
|
||||||
if self.__lowered is None:
|
if self.__lowered is None:
|
||||||
self.__lowered = Value.wrap(self.lower())
|
self.__lowered = Value.cast(self.lower())
|
||||||
return self.__lowered
|
return self.__lowered
|
||||||
|
|
||||||
def shape(self):
|
def shape(self):
|
||||||
|
@ -1136,7 +1145,7 @@ class Sample(Value):
|
||||||
"""
|
"""
|
||||||
def __init__(self, expr, clocks, domain, *, src_loc_at=0):
|
def __init__(self, expr, clocks, domain, *, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=1 + src_loc_at)
|
super().__init__(src_loc_at=1 + src_loc_at)
|
||||||
self.value = Value.wrap(expr)
|
self.value = Value.cast(expr)
|
||||||
self.clocks = int(clocks)
|
self.clocks = int(clocks)
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
if not isinstance(self.value, (Const, Signal, ClockSignal, ResetSignal, Initial)):
|
if not isinstance(self.value, (Const, Signal, ClockSignal, ResetSignal, Initial)):
|
||||||
|
@ -1219,8 +1228,8 @@ class Statement:
|
||||||
class Assign(Statement):
|
class Assign(Statement):
|
||||||
def __init__(self, lhs, rhs, *, src_loc_at=0):
|
def __init__(self, lhs, rhs, *, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
super().__init__(src_loc_at=src_loc_at)
|
||||||
self.lhs = Value.wrap(lhs)
|
self.lhs = Value.cast(lhs)
|
||||||
self.rhs = Value.wrap(rhs)
|
self.rhs = Value.cast(rhs)
|
||||||
|
|
||||||
def _lhs_signals(self):
|
def _lhs_signals(self):
|
||||||
return self.lhs._lhs_signals()
|
return self.lhs._lhs_signals()
|
||||||
|
@ -1235,7 +1244,7 @@ class Assign(Statement):
|
||||||
class Property(Statement):
|
class Property(Statement):
|
||||||
def __init__(self, test, *, _check=None, _en=None, src_loc_at=0):
|
def __init__(self, test, *, _check=None, _en=None, src_loc_at=0):
|
||||||
super().__init__(src_loc_at=src_loc_at)
|
super().__init__(src_loc_at=src_loc_at)
|
||||||
self.test = Value.wrap(test)
|
self.test = Value.cast(test)
|
||||||
self._check = _check
|
self._check = _check
|
||||||
self._en = _en
|
self._en = _en
|
||||||
if self._check is None:
|
if self._check is None:
|
||||||
|
@ -1283,7 +1292,7 @@ class Switch(Statement):
|
||||||
# be automatically traced, so whatever constructs a Switch may optionally provide it.
|
# be automatically traced, so whatever constructs a Switch may optionally provide it.
|
||||||
self.case_src_locs = {}
|
self.case_src_locs = {}
|
||||||
|
|
||||||
self.test = Value.wrap(test)
|
self.test = Value.cast(test)
|
||||||
self.cases = OrderedDict()
|
self.cases = OrderedDict()
|
||||||
for orig_keys, stmts in cases.items():
|
for orig_keys, stmts in cases.items():
|
||||||
# Map: None -> (); key -> (key,); (key...) -> (key...)
|
# Map: None -> (); key -> (key,); (key...) -> (key...)
|
||||||
|
@ -1466,7 +1475,7 @@ class _MappedKeySet(MutableSet, _MappedKeyCollection):
|
||||||
|
|
||||||
class ValueKey:
|
class ValueKey:
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = Value.wrap(value)
|
self.value = Value.cast(value)
|
||||||
if isinstance(self.value, Const):
|
if isinstance(self.value, Const):
|
||||||
self._hash = hash(self.value.value)
|
self._hash = hash(self.value.value)
|
||||||
elif isinstance(self.value, (Signal, AnyValue)):
|
elif isinstance(self.value, (Signal, AnyValue)):
|
||||||
|
|
|
@ -172,7 +172,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _check_signed_cond(self, cond):
|
def _check_signed_cond(self, cond):
|
||||||
cond = Value.wrap(cond)
|
cond = Value.cast(cond)
|
||||||
width, signed = cond.shape()
|
width, signed = cond.shape()
|
||||||
if signed:
|
if signed:
|
||||||
warnings.warn("Signed values in If/Elif conditions usually result from inverting "
|
warnings.warn("Signed values in If/Elif conditions usually result from inverting "
|
||||||
|
@ -249,7 +249,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
|
||||||
def Switch(self, test):
|
def Switch(self, test):
|
||||||
self._check_context("Switch", context=None)
|
self._check_context("Switch", context=None)
|
||||||
switch_data = self._set_ctrl("Switch", {
|
switch_data = self._set_ctrl("Switch", {
|
||||||
"test": Value.wrap(test),
|
"test": Value.cast(test),
|
||||||
"cases": OrderedDict(),
|
"cases": OrderedDict(),
|
||||||
"src_loc": tracer.get_src_loc(src_loc_at=1),
|
"src_loc": tracer.get_src_loc(src_loc_at=1),
|
||||||
"case_src_locs": {},
|
"case_src_locs": {},
|
||||||
|
@ -383,7 +383,7 @@ class Module(_ModuleBuilderRoot, Elaboratable):
|
||||||
tests, cases = [], OrderedDict()
|
tests, cases = [], OrderedDict()
|
||||||
for if_test, if_case in zip(if_tests + [None], if_bodies):
|
for if_test, if_case in zip(if_tests + [None], if_bodies):
|
||||||
if if_test is not None:
|
if if_test is not None:
|
||||||
if_test = Value.wrap(if_test)
|
if_test = Value.cast(if_test)
|
||||||
if len(if_test) != 1:
|
if len(if_test) != 1:
|
||||||
if_test = if_test.bool()
|
if_test = if_test.bool()
|
||||||
tests.append(if_test)
|
tests.append(if_test)
|
||||||
|
|
|
@ -23,27 +23,27 @@ class StringEnum(Enum):
|
||||||
|
|
||||||
|
|
||||||
class ValueTestCase(FHDLTestCase):
|
class ValueTestCase(FHDLTestCase):
|
||||||
def test_wrap(self):
|
def test_cast(self):
|
||||||
self.assertIsInstance(Value.wrap(0), Const)
|
self.assertIsInstance(Value.cast(0), Const)
|
||||||
self.assertIsInstance(Value.wrap(True), Const)
|
self.assertIsInstance(Value.cast(True), Const)
|
||||||
c = Const(0)
|
c = Const(0)
|
||||||
self.assertIs(Value.wrap(c), c)
|
self.assertIs(Value.cast(c), c)
|
||||||
with self.assertRaises(TypeError,
|
with self.assertRaises(TypeError,
|
||||||
msg="Object ''str'' is not an nMigen value"):
|
msg="Object 'str' is not an nMigen value"):
|
||||||
Value.wrap("str")
|
Value.cast("str")
|
||||||
|
|
||||||
def test_wrap_enum(self):
|
def test_cast_enum(self):
|
||||||
e1 = Value.wrap(UnsignedEnum.FOO)
|
e1 = Value.cast(UnsignedEnum.FOO)
|
||||||
self.assertIsInstance(e1, Const)
|
self.assertIsInstance(e1, Const)
|
||||||
self.assertEqual(e1.shape(), (2, False))
|
self.assertEqual(e1.shape(), (2, False))
|
||||||
e2 = Value.wrap(SignedEnum.FOO)
|
e2 = Value.cast(SignedEnum.FOO)
|
||||||
self.assertIsInstance(e2, Const)
|
self.assertIsInstance(e2, Const)
|
||||||
self.assertEqual(e2.shape(), (2, True))
|
self.assertEqual(e2.shape(), (2, True))
|
||||||
|
|
||||||
def test_wrap_enum_wrong(self):
|
def test_cast_enum_wrong(self):
|
||||||
with self.assertRaises(TypeError,
|
with self.assertRaises(TypeError,
|
||||||
msg="Only enumerations with integer values can be converted to nMigen values"):
|
msg="Only enumerations with integer values can be converted to nMigen values"):
|
||||||
Value.wrap(StringEnum.FOO)
|
Value.cast(StringEnum.FOO)
|
||||||
|
|
||||||
def test_bool(self):
|
def test_bool(self):
|
||||||
with self.assertRaises(TypeError,
|
with self.assertRaises(TypeError,
|
||||||
|
|
|
@ -13,8 +13,8 @@ from ..back.pysim import *
|
||||||
|
|
||||||
class SimulatorUnitTestCase(FHDLTestCase):
|
class SimulatorUnitTestCase(FHDLTestCase):
|
||||||
def assertStatement(self, stmt, inputs, output, reset=0):
|
def assertStatement(self, stmt, inputs, output, reset=0):
|
||||||
inputs = [Value.wrap(i) for i in inputs]
|
inputs = [Value.cast(i) for i in inputs]
|
||||||
output = Value.wrap(output)
|
output = Value.cast(output)
|
||||||
|
|
||||||
isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")]
|
isigs = [Signal(i.shape(), name=n) for i, n in zip(inputs, "abcd")]
|
||||||
osig = Signal(output.shape(), name="y", reset=reset)
|
osig = Signal(output.shape(), name="y", reset=reset)
|
||||||
|
|
Loading…
Reference in a new issue