compat.fhdl.module: fix finalization of transformed compat submodules.
authorwhitequark <cz@m-labs.hk>
Thu, 8 Aug 2019 07:45:34 +0000 (07:45 +0000)
committerwhitequark <cz@m-labs.hk>
Thu, 8 Aug 2019 07:45:34 +0000 (07:45 +0000)
Before this commit, the TransformedElaboratable of a CompatModule
would be ignored, and .get_fragment() would be used to retrieve
the CompatModule within.

After this commit, the finalization process is reworked to match
oMigen's finalization closely, and all submodules, native and compat,
are added in the same way that preserves applied transforms.

nmigen/compat/fhdl/module.py

index f4622b02fff7531844786480a507a2e12e88ab91..4431b84a2ab78126aae7b5fdf16d34532f619a31 100644 (file)
@@ -105,7 +105,9 @@ class CompatModule(ir.Elaboratable):
         return self._module
 
     def elaborate(self, platform):
-        return self.get_fragment()
+        if not self.get_fragment_called:
+            self.get_fragment()
+        return self._module
 
     def __getattr__(self, name):
         if name == "comb":
@@ -137,22 +139,22 @@ class CompatModule(ir.Elaboratable):
             raise AttributeError("'{}' object has no attribute '{}'"
                                  .format(type(self).__name__, name))
 
-    def _finalize_submodules(self, finalize_native):
-        for name, submodule in self._submodules:
-            if hasattr(submodule, "get_fragment_called"):
-                # Compat submodule
-                if not submodule.get_fragment_called:
-                    self._module._add_submodule(submodule.get_fragment(), name)
-            elif finalize_native:
-                # Native submodule
-                self._module._add_submodule(submodule, name)
-
     def finalize(self, *args, **kwargs):
+        def finalize_submodules():
+            for name, submodule in self._submodules:
+                if not hasattr(submodule, "finalize"):
+                    continue
+                if submodule.finalized:
+                    continue
+                submodule.finalize(*args, **kwargs)
+
         if not self.finalized:
             self.finalized = True
-            self._finalize_submodules(finalize_native=False)
+            finalize_submodules()
             self.do_finalize(*args, **kwargs)
-            self._finalize_submodules(finalize_native=True)
+            finalize_submodules()
+            for name, submodule in self._submodules:
+                self._module._add_submodule(submodule, name)
 
     def do_finalize(self):
         pass