Improve (hopefully) `Module` submodule facility.
authorJock Tanner <tanner.of.kha@gmail.com>
Mon, 6 Apr 2020 04:42:45 +0000 (04:42 +0000)
committerJock Tanner <tanner.of.kha@gmail.com>
Mon, 6 Apr 2020 04:42:45 +0000 (04:42 +0000)
experiments7/doAlu16.py
experiments7/utils.py

index 5116f67f08ad644a555a945c18431576020b6643..9af989a48616327d4da93475b6d8162fd0890018 100755 (executable)
@@ -74,6 +74,9 @@ class ALU16(Module):
         if not self.build_submodules():
             return False
 
+        # at this point we have the (auto-calculated) submodules' dimensions
+        # in their `ab` properties.
+
         with SessionManager():
             self.init_ab()
             self.place_submodules()
index af4368dd29591edeb58eb6ae42ba6a6a88df9e76..3ec61559833fb29aaffdf8ac268676a7e8db1c97 100644 (file)
@@ -42,7 +42,9 @@ class Module(object):
         :param editor: editor object when executing from cgt (or None),
         :param width: module width,
         :param height: module height,
-        :param submodules: submodules (Module objects),
+        :param submodules: submodules (Module objects)
+          or tuples of (submodule, x, y), where (x, y) is a submodule's
+          placement point (in lambdas, defaults to (0.0, 0.0)),
         :param pin_width: default pin width,
         :param pin_height: default pin height,
         :param pin_suffix: default pin suffix,
@@ -82,7 +84,13 @@ class Module(object):
 
         self.pads = pads or {}
 
-        self.submodules = submodules or []
+        self._submodules = []
+        if submodules is not None:
+            for submodule in submodules:
+                self._submodules.append(
+                    (submodule, 0.0, 0.0) if isinstance(submodule, Module)
+                    else submodule
+                )
 
     @property
     def name(self):
@@ -292,6 +300,21 @@ class Module(object):
         for net, layers in self.pads.items():
             self.create_pads_for_net(net, layers)
 
+    @property
+    def submodules(self):
+        """ Submodules iterator. """
+        return iter(submodule for submodule, x, y in self._submodules)
+
+    def find_submodule(self, name):
+        """
+        Returns first submodule matching `name`. Better give your submodules
+        unique names.
+
+        :param name: submodule name to match,
+        :return: `Module` object.
+        """
+        return next(s for s in self.submodules if s.name == name)
+
     def build_submodules(self):
         """
         Execute submodules and gather their status.
@@ -299,28 +322,41 @@ class Module(object):
         :return: True if all submodules executed successfully, False otherwise.
         """
 
-        for submodule, x, y in self.submodules:
+        for submodule in self.submodules:
             if not submodule.build():
                 return False
 
         return True
 
-    def place_submodules(self):
-        """ Place submodules in the current module. """
+    def place_submodule(self, submodule, x, y):
+        """
+        Places a submodule to a given location.
 
-        for submodule, x, y in self.submodules:
-            # find instance
-            instance = [
-                inst for inst in self.instances if inst.getName().endswith(
-                    submodule.name
-                )
-            ][0]
+        :param submodule: `Module` object,
+        :param x: placement coordinate,
+        :param y: placement coordinate.
+        """
+
+        # find instance
+        instance = [
+            inst for inst in self.instances if inst.getName().endswith(
+                submodule.name
+            )
+        ][0]
 
-            # place submodule
-            instance.setTransformation(Transformation(
-                self.to_dbu(x), self.to_dbu(y), Transformation.Orientation.ID
-            ))
-            instance.setPlacementStatus(Instance.PlacementStatus.FIXED)
+        # place submodule
+        instance.setTransformation(Transformation(
+            self.to_dbu(x), self.to_dbu(y), Transformation.Orientation.ID
+        ))
+        instance.setPlacementStatus(Instance.PlacementStatus.FIXED)
+
+    def place_submodules(self):
+        """
+        Places the submodules in the current module using their initial
+        placement points.
+        """
+        for submodule, x, y in self._submodules:
+            self.place_submodule(submodule, x, y)
 
     def save(self):
         """ Saves cell. """