compat.fhdl.module: implement finalization.
authorwhitequark <whitequark@whitequark.org>
Thu, 13 Dec 2018 02:36:15 +0000 (02:36 +0000)
committerwhitequark <whitequark@whitequark.org>
Thu, 13 Dec 2018 02:36:15 +0000 (02:36 +0000)
nmigen/compat/fhdl/module.py
nmigen/fhdl/ast.py
nmigen/fhdl/dsl.py

index c5432bd65b190d4643d3f3b02075628970f71027..fb2d22a6324e0805a23e52a32b783e26825ee2f6 100644 (file)
@@ -58,14 +58,12 @@ class _CompatModuleSync(_CompatModuleProxy):
             raise AttributeError("Attempted to assign sync property - use += instead")
 
 
-class _CompatModuleForwardAttr:
+class _CompatModuleSpecials(_CompatModuleProxy):
     @deprecated("TODO")
     def __setattr__(self, name, value):
         self.__iadd__(value)
         setattr(self._cm, name, value)
 
-
-class _CompatModuleSpecials(_CompatModuleProxy, _CompatModuleForwardAttr):
     @deprecated("TODO")
     def __iadd__(self, other):
         self._cm._fragment.specials |= set(_flat_list(other))
@@ -73,18 +71,23 @@ class _CompatModuleSpecials(_CompatModuleProxy, _CompatModuleForwardAttr):
 
 
 class _CompatModuleSubmodules(_CompatModuleProxy):
-    @deprecated("TODO")
+    @deprecated("instead of `self.submodules.<mod> =`, use `m.submodules.<mod> =`")
     def __setattr__(self, name, value):
         self._cm._submodules += [(name, e) for e in _flat_list(value)]
         setattr(self._cm, name, value)
 
-    @deprecated("TODO")
+    @deprecated("instead of `self.submodules +=`, use `m.submodules +=`")
     def __iadd__(self, other):
         self._cm._submodules += [(None, e) for e in _flat_list(other)]
         return self
 
 
-class _CompatModuleClockDomains(_CompatModuleProxy, _CompatModuleForwardAttr):
+class _CompatModuleClockDomains(_CompatModuleProxy):
+    @deprecated("TODO")
+    def __setattr__(self, name, value):
+        self.__iadd__(value)
+        setattr(self._cm, name, value)
+
     @deprecated("TODO")
     def __iadd__(self, other):
         self._cm._fragment.clock_domains += _flat_list(other)
@@ -92,11 +95,12 @@ class _CompatModuleClockDomains(_CompatModuleProxy, _CompatModuleForwardAttr):
 
 
 class CompatModule:
+    # Actually returns nmigen.fhdl.Module, not a Fragment.
     def get_fragment(self):
         assert not self.get_fragment_called
         self.get_fragment_called = True
         self.finalize()
-        return self._fragment
+        return self._module
 
     def __getattr__(self, name):
         if name == "comb":
@@ -128,5 +132,20 @@ class CompatModule:
             raise AttributeError("'{}' object has no attribute '{}'"
                                  .format(type(self).__name__, name))
 
+    def _finalize_submodules(self):
+        for name, submodule in self._submodules:
+            if not submodule.get_fragment_called:
+                self._module._add_submodule(submodule.get_fragment(), name)
+
+    def finalize(self, *args, **kwargs):
+        if not self.finalized:
+            self.finalized = True
+            self._finalize_submodules()
+            self.do_finalize(*args, **kwargs)
+            self._finalize_submodules()
+
+    def do_finalize(self):
+        pass
+
 
 Module = CompatModule
index 876b12c0991e6f0da2d0616f4b30aa6956ef88c7..123e2aedc40e3b5d6c1ff284fa05dc04c0c91ed1 100644 (file)
@@ -545,7 +545,7 @@ class Signal(Value, DUID):
         other : Value
             Object to base this Signal on.
         """
-        kw = dict(shape=cls.wrap(other).shape())
+        kw = dict(shape=cls.wrap(other).shape(), name=tracer.get_var_name())
         if isinstance(other, cls):
             kw.update(reset=other.reset, reset_less=other.reset_less, attrs=other.attrs)
         kw.update(kwargs)
index d5b73b9e4c756962b29fbdd7d0170e40e60affb4..db04892ce98b3eec580bd3b09e2b9c6cecc1d47e 100644 (file)
@@ -53,6 +53,8 @@ class _ModuleBuilderRoot:
         if name in ("comb", "sync"):
             raise AttributeError("'{}' object has no attribute '{}'; did you mean 'd.{}'?"
                                  .format(type(self).__name__, name, name))
+        raise AttributeError("'{}' object has no attribute '{}'"
+                             .format(type(self).__name__, name))
 
 
 class _ModuleBuilderIf(_ModuleBuilderRoot):
@@ -223,7 +225,7 @@ class Module(_ModuleBuilderRoot):
     def _add_submodule(self, submodule, name=None):
         if not hasattr(submodule, "get_fragment"):
             raise TypeError("Trying to add {!r}, which does not have .get_fragment(), as "
-                            " a submodule")
+                            "a submodule".format(submodule))
         self._submodules.append((submodule, name))
 
     def lower(self, platform):
@@ -237,3 +239,5 @@ class Module(_ModuleBuilderRoot):
             for lhs_signal in signal._lhs_signals():
                 fragment.drive(lhs_signal, cd_name)
         return fragment
+
+    get_fragment = lower