use --recursive on git submodule not --remote - one does a "latest update"
[soclayout.git] / experiments7 / utils.py
index e575bd33afff19ea64933c8caeaec05019b86dc7..4dcb8890a57df1150d2a2f08ebc5b16c5782e10c 100644 (file)
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import print_function
+import re
 
 import Anabatic
 import CRL
@@ -164,6 +165,37 @@ class Module(object):
     def ab_height(self):
         return self.from_dbu(self.ab.getXHeight())
 
+    @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
+                    print ("match", plug_name, int(m.group('index')),
+                            column, inst)
+                    return True
+            break
+        return False
+
     def compute_ab(self):
         """ Compute default abutment box without placement. """
         etesian = Etesian.EtesianEngine.create(self.cell)
@@ -191,7 +223,7 @@ class Module(object):
         katana.loadGlobalRouting(Anabatic.EngineLoadGrByNet)
         katana.layerAssign(Anabatic.EngineNoNetLayerAssign)
         katana.runNegociate(Katana.Flags.NoFlags)
-        Breakpoint.stop(0, 'After routing {0}'.format(self.cell))
+        #Breakpoint.stop(0, 'After routing {0}'.format(self.cell))
         katana.finalizeLayout()
         result = katana.isDetailedRoutingSuccess()
         katana.destroy()
@@ -403,6 +435,10 @@ class Module(object):
 
         raise NotImplementedError('You need to implement the `build` method.')
 
+    def get_net_connections(self, to_find, already_found):
+        inst = self.cell.getInstances()
+        return get_net_connections(inst, to_find, already_found)
+
 
 class Config:
 
@@ -436,3 +472,39 @@ class Config:
         if self._priority is not None:
             Cfg.Configuration.popDefaultPriority()
 
+
+def get_net_connections(instances, find, already_found):
+    res = set()
+    new = set()
+    search_more = []
+    for inst in instances:
+        if (inst.getPlacementStatus() !=
+                Instance.PlacementStatus.UNPLACED):
+            continue
+        #print ("instance", inst)
+        for plug in inst.getConnectedPlugs():
+            netname = plug.getNet().getName()
+            if netname in already_found:
+                continue
+            if plug.getNet().getName() in find:
+                #print ("plug", plug, plug.getNet().getName())
+                for p in plug.getNet().getPlugs():
+                    c = p.getInstance()
+                    if (c.getPlacementStatus() !=
+                            Instance.PlacementStatus.UNPLACED):
+                        continue
+                    #print ("notplaced", c)
+                    for pc in c.getConnectedPlugs():
+                        #print ("plug", pc)
+                        pn = pc.getNet().getName()
+                        if pn not in find and pn not in already_found:
+                            search_more.append(pn)
+                    new.add(c)
+    res.update(new)
+    if search_more:
+        print("more", search_more)
+        new_found = find + already_found
+        more = get_net_connections(new, search_more, new_found)
+        res.update(more)
+
+    return res