Attempt to auto-place ALU16.
authorJock Tanner <tanner.of.kha@gmail.com>
Mon, 6 Apr 2020 14:11:17 +0000 (14:11 +0000)
committerJock Tanner <tanner.of.kha@gmail.com>
Mon, 6 Apr 2020 14:11:17 +0000 (14:11 +0000)
experiments7/doAlu16.py
experiments7/utils.py

index 9af989a48616327d4da93475b6d8162fd0890018..435c619e4de678c36073c822494622d8686b7416 100755 (executable)
@@ -71,18 +71,33 @@ class ALU16(Module):
 
     def build(self):
 
+        h_margin = 25.0
+        v_margin = 75.0
+
         if not self.build_submodules():
             return False
 
         # at this point we have the (auto-calculated) submodules' dimensions
         # in their `ab` properties.
 
+        add, sub = self.submodules
+
         with SessionManager():
-            self.init_ab()
-            self.place_submodules()
+            self.compute_ab()
+
+            width = self.from_dbu(
+                self.ab.getWidth() + add.ab.getWidth() + sub.ab.getWidth()
+            ) + 4*h_margin
+            height = self.from_dbu(max([
+                self.ab.getHeight(), add.ab.getHeight(), sub.ab.getHeight()
+            ])) + 2*v_margin
+            self.ab = Box(0, 0, self.to_dbu(width), self.to_dbu(height))
+
+            self.place_submodule(add, h_margin, v_margin)
+            self.place_submodule(sub, width-sub.ab_width-h_margin, v_margin)
 
             # TODO: replace with some form of lazy evaluation?
-            y_north = self.from_dbu(self.cell.getAbutmentBox().getYMax())
+            y_north = self.from_dbu(self.ab.getYMax())
             for pin_conf in self.north_pins:
                 pin_conf['y'] = y_north
 
@@ -95,14 +110,18 @@ class ALU16(Module):
         # this puts all the remaining cells (little ones)
         # into this (small) space so that they do not go
         # "all over the place" around the add and sub
-        self.ab = Box(self.to_dbu(400.0), self.to_dbu(50.0),
-                      self.to_dbu(700.0), self.to_dbu(500.0))
+        self.ab = Box(
+            self.to_dbu((width-self.ab_width)/2 - h_margin),
+            self.to_dbu(v_margin),
+            self.to_dbu((width+self.ab_width)/2 + h_margin),
+            self.to_dbu(height - v_margin)
+        )
         self.place()
 
         # then route (globally)
         # this connects up not just in the remaining (little) cells,
         # it connects *to add and sub and the outside world as well*
-        self.init_ab()
+        self.ab = Box(0, 0, self.to_dbu(width), self.to_dbu(height))
         result = self.place_and_route()
 
         self.save()
@@ -144,8 +163,7 @@ def ScriptMain(editor=None, **kwargs):
     )
 
     alu16 = ALU16(
-        'alu16', editor, width=1100.0, height=570.0,
-        submodules=[(add, 25.0, 75.0), (sub, 725.0, 75.0)],
+        'alu16', editor, submodules=[add, sub],
         north_pins=[
             {'net': 'o({})', 'x': 50.0, 'delta': 60.0, 'repeat': BIT_WIDTH},
             {'net': 'op'},
index 62ba52822df58da982d3e925efc96f298b7d7a7a..5e5738f1f5cfdf130bf82cb80dbd3ddc85017dec 100644 (file)
@@ -143,6 +143,22 @@ class Module(object):
         """
         return DbU.toLambda(dbu)
 
+    @property
+    def ab_x(self):
+        return self.from_dbu(self.ab.getXMin())
+
+    @property
+    def ab_y(self):
+        return self.from_dbu(self.ab.getYMin())
+
+    @property
+    def ab_width(self):
+        return self.from_dbu(self.ab.getWidth())
+
+    @property
+    def ab_height(self):
+        return self.from_dbu(self.ab.getXHeight())
+
     def compute_ab(self):
         """ Compute default abutment box without placement. """
         etesian = Etesian.EtesianEngine.create(self.cell)