if domain_name is None:
continue
if domain_name not in self.domains:
- domain = missing_domain(domain_name)
- if domain is None:
+ value = missing_domain(domain_name)
+ if value is None:
raise DomainError("Domain '{}' is used but not defined".format(domain_name))
+ if type(value) is ClockDomain:
+ domain = value
+ else:
+ new_fragment = Fragment.get(value, platform=None)
+ if new_fragment.domains.keys() != {domain_name}:
+ raise DomainError(
+ "Fragment returned by missing domain callback should define exactly "
+ "one domain '{}', but defines domain(s) {}."
+ .format(domain_name,
+ ", ".join("'{}'".format(n)
+ for n in new_fragment.domains.keys())))
+ new_fragment.flatten = True
+ self.add_subfragment(new_fragment)
+ domain = new_fragment.domains[domain_name]
self.add_domains(domain)
new_domains.append(domain)
return new_domains
f1.add_domains(cd)
f1.add_subfragment(f2)
- f1._propagate_domains(missing_domain=lambda name: None)
+ new_domains = f1._propagate_domains(missing_domain=lambda name: None)
self.assertEqual(f1.domains, {"cd": cd})
self.assertEqual(f2.domains, {"cd": cd})
+ self.assertEqual(new_domains, [])
def test_propagate_missing(self):
s1 = Signal()
f2 = Fragment()
f1.add_subfragment(f2)
- f1._propagate_domains(missing_domain=lambda name: ClockDomain(name))
+ new_domains = f1._propagate_domains(missing_domain=lambda name: ClockDomain(name))
self.assertEqual(f1.domains.keys(), {"sync"})
self.assertEqual(f2.domains.keys(), {"sync"})
self.assertEqual(f1.domains["sync"], f2.domains["sync"])
+ self.assertEqual(new_domains, [f1.domains["sync"]])
+
+ def test_propagate_create_missing_fragment(self):
+ s1 = Signal()
+ f1 = Fragment()
+ f1.add_driver(s1, "sync")
+
+ cd = ClockDomain("sync")
+ f2 = Fragment()
+ f2.add_domains(cd)
+
+ new_domains = f1._propagate_domains(missing_domain=lambda name: f2)
+ self.assertEqual(f1.domains.keys(), {"sync"})
+ self.assertEqual(f1.domains["sync"], f2.domains["sync"])
+ self.assertEqual(new_domains, [f1.domains["sync"]])
+ self.assertEqual(f1.subfragments, [
+ (f2, None)
+ ])
+ self.assertTrue(f2.flatten)
+
+ def test_propagate_create_missing_fragment_wrong(self):
+ s1 = Signal()
+ f1 = Fragment()
+ f1.add_driver(s1, "sync")
+
+ f2 = Fragment()
+ f2.add_domains(ClockDomain("foo"))
+
+ with self.assertRaises(DomainError,
+ msg="Fragment returned by missing domain callback should define exactly "
+ "one domain 'sync', but defines domain(s) 'foo'."):
+ f1._propagate_domains(missing_domain=lambda name: f2)
class FragmentHierarchyConflictTestCase(FHDLTestCase):