sim: use Format.* for VCD output, remove hdl._repr.

This also changes `decoder` a bit: when an enum is used as a decoder,
it is converted to a `Format.Enum` instead. The original enum is still
stored on the `decoder` attribute, so that it can be propagated
on `Signal.like`.
This commit is contained in:
Wanda 2024-04-12 23:08:41 +02:00 committed by Catherine
parent 122be7849c
commit 8bf4f77616
12 changed files with 88 additions and 179 deletions

View file

@ -1326,17 +1326,15 @@ class SignalTestCase(FHDLTestCase):
RED = 1
BLUE = 2
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), ()),)")
self.assertEqual(s.decoder, Color)
self.assertRepr(s._format, "(format-enum (sig s) 'Color' (1 'RED') (2 'BLUE'))")
def test_enum(self):
s1 = Signal(UnsignedEnum)
self.assertEqual(s1.shape(), unsigned(2))
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), ()),)")
self.assertRepr(s2._format, "(format-enum (sig s2) 'SignedEnum' (-1 'FOO') (0 'BAR') (1 'BAZ'))")
def test_const_wrong(self):
s1 = Signal()
@ -1344,9 +1342,9 @@ class SignalTestCase(FHDLTestCase):
r"^Value \(sig s1\) cannot be converted to an Amaranth constant$"):
Const.cast(s1)
def test_value_repr(self):
def test_format_simple(self):
s = Signal()
self.assertRepr(s._value_repr, "(Repr(FormatInt(), (sig s), ()),)")
self.assertRepr(s._format, "(format '{}' (sig s))")
class ClockSignalTestCase(FHDLTestCase):

View file

@ -203,7 +203,7 @@ class RecordTestCase(FHDLTestCase):
def test_enum_decoder(self):
r1 = Record([("a", UnsignedEnum)])
self.assertEqual(r1.a.decoder(UnsignedEnum.FOO), "FOO/1")
self.assertRepr(r1.a._format, "(format-enum (sig r1__a) 'UnsignedEnum' (1 'FOO') (2 'BAR') (3 'BAZ'))")
def test_operators(self):
r1 = Record([("a", 1)])

View file

@ -531,10 +531,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',)))
self.assertRepr(cv._format, """
(format-struct (sig v)
('a' (format '{}' (slice (sig v) 0:1)))
('b' (format '{}' (slice (sig v) 1:3)))
)
""")
def test_construct_signal_init(self):

View file

@ -138,7 +138,7 @@ class EnumTestCase(FHDLTestCase):
B = -3
a = Signal(EnumA)
self.assertRepr(a, "(sig a)")
self.assertRepr(a._value_repr, "(Repr(FormatEnum(EnumA), (sig a), ()),)")
self.assertRepr(a._format, "(format-enum (sig a) 'EnumA' (0 'A') (-3 'B'))")
def test_enum_view(self):
class EnumA(Enum, shape=signed(4)):

View file

@ -469,10 +469,10 @@ class SimulatorUnitTestCase(FHDLTestCase):
class SimulatorIntegrationTestCase(FHDLTestCase):
@contextmanager
def assertSimulation(self, module, *, deadline=None):
def assertSimulation(self, module, *, deadline=None, traces=[]):
sim = Simulator(module)
yield sim
with sim.write_vcd("test.vcd", "test.gtkw"):
with sim.write_vcd("test.vcd", "test.gtkw", traces=traces):
if deadline is None:
sim.run()
else:
@ -1336,10 +1336,25 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
self.assertEqual(eval_format(state, Format("{:s}", sig5)), "ABCD")
self.assertEqual(eval_format(state, Format("{:<5s}", sig5)), "ABCD ")
sim = Simulator(Module())
sim.add_testbench(testbench)
with sim.write_vcd("test.vcd", fs_per_delta=1):
sim.run()
with self.assertSimulation(Module(), traces=[sig, sig2, sig3, sig4, sig5]) as sim:
sim.add_testbench(testbench)
def test_decoder(self):
def decoder(val):
return f".oO{val}Oo."
sig = Signal(2, decoder=decoder)
def testbench():
yield Delay(1e-6)
yield sig.eq(1)
yield Delay(1e-6)
yield sig.eq(2)
yield Delay(1e-6)
with self.assertSimulation(Module(), traces=[sig]) as sim:
sim.add_testbench(testbench)
class SimulatorRegressionTestCase(FHDLTestCase):
def test_bug_325(self):