use --recursive on git submodule not --remote - one does a "latest update"
[soclayout.git] / experiments5 / ringoscillator.py
index 8451eb5b0b37447457172c1d0b613eb38a380bd4..afa48194c7a05c7d1c1715ee3d3d570fc7a6fbaa 100755 (executable)
@@ -4,6 +4,7 @@
 import sys
 import re
 import traceback
+import shutil
 import os.path
 import optparse
 import Cfg
@@ -218,7 +219,7 @@ def add ( cell, **kw ):
 
     if False:
         VIA23 = DataBase.getDB().getTechnology().getLayer( 'VIA23' )
-        UpdateSession.open()
+        #UpdateSession.open()
         #net = cell.getNet('b(%d)' % 0)
         net = cell.getNet('vdd')
         build_downtrace(net, VIA23, metal2, -5, -10, -20)
@@ -233,12 +234,129 @@ def add ( cell, **kw ):
                 build_downtrace(net, metal2, x, y, y+10)
         ab.inflate ( l(30.0) )
         cell.setAbutmentBox( ab )
-        UpdateSession.close()
+        #UpdateSession.close()
 
     #af.saveCell( cell, CRL.Catalog.State.Views )
     #plugins.RSavePlugin.ScriptMain( **kw )
 
 
+###################
+# sub
+
+def sub ( cell, **kw ):
+    editor = None
+    if kw.has_key('editor') and kw['editor']:
+      editor = kw['editor']
+
+    db = DataBase.getDB()
+    print db, dir(db)
+    metal2 = DataBase.getDB().getTechnology().getLayer( 'metal2' )
+    metal3 = DataBase.getDB().getTechnology().getLayer( 'metal3' )
+    metal5 = DataBase.getDB().getTechnology().getLayer( 'metal5' )
+
+    #cell = af.getCell( 'sub', CRL.Catalog.State.Logical )
+    print cell.getNet('a(0)')
+
+    if not cell:
+      print '[ERROR] Unable to load cell "alu16.vst", aborting .'
+      return False
+    kw[ 'cell' ] = cell
+
+    width = 350.0
+    height = 405.0
+
+    ab = Box( l(    0.0 )
+            , l(    0.0 )
+            , l( width )
+            , l( height ) )
+
+    cellGauge   = af.getCellGauge()
+    spaceMargin = (Cfg.getParamPercentage('etesian.spaceMargin').asPercentage()+5) / 100.0
+    aspectRatio =  Cfg.getParamPercentage('etesian.aspectRatio').asPercentage()    / 100.0
+    clocktree.ClockTree.computeAbutmentBox( cell, spaceMargin, aspectRatio, cellGauge )
+    ab2 = cell.getAbutmentBox()
+    print "box", ab, ab.getHeight(), ab.getWidth()
+    print "calc box", ab2, ab2.getHeight(), ab2.getWidth()
+
+    #height = ab.getHeight()
+    #width = ab.getWidth()
+
+    #UpdateSession.open()
+    cell.setAbutmentBox( ab )
+
+    for i in range(16):
+      if True:
+          x = 20.0*i + 10.0
+          y = height
+          Pin.create( cell.getNet('a(%d)' % i)
+                , 'a(%d).0' % i
+                , Pin.Direction.NORTH
+                , Pin.PlacementStatus.FIXED
+                , metal3
+                , l( x ), l( y - 0 )   # Position.
+                , l( 2.0 )            , l( 2.0 )  # Size.
+                )
+    for i in range(16):
+      if True:
+          Pin.create( cell.getNet('o(%d)' % i)
+                , 'o(%d).0' % i
+                , Pin.Direction.SOUTH
+                , Pin.PlacementStatus.FIXED
+                , metal3
+                , l( 10.0*i + 100.0 ), l( 0)   # Position.
+                , l( 2.0 )            , l( 2.0 )  # Size.
+                )
+
+    for i in range(16):
+      if True:
+          net = cell.getNet('b(%d)' % i)
+          x = 20.0*i + 10.0 + 10
+          y = height - 0
+          #build_downtrace(net, metal3, x, y+11, y)
+          #continue
+          Pin.create( net
+                , 'b(%d).0' % i
+                , Pin.Direction.NORTH
+                , Pin.PlacementStatus.FIXED
+                , metal3
+                , l( x ), l( y - 0 )   # Position.
+                , l( 2.0 )            , l( 2.0 )  # Size.
+                )
+    if False:
+      Pin.create( cell.getNet('rst')
+              , 'p_reset.0'
+              , Pin.Direction.WEST
+              , Pin.PlacementStatus.FIXED
+              , metal2
+              , l(   0.0 )
+              , l( 140.0 )
+              , l(   2.0 )
+              , l(   2.0 )
+              )
+    #UpdateSession.close()
+
+    if True:
+          if editor: editor.setCell( cell )
+
+          etesian = Etesian.EtesianEngine.create(cell)
+          etesian.place()
+
+          katana = Katana.KatanaEngine.create(cell)
+          katana.digitalInit          ()
+          #katana.runNegociatePreRouted()
+          print dir(katana)
+          katana.runGlobalRouter      (0)
+          katana.loadGlobalRouting    ( Anabatic.EngineLoadGrByNet )
+          katana.layerAssign          ( Anabatic.EngineNoNetLayerAssign )
+          katana.runNegociate         ( Katana.Flags.NoFlags )
+          katana.finalizeLayout       ()
+          print dir(katana)
+          success = katana.getSuccessState()
+          katana.destroy()
+
+    #af.saveCell( cell, CRL.Catalog.State.Views )
+    #plugins.RSavePlugin.ScriptMain( **kw )
+
 
 #def toDbU(v): return DbU.fromLambda(v)
 def toDbU(v): return l(v)
