hdl.dsl: check for unique domain name.
authorwhitequark <whitequark@whitequark.org>
Tue, 19 May 2020 23:40:49 +0000 (23:40 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 31 Dec 2021 13:31:22 +0000 (13:31 +0000)
Fixes #385.

nmigen/hdl/dsl.py
nmigen/test/test_hdl_dsl.py

index 85ae4722044c2d31c10fcb00154db7089b22bcb0..6a7f5f9934c50b2c155fe4d48f20f5ec1045ba17 100644 (file)
@@ -174,9 +174,9 @@ class Module(_ModuleBuilderRoot, Elaboratable):
         self._ctrl_stack   = []
 
         self._driving      = SignalDict()
-        self._named_submodules   = {}
-        self._anon_submodules = []
-        self._domains      = []
+        self._named_submodules = {}
+        self._anon_submodules  = []
+        self._domains      = {}
         self._generated    = {}
 
     def _check_context(self, construct, context):
@@ -523,7 +523,9 @@ class Module(_ModuleBuilderRoot, Elaboratable):
             raise AttributeError("No submodule named '{}' exists".format(name))
 
     def _add_domain(self, cd):
-        self._domains.append(cd)
+        if cd.name in self._domains:
+            raise NameError("Clock domain named '{}' already exists".format(cd.name))
+        self._domains[cd.name] = cd
 
     def _flush(self):
         while self._ctrl_stack:
@@ -541,6 +543,6 @@ class Module(_ModuleBuilderRoot, Elaboratable):
         fragment.add_statements(statements)
         for signal, domain in self._driving.items():
             fragment.add_driver(signal, domain)
-        fragment.add_domains(self._domains)
+        fragment.add_domains(self._domains.values())
         fragment.generated.update(self._generated)
         return fragment
index 1c5686b0b5ecfa526dbf5e90f044f958defc025d..72cf3dff4787a9f521b68567b5687864c3c1ec8f 100644 (file)
@@ -712,7 +712,7 @@ class DSLTestCase(FHDLTestCase):
         m = Module()
         m.domains.foo = ClockDomain()
         self.assertEqual(len(m._domains), 1)
-        self.assertEqual(m._domains[0].name, "foo")
+        self.assertEqual(m._domains["foo"].name, "foo")
 
     def test_domain_add_wrong(self):
         m = Module()
@@ -729,6 +729,13 @@ class DSLTestCase(FHDLTestCase):
                 msg="Clock domain name 'bar' must match name in `m.domains.foo += ...` syntax"):
             m.domains.foo = ClockDomain("bar")
 
+    def test_domain_add_wrong_duplicate(self):
+        m = Module()
+        m.domains += ClockDomain("foo")
+        with self.assertRaises(NameError,
+                msg="Clock domain named 'foo' already exists"):
+            m.domains += ClockDomain("foo")
+
     def test_lower(self):
         m1 = Module()
         m1.d.comb += self.c1.eq(self.s1)