From abd74ead55c3a0d43a0f8c1b30f34ca3ace53f3a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 15 Nov 2023 18:03:13 -0500 Subject: [PATCH] lib.wiring: flip sub-interfaces accessed via FlippedInterface. --- amaranth/lib/wiring.py | 3 +++ tests/test_lib_wiring.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/amaranth/lib/wiring.py b/amaranth/lib/wiring.py index d808de6..e34d895 100644 --- a/amaranth/lib/wiring.py +++ b/amaranth/lib/wiring.py @@ -570,6 +570,9 @@ class FlippedInterface: value = getattr(self.__unflipped, name) if inspect.ismethod(value): return types.MethodType(value.__func__, self) + elif name in self.__unflipped.signature.members and \ + self.__unflipped.signature.members[name].is_signature: + return flipped(value) else: return value diff --git a/tests/test_lib_wiring.py b/tests/test_lib_wiring.py index d7bc2ef..a1f5262 100644 --- a/tests/test_lib_wiring.py +++ b/tests/test_lib_wiring.py @@ -598,6 +598,38 @@ class FlippedInterfaceTestCase(unittest.TestCase): flipped_interface = CustomSignature({}).flip().create() self.assertTrue(hasattr(flipped_interface, "custom_method")) + def test_propagate_flipped(self): + class InterfaceWithFlippedSub(Component): + signature = Signature({ + "a": In(Signature({ + "b": Out(Signature({ + "c": Out(1) + })), + "d": In(Signature({ + "e": Out(1) + })), + "f": Out(1) + })) + }) + + def __init__(self): + super().__init__() + self.g = Signature({"h": In(1)}) + + ifsub = InterfaceWithFlippedSub() + self.assertIsInstance(ifsub.a.b.signature, FlippedSignature) + self.assertIsInstance(ifsub.a.d.signature, Signature) + self.assertIsInstance(ifsub.signature.members["a"].signature. + members["b"].signature, FlippedSignature) + self.assertIsInstance(ifsub.signature.members["a"].signature. + members["d"].signature, Signature) + self.assertIsInstance(ifsub.a.f, Signal) + self.assertEqual(ifsub.signature.members["a"].signature. + members["f"].flow, In) + self.assertIsInstance(flipped(ifsub).g, Signature) + self.assertEqual(ifsub.g.members["h"].flow, In) + self.assertEqual(flipped(ifsub).g.members["h"].flow, In) + class ConnectTestCase(unittest.TestCase): def test_arg_handles_and_signature_attr(self):