@@ -256,19 +374,24 @@ class Model (object):
     HorizontalAccess = 1
     VerticalAccess = 2
 
-    def __init__(self, modelName):
-        UpdateSession.open()
+    def __init__(self, modelName, session=True, views=False):
+        if session:
+            UpdateSession.open()
         self.fillerCount = 0
         self.af = CRL.AllianceFramework.get()
         #self.cell = af.createCell(modelName)
-        self.cell = af.getCell( modelName, CRL.Catalog.State.Logical )
+        if not views:
+            self.cell = self.af.getCell( modelName, CRL.Catalog.State.Logical )
+        else:
+            self.cell = self.af.getCell( modelName, CRL.Catalog.State.Views )
         self.createNet('vss', direction=Net.Direction.IN,
                        isExternal=True, isGlobal=True, type=Net.Type.POWER)
         self.createNet('vdd', direction=Net.Direction.IN,
                        isExternal=True, isGlobal=True, type=Net.Type.GROUND)
 
         self.build()
-        UpdateSession.close()
+        if session:
+            UpdateSession.close()
         return
 
     def createNet(self, netName, **attributes):
@@ -323,15 +446,15 @@ class Model (object):
         instance = self.cell.getInstance(instanceName)
         if not instance:
             if isinstance(modelRef, str):
-                model = af.getCell(modelRef, CRL.Catalog.State.Views)
+                model = self.af.getCell(modelRef, CRL.Catalog.State.Views)
             else:
                 model = modelRef
             instance = Instance.create(self.cell, instanceName, model)
             for pin, net in portmap.items():
                 self.connect(instance, pin, net)
 
-            if transf:
-                self.place(instance, transf[0], transf[1], transf[2])
+        if transf:
+            self.place(instance, transf[0], transf[1], transf[2])
         return instance
 
     def createAccess(self, termPath, x, y, flags):
@@ -481,19 +604,14 @@ class Model (object):
         return self.getMasterCell(name).getAbutmentBox().getWidth()
 
     def save(self):
