hdl._ast: fix _value_repr computation.

Fixes fallout from #1165.
This commit is contained in:
Wanda 2024-03-25 14:41:20 +01:00 committed by Catherine
parent 11f7b887ad
commit efcd9a4538
5 changed files with 33 additions and 11 deletions

View file

@ -1972,9 +1972,11 @@ class Signal(Value, DUID, metaclass=_SignalMeta):
if decoder is not None:
# The value representation is specified explicitly. Since we do not expose `hdl._repr`,
# this is the only way to add a custom filter to the signal right now. The setter sets
# `self._value_repr` as well as the compatibility `self.decoder`.
pass
# this is the only way to add a custom filter to the signal right now.
if isinstance(decoder, type) and issubclass(decoder, Enum):
self._value_repr = (_repr.Repr(_repr.FormatEnum(decoder), self),)
else:
self._value_repr = (_repr.Repr(_repr.FormatCustom(decoder), self),)
else:
# If it's an enum, expose it via `self.decoder` for compatibility, whether it's a Python
# enum or an Amaranth enum. This also sets the value representation, even for custom
@ -1995,20 +1997,16 @@ class Signal(Value, DUID, metaclass=_SignalMeta):
self._value_repr = (_repr.Repr(_repr.FormatInt(), self),)
# Compute the value representation that will be used by Amaranth.
if decoder is None:
self._value_repr = (_repr.Repr(_repr.FormatInt(), self),)
self._decoder = None
elif not (isinstance(decoder, type) and issubclass(decoder, Enum)):
self._value_repr = (_repr.Repr(_repr.FormatCustom(decoder), self),)
self._decoder = decoder
else: # Violence. In the name of backwards compatibility!
self._value_repr = (_repr.Repr(_repr.FormatEnum(decoder), self),)
if isinstance(decoder, type) and issubclass(decoder, Enum):
# Violence. In the name of backwards compatibility!
def enum_decoder(value):
try:
return "{0.name:}/{0.value:}".format(decoder(value))
except ValueError:
return str(value)
self._decoder = enum_decoder
else:
self._decoder = decoder
@property
def width(self):

View file

@ -14,6 +14,9 @@ class FormatInt(Format):
def format(self, value):
return f"{value:d}"
def __repr__(self):
return f"FormatInt()"
class FormatEnum(Format):
def __init__(self, enum):
@ -25,6 +28,9 @@ class FormatEnum(Format):
except ValueError:
return f"?/{value:d}"
def __repr__(self):
return f"FormatEnum({self.enum.__name__})"
class FormatCustom(Format):
def __init__(self, formatter):
@ -33,6 +39,9 @@ class FormatCustom(Format):
def format(self, value):
return self.formatter(value)
def __repr__(self):
return f"FormatCustom({self.formatter})"
class Repr:
def __init__(self, format, value, *, path=()):
@ -44,3 +53,6 @@ class Repr:
self.format = format
self.value = value
self.path = path
def __repr__(self):
return f"Repr({self.format!r}, {self.value!r}, {self.path!r})"

View file

@ -1321,6 +1321,7 @@ class SignalTestCase(FHDLTestCase):
s = Signal(decoder=Color)
self.assertEqual(s.decoder(1), "RED/1")
self.assertEqual(s.decoder(3), "3")
self.assertRepr(s._value_repr, "(Repr(FormatEnum(Color), (sig s), ()),)")
def test_enum(self):
s1 = Signal(UnsignedEnum)
@ -1328,6 +1329,7 @@ class SignalTestCase(FHDLTestCase):
s2 = Signal(SignedEnum)
self.assertEqual(s2.shape(), signed(2))
self.assertEqual(s2.decoder(SignedEnum.FOO), "FOO/-1")
self.assertRepr(s2._value_repr, "(Repr(FormatEnum(SignedEnum), (sig s2), ()),)")
def test_const_wrong(self):
s1 = Signal()
@ -1335,6 +1337,10 @@ class SignalTestCase(FHDLTestCase):
r"^Value \(sig s1\) cannot be converted to an Amaranth constant$"):
Const.cast(s1)
def test_value_repr(self):
s = Signal()
self.assertRepr(s._value_repr, "(Repr(FormatInt(), (sig s), ()),)")
class ClockSignalTestCase(FHDLTestCase):
def test_domain(self):

View file

@ -458,6 +458,11 @@ class ViewTestCase(FHDLTestCase):
self.assertIsInstance(cv, Signal)
self.assertEqual(cv.shape(), unsigned(3))
self.assertEqual(cv.name, "v")
self.assertRepr(cv._value_repr, """
(Repr(FormatInt(), (sig v), ()),
Repr(FormatInt(), (slice (sig v) 0:1), ('a',)),
Repr(FormatInt(), (slice (sig v) 1:3), ('b',)))
""")
def test_construct_signal_init(self):
v1 = Signal(data.StructLayout({"a": unsigned(1), "b": unsigned(2)}),

View file

@ -137,6 +137,7 @@ class EnumTestCase(FHDLTestCase):
B = -3
a = Signal(EnumA)
self.assertRepr(a, "(sig a)")
self.assertRepr(a._value_repr, "(Repr(FormatEnum(EnumA), (sig a), ()),)")
def test_enum_view(self):
class EnumA(Enum, shape=signed(4)):