hdl.ir: fix port propagation between siblings, in the other direction.
authorwhitequark <cz@m-labs.hk>
Sat, 22 Dec 2018 00:31:31 +0000 (00:31 +0000)
committerwhitequark <cz@m-labs.hk>
Sat, 22 Dec 2018 00:31:31 +0000 (00:31 +0000)
nmigen/hdl/ir.py
nmigen/test/test_hdl_ir.py

index 1d6a79f2dd59e594ddda3d7ee37c442fd5bb3b73..f9a4774973d642f288f2959e9d9a6d087152439a 100644 (file)
@@ -268,16 +268,20 @@ class Fragment:
         # an underapproximation: some of these signals may be driven by subfragments.
         outs = ports & self_driven
 
-        # Go through subfragments and refine our approximation for ports.
+        # Go through subfragments and refine our approximation for inputs.
+        for subfrag, name in self.subfragments:
+            # Refine the input port approximation: if a subfragment requires a signal as an input,
+            # and we aren't driving it, it has to be our input as well.
+            sub_ins, sub_outs, sub_inouts = subfrag._propagate_ports(ports=())
+            ins  |= sub_ins - self_driven
+
         for subfrag, name in self.subfragments:
             # 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.
+            # Refine the input port appropximation further: if any subfragment is driving a signal
+            # that we currently think should be our input, it shouldn't actually be our input.
             ins  -= sub_outs
-            ins  |= sub_ins - self_driven
             # Refine the output port approximation: if a subfragment is driving a signal,
             # and we're asked to provide it, we can provide it now.
             outs |= ports & sub_outs
index 06c45e34e31521073184c887555e4929bab13de8..0df49ab59588e8def4c3aad7b957b375c961daa0 100644 (file)
@@ -134,6 +134,23 @@ class FragmentPortsTestCase(FHDLTestCase):
         f1._propagate_ports(ports=())
         self.assertEqual(f1.ports, SignalDict())
 
+    def test_output_input_sibling(self):
+        f1 = Fragment()
+        f2 = Fragment()
+        f2.add_statements(
+            self.c2.eq(0)
+        )
+        f2.add_driver(self.c2)
+        f1.add_subfragment(f2)
+        f3 = Fragment()
+        f3.add_statements(
+            self.c1.eq(self.c2)
+        )
+        f1.add_subfragment(f3)
+
+        f1._propagate_ports(ports=())
+        self.assertEqual(f1.ports, SignalDict())
+
     def test_input_cd(self):
         sync = ClockDomain()
         f = Fragment()