-        self.af.saveCell(self.cell, CRL.Catalog.State.Physical)
+        plugins.RSavePlugin.ScriptMain( cell=self.cell )
+        #self.af.saveCell(self.cell, CRL.Catalog.State.Views)
 
     def build(self):
         print '[ERROR] Model.build() base class method should never be called.'
 
 
-class Add (Model):
-
-    def build(self):
-        #self.setAbutmentBox(
-            #Box(toDbU(0.0), toDbU(0.0), toDbU(1595.0), toDbU(450.0)))
-        add(self.cell)
-        self.buildPower()
+class Ringed (Model):
 
     def addFillers(self):
         self.addFillersRow(toDbU(1580.0), toDbU(0.0),
@@ -517,6 +635,7 @@ class Add (Model):
         METAL1 = self.getLayer("METAL1")
         METAL2 = self.getLayer("METAL2")
         METAL3 = self.getLayer("METAL3")
+        METAL4 = self.getLayer("METAL3")
         VIA12 = self.getLayer("VIA12")
         VIA23 = self.getLayer("VIA23")
         powerWidth = toDbU(2.0)
@@ -561,8 +680,11 @@ class Add (Model):
             westContactsVdd.insert(-1, westContact)
             eastContactsVdd.insert(-1, eastContact)
 
-        self.createVertical(westContactsVdd, vddAxis.getXMin(), powerWidth)
-        self.createVertical(eastContactsVdd, vddAxis.getXMax(), powerWidth)
+        for layer in [METAL2, METAL3]:
+            self.createVertical(westContactsVdd, vddAxis.getXMin(), powerWidth,
+                                layer=layer)
+            self.createVertical(eastContactsVdd, vddAxis.getXMax(), powerWidth,
+                                layer=layer)
 
         xcenter = vddAxis.getCenter().getX() + powerWidth / 2 + toDbU(5.0)
         if False:
@@ -652,8 +774,11 @@ class Add (Model):
             westContactsVss.insert(-1, westContact)
             eastContactsVss.insert(-1, eastContact)
 
-        self.createVertical(westContactsVss, vssAxis.getXMin(), powerWidth)
-        self.createVertical(eastContactsVss, vssAxis.getXMax(), powerWidth)
+        for layer in [METAL2, METAL3]:
+            self.createVertical(westContactsVss, vssAxis.getXMin(), powerWidth,
+                                            layer=layer)
+            self.createVertical(eastContactsVss, vssAxis.getXMax(), powerWidth,
+                                            layer=layer)
 
         xcenter = vssAxis.getCenter().getX() - powerWidth / 2 - toDbU(5.0)
         if False:
@@ -695,17 +820,271 @@ class Add (Model):
 
         return
 
+class Add(Ringed):
+
+    def build(self):
+        add(self.cell)
+        self.buildPower()
+
+
+class Sub(Ringed):
+
+    def build(self):
+        sub(self.cell)
+        self.buildPower()
+
+
+class AddSubPlace(Ringed):
+
+    def build(self):
+        self.alu_hier_place()
+
+    def alu_hier_place(self, **kw):
+
+        cell = self.cell
+        editor = None
+        if kw.has_key('editor') and kw['editor']:
+          editor = kw['editor']
+
+        db = DataBase.getDB()
+        print db, dir(db)
+        metal2 = DataBase.getDB().getTechnology().getLayer( 'metal2' )
+        metal3 = DataBase.getDB().getTechnology().getLayer( 'metal3' )
+
+        add = self.af.getCell( 'add', CRL.Catalog.State.Views )
+        sub = self.af.getCell( 'sub', CRL.Catalog.State.Views )
+        #cell = self.af.getCell( 'alu_hier', CRL.Catalog.State.Logical )
+        if not cell:
+          print '[ERROR] Unable to load cell "snx.vst", aborting .'
+          return False
+        kw[ 'cell' ] = cell
+
+        ab = Box( l(    0.0 )
+                , l(    0.0 )
+                , l(  850.0 )
+                , l(  700.0 ) )
+
+        #UpdateSession.open()
+        cell.setAbutmentBox( ab )
+
+        transf = (l(25.0), l(250.0), Transformation.Orientation.ID)
+        subi = self.createInstance("subckt_49_sub", sub, transf=transf)
+        print "sub place", subi
+
+        transf = (l(450.0), l(250.0), Transformation.Orientation.ID)
+        addi = self.createInstance("subckt_48_add", add, transf=transf)
+        print "add place", addi
+
+        if False:
+            for i in range(16):
+              Pin.create( cell.getNet('a(%d)' % i)
+                        , 'a(%d).0' % i
+                        , Pin.Direction.SOUTH
+                        , Pin.PlacementStatus.FIXED
+                        , metal3
+                        , l( 100.0*i + 50.0 ) , l( 0.0 )  # Position.
+                        , l( 2.0 )            , l( 2.0 )  # Size.
+                        )
+              Pin.create( cell.getNet('b(%d)' % i)
+                        , 'b(%d).0' % i
+                        , Pin.Direction.SOUTH
+                        , Pin.PlacementStatus.FIXED
+                        , metal3
+                        , l( 100.0*i + 50.0 ) , l( 0.0 )  # Position.
+                        , l( 2.0 )            , l( 2.0 )  # Size.
+                        )
+              Pin.create( cell.getNet('o(%d)' % i)
+                        , 'o(%d).0' % i
+                        , Pin.Direction.NORTH
+                        , Pin.PlacementStatus.FIXED
+                        , metal3
+                        , l( 100.0*i + 25.0 ) , l( 0.0 )  # Position.
+                        , l( 2.0 )            , l( 2.0 )  # Size.
+                        )
+
+            Pin.create( cell.getNet('rst')
+                      , 'p_reset.0'
+                      , Pin.Direction.WEST
+                      , Pin.PlacementStatus.FIXED
+                      , metal2
+                      , l(   0.0 )
+                      , l( 140.0 )
+                      , l(   2.0 )
+                      , l(   2.0 )
+                      )
+        #UpdateSession.close()
+
+        if editor: editor.setCell( cell )
+
+        print "editor", editor, dir(editor)
+
+        #self.af.saveCell( cell, CRL.Catalog.State.Views )
+        #plugins.RSavePlugin.ScriptMain( **kw )
+
+        return 0
+
+
+class AddSubEtesian(Ringed):
+
+    def build(self):
+        self.alu_hier_route()
+
+    def alu_hier_route(self, **kw):
+
+        cell = self.cell
+        editor = None
+        if kw.has_key('editor') and kw['editor']:
+          editor = kw['editor']
+
+        db = DataBase.getDB()
+        print db, dir(db)
+        metal2 = DataBase.getDB().getTechnology().getLayer( 'metal2' )
+        metal3 = DataBase.getDB().getTechnology().getLayer( 'metal3' )
+
+        #cell = self.af.getCell( 'alu_hier', CRL.Catalog.State.Logical )
+        if not cell:
+          print '[ERROR] Unable to load cell "snx.vst", aborting .'
+          return False
+        kw[ 'cell' ] = cell
+
+        ab = Box( l(    0.0 )
+                , l(    0.0 )
+                , l(  850.0 )
+                , l(  175.0 ) )
+
+        cell.setAbutmentBox( ab )
+
+        if editor: editor.setCell( cell )
+
+        print "editor", editor, dir(editor)
+
+        success = 0
+
+        etesian = Etesian.EtesianEngine.create(cell)
+        etesian.place()
+
+        print "cell", cell, dir(cell)
+        c = cell.getComponents()
+        print "components", c, dir(c)
+        for child in cell.getInstances():
+            print "child", child
+
+        return success
+
+
+class AddSubRoute(Ringed):
+
+    def build(self):
+        self.alu_hier_route()
+
+    def alu_hier_route(self, **kw):
+
+        cell = self.cell
+        editor = None
+        if kw.has_key('editor') and kw['editor']:
+          editor = kw['editor']
+
+        db = DataBase.getDB()
+        print db, dir(db)
+        metal2 = DataBase.getDB().getTechnology().getLayer( 'metal2' )
+        metal3 = DataBase.getDB().getTechnology().getLayer( 'metal3' )
+
+        #cell = self.af.getCell( 'alu_hier', CRL.Catalog.State.Logical )
+        if not cell:
+          print '[ERROR] Unable to load cell "snx.vst", aborting .'
+          return False
+        kw[ 'cell' ] = cell
+
+        ab = Box( l(    0.0 )
+                , l(    0.0 )
+                , l(  850.0 )
+                , l(  700.0 ) )
+
+        cell.setAbutmentBox( ab )
+
+        if editor: editor.setCell( cell )
+
+        print "editor", editor, dir(editor)
+
+        success = 0
+
+        if True:
+            katana = Katana.KatanaEngine.create(cell)
+            katana.digitalInit          ()
+            katana.runNegociatePreRouted()
+            print dir(katana)
+            katana.runGlobalRouter      (0)
+            katana.loadGlobalRouting    ( Anabatic.EngineLoadGrByNet )
+            katana.layerAssign          ( Anabatic.EngineNoNetLayerAssign )
+            katana.runNegociate         ( Katana.Flags.NoFlags )
+            katana.finalizeLayout       ()
+            print dir(katana)
+            success = katana.getSuccessState()
+            katana.destroy()
+            success = 0
+
+        #self.af.saveCell( cell, CRL.Catalog.State.Views )
+        #plugins.RSavePlugin.ScriptMain( **kw )
+
+        print "cell", cell, dir(cell)
+        c = cell.getComponents()
+        print "components", c, dir(c)
+        for child in cell.getInstances():
+            print "child", child
+
+        return success
+
+
 
 def ScriptMain(**kw):
-    editor = None
-    if "editor" in kw and kw["editor"]:
-        editor = kw["editor"]
-
-    ringo = Add('add')
-    ringo.save()
-    if editor:
-        editor.setCell(ringo.getCell())
-        editor.fit()
+    #editor = None
+    #if "editor" in kw and kw["editor"]:
+    #    editor = kw["editor"]
+
+    add = Add('add')
+    add.save()
+    sub = Sub('sub')
+    sub.save()
+    # create blank ap
+    print ("Create alu_hier.ap")
+    cell = af.getCell( "alu_hier", CRL.Catalog.State.Views )
+    plugins.RSavePlugin.ScriptMain( cell=cell )
+
+    print ("copying alu_hier to altered")
+    with open("alu_hier.ap") as f:
+        x = f.read()
+        x = x.replace("alu_hier", "alu_hier_altered")
+        with open("alu_hier_altered.ap", "w") as f:
+            f.write(x)
+
+    print ("AddSubEtesian")
+    addsub = AddSubEtesian('alu_hier_altered', True, True)
+    addsub.save()
+
+    print ("copying altered to alu_hier ")
+    with open("alu_hier_altered.ap") as f:
+        x = f.read()
+        x = x.replace("alu_hier_altered", "alu_hier_altered2")
+        with open("alu_hier_altered2.ap", "w") as f:
+            f.write(x)
+
+    with open("alu_hier.vst") as f:
+        x = f.read()
+        x = x.replace("alu_hier", "alu_hier_altered2")
+        with open("alu_hier_altered2.vst", "w") as f:
+            f.write(x)
+
+    print ("AddSubPlace")
+    addsub = AddSubPlace('alu_hier_altered2', True, True)
+    addsub.save()
+
+    print ("AddSubRoute")
+    addsub = AddSubRoute('alu_hier_altered2', True, True)
+    addsub.save()
+
+    #if editor:
+    #    editor.setCell(ringo.getCell())
+    #    editor.fit()
     return True