hdl.ir: resolve hierarchy conflicts before creating missing domains.
Otherwise, code such as: m.submodules.a = (something with cd_sync) m.submodules.b = (something with cd_sync) m.d.b_sync += x.eq(y) causes an assertion failure. Fixes #304 (again).
This commit is contained in:
parent
7cb3095334
commit
a7be3b480a
|
@ -203,6 +203,15 @@ class Fragment:
|
|||
driver_subfrags = SignalDict()
|
||||
memory_subfrags = OrderedDict()
|
||||
def add_subfrag(registry, entity, entry):
|
||||
# Because of missing domain insertion, at the point when this code runs, we have
|
||||
# a mixture of bound and unbound {Clock,Reset}Signals. Map the bound ones to
|
||||
# the actual signals (because the signal itself can be driven as well); but leave
|
||||
# the unbound ones as it is, because there's no concrete signal for it yet anyway.
|
||||
if isinstance(entity, ClockSignal) and entity.domain in self.domains:
|
||||
entity = self.domains[entity.domain].clk
|
||||
elif isinstance(entity, ResetSignal) and entity.domain in self.domains:
|
||||
entity = self.domains[entity.domain].rst
|
||||
|
||||
if entity not in registry:
|
||||
registry[entity] = set()
|
||||
registry[entity].add(entry)
|
||||
|
@ -387,12 +396,15 @@ class Fragment:
|
|||
"requested domain '{}' (defines {})."
|
||||
.format(domain_name, ", ".join("'{}'".format(n) for n in defined)))
|
||||
self.add_subfragment(new_fragment, "cd_{}".format(domain_name))
|
||||
self.add_domains(new_fragment.domains.values())
|
||||
return new_domains
|
||||
|
||||
def _propagate_domains(self, missing_domain):
|
||||
new_domains = self.create_missing_domains(missing_domain)
|
||||
self._propagate_domains_up()
|
||||
self._propagate_domains_down()
|
||||
self._resolve_hierarchy_conflicts()
|
||||
new_domains = self.create_missing_domains(missing_domain)
|
||||
self._propagate_domains_down()
|
||||
return new_domains
|
||||
|
||||
def _prepare_use_def_graph(self, parent, level, uses, defs, ios, top):
|
||||
|
@ -543,7 +555,6 @@ class Fragment:
|
|||
fragment = SampleLowerer()(self)
|
||||
new_domains = fragment._propagate_domains(missing_domain)
|
||||
fragment = DomainLowerer()(fragment)
|
||||
fragment._resolve_hierarchy_conflicts()
|
||||
if ports is None:
|
||||
fragment._propagate_ports(ports=(), all_undef_as_ports=True)
|
||||
else:
|
||||
|
|
|
@ -408,6 +408,22 @@ class FragmentDomainsTestCase(FHDLTestCase):
|
|||
None: SignalSet((ResetSignal("b_sync"),))
|
||||
}))
|
||||
|
||||
def test_domain_conflict_rename_drivers(self):
|
||||
cda = ClockDomain("sync")
|
||||
cdb = ClockDomain("sync")
|
||||
s = Signal()
|
||||
|
||||
fa = Fragment()
|
||||
fa.add_domains(cda)
|
||||
fb = Fragment()
|
||||
fb.add_domains(cdb)
|
||||
f = Fragment()
|
||||
f.add_subfragment(fa, "a")
|
||||
f.add_subfragment(fb, "b")
|
||||
f.add_driver(s, "b_sync")
|
||||
|
||||
f._propagate_domains(lambda name: ClockDomain(name))
|
||||
|
||||
def test_propagate_down(self):
|
||||
cd = ClockDomain()
|
||||
|
||||
|
|
Loading…
Reference in a new issue