hdl.ir: during port propagation, defs should take priority over uses.
authorwhitequark <whitequark@whitequark.org>
Mon, 13 May 2019 15:34:13 +0000 (15:34 +0000)
committerwhitequark <whitequark@whitequark.org>
Mon, 13 May 2019 15:34:13 +0000 (15:34 +0000)
nmigen/hdl/ir.py
nmigen/test/test_hdl_ir.py

index 6c050182a882d92a77a6c5f87fe02d30549cf783..21c78b5901ac90ed75ecec97d19987196448a294 100644 (file)
@@ -445,11 +445,6 @@ class Fragment:
         for sig in uses:
             if sig in defs:
                 lca  = reduce(lca_of, uses[sig], defs[sig])
-
-                frag = defs[sig]
-                while frag != lca:
-                    frag.add_ports(sig, dir="o")
-                    frag = parent[frag]
             else:
                 lca  = reduce(lca_of, uses[sig])
 
@@ -460,6 +455,12 @@ class Fragment:
                     frag.add_ports(sig, dir="i")
                     frag = parent[frag]
 
+            if sig in defs:
+                frag = defs[sig]
+                while frag != lca:
+                    frag.add_ports(sig, dir="o")
+                    frag = parent[frag]
+
         for sig in ios:
             frag = ios[sig]
             while frag is not None:
index 34a31e62d2d065d56e6050ea9167a6888e47a4e8..0e96662ada893d84650578e964d62f8943704a0b 100644 (file)
@@ -156,6 +156,27 @@ class FragmentPortsTestCase(FHDLTestCase):
             (self.c2, "o"),
         ]))
 
+    def test_output_from_subfragment_2(self):
+        f1 = Fragment()
+        f1.add_statements(
+            self.c1.eq(self.s1)
+        )
+        f2 = Fragment()
+        f2.add_statements(
+            self.c2.eq(self.s1)
+        )
+        f1.add_subfragment(f2)
+        f3 = Fragment()
+        f3.add_statements(
+            self.s1.eq(0)
+        )
+        f2.add_subfragment(f3)
+
+        f1._propagate_ports(ports=(), all_undef_as_ports=True)
+        self.assertEqual(f2.ports, SignalDict([
+            (self.s1, "o"),
+        ]))
+
     def test_input_output_sibling(self):
         f1 = Fragment()
         f2 = Fragment()