Skip to content

Commit 67f5b61

Browse files
wanda-phiwhitequark
authored andcommitted
hdl._ast: add enum name argument to Format.Enum.
Turns out that RTLIL enum representation requires such, so add a place to store it.
1 parent 1fdd9bf commit 67f5b61

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

amaranth/hdl/_ast.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,8 +2769,11 @@ def _rhs_signals(self):
27692769

27702770

27712771
class Enum(_FormatLike):
2772-
def __init__(self, value, /, variants):
2772+
def __init__(self, value, /, variants, *, name=None):
27732773
self._value = Value.cast(value)
2774+
if name is not None and not isinstance(name, str):
2775+
raise TypeError(f"Enum name must be a string or None, not {name!r}")
2776+
self._name = name
27742777
if isinstance(variants, EnumMeta):
27752778
self._variants = {Const.cast(member.value).value: member.name for member in variants}
27762779
else:
@@ -2796,7 +2799,8 @@ def __repr__(self):
27962799
f" ({val!r} {name!r})"
27972800
for val, name in self._variants.items()
27982801
)
2799-
return f"(format-enum {self._value!r}{variants})"
2802+
name = "-" if self._name is None else repr(self._name)
2803+
return f"(format-enum {self._value!r} {name}{variants})"
28002804

28012805

28022806
class Struct(_FormatLike):

amaranth/lib/enum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def from_bits(cls, bits):
179179
def format(cls, value, format_spec):
180180
if format_spec != "":
181181
raise ValueError(f"Format specifier {format_spec!r} is not supported for enums")
182-
return Format.Enum(value, cls)
182+
return Format.Enum(value, cls, name=cls.__name__)
183183

184184
def _value_repr(cls, value):
185185
yield Repr(FormatEnum(cls), value)

tests/test_hdl_ast.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,7 +1740,7 @@ class FormatEnumTestCase(FHDLTestCase):
17401740
def test_construct(self):
17411741
a = Signal(3)
17421742
fmt = Format.Enum(a, {1: "A", 2: "B", 3: "C"})
1743-
self.assertRepr(fmt, "(format-enum (sig a) (1 'A') (2 'B') (3 'C'))")
1743+
self.assertRepr(fmt, "(format-enum (sig a) - (1 'A') (2 'B') (3 'C'))")
17441744
self.assertRepr(Format("{}", fmt), """
17451745
(format '{:s}' (switch-value (sig a)
17461746
(case 001 (const 8'd65))
@@ -1755,8 +1755,8 @@ class MyEnum(Enum):
17551755
B = 3
17561756
C = 4
17571757

1758-
fmt = Format.Enum(a, MyEnum)
1759-
self.assertRepr(fmt, "(format-enum (sig a) (0 'A') (3 'B') (4 'C'))")
1758+
fmt = Format.Enum(a, MyEnum, name="MyEnum")
1759+
self.assertRepr(fmt, "(format-enum (sig a) 'MyEnum' (0 'A') (3 'B') (4 'C'))")
17601760
self.assertRepr(Format("{}", fmt), """
17611761
(format '{:s}' (switch-value (sig a)
17621762
(case 000 (const 8'd65))
@@ -1774,6 +1774,9 @@ def test_construct_wrong(self):
17741774
with self.assertRaisesRegex(TypeError,
17751775
r"^Variant names must be strings, not 123$"):
17761776
Format.Enum(a, {1: 123})
1777+
with self.assertRaisesRegex(TypeError,
1778+
r"^Enum name must be a string or None, not 123$"):
1779+
Format.Enum(a, {}, name=123)
17771780

17781781

17791782
class FormatStructTestCase(FHDLTestCase):

tests/test_lib_enum.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,13 @@ class EnumB(IntEnum, shape=4):
320320
A = 1
321321
B = py_enum.member(2)
322322
self.assertIs(2, EnumB.B.value)
323+
324+
def test_format(self):
325+
class EnumA(Enum, shape=unsigned(2)):
326+
A = 0
327+
B = 1
328+
329+
sig = Signal(EnumA)
330+
self.assertRepr(EnumA.format(sig, ""), """
331+
(format-enum (sig sig) 'EnumA' (0 'A') (1 'B'))
332+
""")

0 commit comments

Comments
 (0)