hdl.ast: deprecate UserValue in favor of ValueCastable.

Closes #527.
This commit is contained in:
whitequark 2020-11-06 02:21:53 +00:00
parent c9fd000103
commit bde37fe2f2
3 changed files with 27 additions and 15 deletions

View file

@ -1237,6 +1237,7 @@ class ArrayProxy(Value):
return "(proxy (array [{}]) {!r})".format(", ".join(map(repr, self.elems)), self.index)
# TODO(nmigen-0.4): remove
class UserValue(Value):
"""Value with custom lowering.
@ -1257,6 +1258,7 @@ class UserValue(Value):
* Indexing or iterating through individual bits;
* Adding an assignment to the value to a ``Module`` using ``m.d.<domain> +=``.
"""
@deprecated("instead of `UserValue`, use `ValueCastable`", stacklevel=3)
def __init__(self, *, src_loc_at=0):
super().__init__(src_loc_at=1 + src_loc_at)
self.__lowered = None
@ -1292,7 +1294,7 @@ class ValueCastable:
providing fixed semantics upfront, it is kept abstract for as long as possible, only being
cast to a concrete nMigen value when required.
Note that it is necessary to ensure that nMigen's view of representation of all values stays
Note that it is necessary to ensure that nMigen's view of representation of all values stays
internally consistent. The class deriving from ``ValueCastable`` must decorate the ``as_value``
method with the ``lowermethod`` decorator, which ensures that all calls to ``as_value``return the
same ``Value`` representation. If the class deriving from ``ValueCastable`` is mutable, it is

View file

@ -1009,20 +1009,24 @@ class MockUserValue(UserValue):
class UserValueTestCase(FHDLTestCase):
def test_shape(self):
uv = MockUserValue(1)
self.assertEqual(uv.shape(), unsigned(1))
self.assertIsInstance(uv.shape(), Shape)
uv.lowered = 2
self.assertEqual(uv.shape(), unsigned(1))
self.assertEqual(uv.lower_count, 1)
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
uv = MockUserValue(1)
self.assertEqual(uv.shape(), unsigned(1))
self.assertIsInstance(uv.shape(), Shape)
uv.lowered = 2
self.assertEqual(uv.shape(), unsigned(1))
self.assertEqual(uv.lower_count, 1)
def test_lower_to_user_value(self):
uv = MockUserValue(MockUserValue(1))
self.assertEqual(uv.shape(), unsigned(1))
self.assertIsInstance(uv.shape(), Shape)
uv.lowered = MockUserValue(2)
self.assertEqual(uv.shape(), unsigned(1))
self.assertEqual(uv.lower_count, 1)
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
uv = MockUserValue(MockUserValue(1))
self.assertEqual(uv.shape(), unsigned(1))
self.assertIsInstance(uv.shape(), Shape)
uv.lowered = MockUserValue(2)
self.assertEqual(uv.shape(), unsigned(1))
self.assertEqual(uv.lower_count, 1)
class MockValueCastableChanges(ValueCastable):

View file

@ -1,5 +1,7 @@
# nmigen: UnusedElaboratable=no
import warnings
from nmigen.hdl.ast import *
from nmigen.hdl.cd import *
from nmigen.hdl.ir import *
@ -614,7 +616,9 @@ class UserValueTestCase(FHDLTestCase):
def setUp(self):
self.s = Signal()
self.c = Signal()
self.uv = MockUserValue(self.s)
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
self.uv = MockUserValue(self.s)
def test_lower(self):
sync = ClockDomain()
@ -645,6 +649,8 @@ class UserValueRecursiveTestCase(UserValueTestCase):
def setUp(self):
self.s = Signal()
self.c = Signal()
self.uv = MockUserValue(MockUserValue(self.s))
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
self.uv = MockUserValue(MockUserValue(self.s))
# inherit the test_lower method from UserValueTestCase because the checks are the same