hdl.ir: fix port propagation between siblings.
authorwhitequark <whitequark@whitequark.org>
Fri, 21 Dec 2018 23:53:18 +0000 (23:53 +0000)
committerwhitequark <whitequark@whitequark.org>
Fri, 21 Dec 2018 23:53:18 +0000 (23:53 +0000)
nmigen/hdl/ir.py
nmigen/test/test_hdl_ir.py

index 018fa9af7a83c87a8edb531991d6de9bd126981b..1d6a79f2dd59e594ddda3d7ee37c442fd5bb3b73 100644 (file)
@@ -270,9 +270,9 @@ class Fragment:
 
         # Go through subfragments and refine our approximation for ports.
         for subfrag, name in self.subfragments:
-            # Always ask subfragments to provide all signals we're using and signals we're asked
-            # to provide. If the subfragment is not driving it, it will silently ignore it.
-            sub_ins, sub_outs, sub_inouts = subfrag._propagate_ports(ports=self_used | ports)
+            # Always ask subfragments to provide all signals that are our inputs.
+            # If the subfragment is not driving it, it will silently ignore it.
+            sub_ins, sub_outs, sub_inouts = subfrag._propagate_ports(ports=ins | ports)
             # Refine the input port approximation: if a subfragment is driving a signal,
             # it is definitely not our input. But, if a subfragment requires a signal as an input,
             # and we aren't driving it, it has to be our input as well.
index bd71ecabbe6cabe63013b7686fde93d7ac2ae19b..06c45e34e31521073184c887555e4929bab13de8 100644 (file)
@@ -117,6 +117,23 @@ class FragmentPortsTestCase(FHDLTestCase):
             (self.c2, "o"),
         ]))
 
+    def test_input_output_sibling(self):
+        f1 = Fragment()
+        f2 = Fragment()
+        f2.add_statements(
+            self.c1.eq(self.c2)
+        )
+        f1.add_subfragment(f2)
+        f3 = Fragment()
+        f3.add_statements(
+            self.c2.eq(0)
+        )
+        f3.add_driver(self.c2)
+        f1.add_subfragment(f3)
+
+        f1._propagate_ports(ports=())
+        self.assertEqual(f1.ports, SignalDict())
+
     def test_input_cd(self):
         sync = ClockDomain()
         f = Fragment()