build.plat: align pipeline with Fragment.prepare().
authorwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 03:24:26 +0000 (03:24 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 1 Feb 2020 03:26:04 +0000 (03:26 +0000)
Since commit 7257c20a, platform code calls create_missing_domains()
before _propagate_domains_up() (as a part of prepare() call). Since
commit a7be3b48, without a platform, create_missing_domains() is
calle after _propagate_domains_up(); because of that, it adds
the missing domain to the fragment. When platform code then calls
prepare() again, this causes an assertion failure.

The true intent behind the platform code being written this way is
that it *overrides* a part of prepare()'s mechanism. Because it was
not changed when prepare() was modified in 7257c20a, the override,
which happened to work by coincidence, stopped working. This is
now fixed by inlining the relevant parts of Fragment.prepare() into
Platform.prepare().

This is not a great solution, but given the amount of breakage this
causes (no platform-using code works), it is acceptable for now.

Fixes #307.

nmigen/build/plat.py
nmigen/hdl/ir.py

index 174cda7e7fd76af984a60199ea8b076ebee0f544..422cc857ef6252bc93e46373e499b9e308176777 100644 (file)
@@ -8,6 +8,7 @@ import jinja2
 from .. import __version__
 from .._toolchain import *
 from ..hdl import *
+from ..hdl.xfrm import SampleLowerer, DomainLowerer
 from ..lib.cdc import ResetSynchronizer
 from ..back import rtlil, verilog
 from .res import *
@@ -115,7 +116,9 @@ class Platform(ResourceManager, metaclass=ABCMeta):
         self._prepared = True
 
         fragment = Fragment.get(elaboratable, self)
-        fragment.create_missing_domains(self.create_missing_domain, platform=self)
+        fragment = SampleLowerer()(fragment)
+        fragment._propagate_domains(self.create_missing_domain, platform=self)
+        fragment = DomainLowerer()(fragment)
 
         def add_pin_fragment(pin, pin_fragment):
             pin_fragment = Fragment.get(pin_fragment, self)
@@ -144,7 +147,7 @@ class Platform(ResourceManager, metaclass=ABCMeta):
                 add_pin_fragment(pin,
                     self.get_diff_input_output(pin, p_port, n_port, attrs, invert))
 
-        fragment = fragment.prepare(ports=self.iter_ports(), missing_domain=lambda name: None)
+        fragment._propagate_ports(ports=self.iter_ports(), all_undef_as_ports=False)
         return self.toolchain_prepare(fragment, name, **kwargs)
 
     @abstractmethod
index cea9b4034d7f9755d942fd8cb814340e77e90379..8c169ada820ab17b7cd026b3caf1ca1efa359b5b 100644 (file)
@@ -343,7 +343,7 @@ class Fragment:
 
             subfrag._propagate_domains_down()
 
-    def create_missing_domains(self, missing_domain, *, platform=None):
+    def _create_missing_domains(self, missing_domain, *, platform=None):
         from .xfrm import DomainCollector
 
         collector = DomainCollector()
@@ -373,11 +373,11 @@ class Fragment:
                 self.add_domains(new_fragment.domains.values())
         return new_domains
 
-    def _propagate_domains(self, missing_domain):
+    def _propagate_domains(self, missing_domain, *, platform=None):
         self._propagate_domains_up()
         self._propagate_domains_down()
         self._resolve_hierarchy_conflicts()
-        new_domains = self.create_missing_domains(missing_domain)
+        new_domains = self._create_missing_domains(missing_domain, platform=platform)
         self._propagate_domains_down()
         return new_domains