hdl.ir: raise DomainError if a domain is used but not defined.
authorwhitequark <cz@m-labs.hk>
Sat, 3 Aug 2019 15:31:00 +0000 (15:31 +0000)
committerwhitequark <cz@m-labs.hk>
Sat, 3 Aug 2019 15:31:24 +0000 (15:31 +0000)
Before this commit, a KeyError would be raised elsewhere in guts of
hdl.ir, which is not helpful.

nmigen/hdl/ir.py
nmigen/test/test_hdl_ir.py

index 805c31c4f90a37059c561a480687a2bea93e894f..578509e92987a62a7baeb562a5361ac84f42e5af 100644 (file)
@@ -351,19 +351,24 @@ class Fragment:
 
             subfrag._propagate_domains_down()
 
-    def _propagate_domains(self, missing_domain):
+    def _create_missing_domains(self, missing_domain):
         from .xfrm import DomainCollector
 
-        self._propagate_domains_up()
         new_domains = []
         for domain_name in DomainCollector()(self):
             if domain_name is None:
                 continue
             if domain_name not in self.domains:
                 domain = missing_domain(domain_name)
-                if domain is not None:
-                    self.add_domains(domain)
-                    new_domains.append(domain)
+                if domain is None:
+                    raise DomainError("Domain '{}' is used but not defined".format(domain_name))
+                self.add_domains(domain)
+                new_domains.append(domain)
+        return new_domains
+
+    def _propagate_domains(self, missing_domain):
+        self._propagate_domains_up()
+        new_domains = self._create_missing_domains(missing_domain)
         self._propagate_domains_down()
         return new_domains
 
index f8efd8c34af479e4730b25fa786666e67360f88c..60c018943656f2cece58bd9e0ca77ae14631791d 100644 (file)
@@ -380,6 +380,15 @@ class FragmentDomainsTestCase(FHDLTestCase):
         self.assertEqual(f1.domains, {"cd": cd})
         self.assertEqual(f2.domains, {"cd": cd})
 
+    def test_propagate_missing(self):
+        s1 = Signal()
+        f1 = Fragment()
+        f1.add_driver(s1, "sync")
+
+        with self.assertRaises(DomainError,
+                msg="Domain 'sync' is used but not defined"):
+            f1._propagate_domains(missing_domain=lambda name: None)
+
     def test_propagate_create_missing(self):
         s1 = Signal()
         f1 = Fragment()