build.plat: align pipeline with Fragment.prepare().

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.
This commit is contained in:
whitequark 2020-02-01 03:24:26 +00:00
parent 6fd7cbad0d
commit cce6b8687b
2 changed files with 8 additions and 5 deletions

View 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

View 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