Enable the heavy leaf load on the main clock.
[soclayout.git] / experiments7 / doAlu16.py
index d6fa7460d2db89760957f7c410539bcfbaf13c3a..1b8248fe3c877c75b59cf23a6edee2481897af6d 100755 (executable)
@@ -2,7 +2,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import print_function
 import sys
-import re
 
 import CRL
 import Cfg
@@ -12,11 +11,14 @@ from Hurricane import Breakpoint
 from Hurricane import Instance
 from coriolis2.settings import af
 from utils import Module, SessionManager, Config
+import Etesian
+import helpers
+from helpers.overlay import UpdateSession
 
 import symbolic.cmos  # do not remove
 
 BIT_WIDTH = 16
-
+widths = {32: 600.0, 16: 490}
 
 def coriolis_setup():
     with Config(Cfg.Parameter.Priority.UserFile) as cfg:
@@ -68,35 +70,6 @@ class AddSub(Module):
 
 class ALU16(Module):
 
-    @staticmethod
-    def match_instance(datapath_insts, op, plug_name, inst):
-        """
-        Guess the position of an instance from its nets connections,
-        and put it at the right place in the datapath vector.
-
-        :param datapath_insts: vector of bit slices,
-        :param op: operator name,
-        :param inst: instance to classify,
-        :param plug_name: name of the plug to use to guess the bit index,
-        :return: boolean, True if the instance has been matched.
-        """
-        if not inst.getMasterCell().getName().startswith(op):
-            return False
-        re_net_index = re.compile(r'[^(]+\((?P<index>[\d]+)\)$')
-        for plug in inst.getPlugs():
-            if plug.getMasterNet().getName() != plug_name:
-                continue
-            m = re_net_index.match(plug.getNet().getName())
-            if not m:
-                continue
-            bit_slice = datapath_insts[int(m.group('index'))]
-            for column in bit_slice:
-                if column[0] == op:
-                    column[1] = inst
-                    return True
-            break
-        return False
-
     def place_datapath(self, datapath_insts, x_orig, y_orig, fold):
         channel_sff1 = self.to_dbu(0)
         with SessionManager():
@@ -122,13 +95,61 @@ class ALU16(Module):
     def place(self):
         """ALU16.place(), manual placement overload."""
         datapath_insts = []
+        add, sub = self.submodules
+        #print (sub.ab, dir(list(sub.cell.getInstances())[0]))
+        #print (list(sub.cell.getInstances())[0].getAbutmentBox())
+        subx = widths[BIT_WIDTH] - 40 #self.from_dbu(sub.ab.getXMax())
+        addx = self.from_dbu(add.ab.getWidth()) + 5
+
         for i in range(BIT_WIDTH):
-            datapath_insts.append([['nmx2', None], ['no2', None], ['sff1', None]])
+            dp = [['nmx2', None],
+                  ['no2', None],
+                  ['sff1', None]]
+
+            # XXX here is the computed abutment box which we want to
+            # place the auto-located cells into, using *auto* place
+            # *not* manual place.
+            y = 40.0 + i * 50
+            y1 = y + 50
+            ab = Box(self.to_dbu(addx), self.to_dbu(y),
+                     self.to_dbu(subx), self.to_dbu(y1))
+            print ("ab", addx, subx, ab, self.from_dbu(ab.getWidth()),
+                                         self.from_dbu(ab.getHeight()))
+
+            # automatically locate all non-placed cells connected to
+            # o(0)....o(15)
+            find = self.get_net_connections(['o(%d)' % i],
+                                        ['clk', 'rst', 'op'])
+            for inst in find:
+                print (inst, inst.getName(), dir(inst))
+                print ("place", ab, inst, dir(inst))
+                for column in dp:
+                    if inst.getName().find(column[0]) != -1:
+                        column[1] = inst
+                # XXX TODO: want to auto-place the instances
+                #with SessionManager():
+                    #cell.setAbutmentBox(ab)
+                    #etesian = Etesian.EtesianEngine.create(cell)
+                    #etesian.place()
+            datapath_insts.append(dp)
+
+        # place to right of add
+        add, sub = self.submodules
+        add_wid = self.from_dbu(add.ab.getWidth())
+        self.place_datapath(datapath_insts, add_wid, 40.0, 1)
+
+    def _old_place(self):
+        """ALU16.place(), manual placement overload."""
+        datapath_insts = []
+        for i in range(BIT_WIDTH):
+            datapath_insts.append([['nmx2', None],
+                                   ['no2', None],
+                                   ['sff1', None]])
 
         for inst in self.cell.getInstances():
-            if (ALU16.match_instance(datapath_insts, 'nmx2', 'i0', inst) or
-                ALU16.match_instance(datapath_insts, 'no2', 'nq', inst) or
-                ALU16.match_instance(datapath_insts, 'sff1', 'i', inst)):
+            if (Module.match_instance(datapath_insts, 'nmx2', 'i0', inst) or
+                Module.match_instance(datapath_insts, 'no2', 'nq', inst) or
+                Module.match_instance(datapath_insts, 'sff1', 'i', inst)):
                 continue
 
         # place to right of add
@@ -165,7 +186,7 @@ class ALU16(Module):
             ])) + v_margin
 
             # experiment, over-ride
-            width = 490
+            width = widths[BIT_WIDTH]
             #width = 1310
             #height = 370
 
@@ -185,6 +206,15 @@ class ALU16(Module):
 
             self.create_pins()
 
+        if False:
+            find = self.get_net_connections(['o(15)'],
+                                            ['clk', 'rst', 'op'])
+            print (find)
+            sys.exit(0)
+            find = self.get_net_connections(['o_next(0)'],
+                                            ['clk', 'vss', 'vdd', 'rst'])
+            print (find)
+
         if self.editor:
             self.editor.setCell(self.cell)
 
@@ -221,9 +251,12 @@ def scriptMain(editor=None, **kwargs):
     add = AddSub(
         'add', editor,
         east_pins=[
-            {'net': 'a({})', 'y': 15.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
-            {'net': 'b({})', 'y': 20.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
-            {'net': 'o({})', 'y': 25.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'a({})', 'y': 15.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'b({})', 'y': 20.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'o({})', 'y': 25.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
         ],
         pads={
             'b({})'.format(BIT_WIDTH-1): (
@@ -232,13 +265,16 @@ def scriptMain(editor=None, **kwargs):
         },
         orientation=Transformation.Orientation.ID,
     )
-    add.set_ab(160.0, 800.0)
+    add.set_ab(160.0, 50.0 * BIT_WIDTH)
     sub = AddSub(
         'sub', editor,
         west_pins=[
-            {'net': 'a({})', 'y': 15.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
-            {'net': 'b({})', 'y': 20.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
-            {'net': 'o({})', 'y': 25.0, 'delta': 50.0, 'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'a({})', 'y': 15.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'b({})', 'y': 20.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
+            {'net': 'o({})', 'y': 25.0, 'delta': 50.0,
+                    'repeat': BIT_WIDTH, 'layer': 'METAL2'},
         ],
         pads={
             'b({})'.format(BIT_WIDTH-1): (
@@ -247,7 +283,7 @@ def scriptMain(editor=None, **kwargs):
         },
         orientation=Transformation.Orientation.ID,
     )
-    sub.set_ab(165.0, 800.0)
+    sub.set_ab(165.0, 50.0 * BIT_WIDTH)
 
     o = 00.0
     alu16 = ALU16(