More accurate abstract models for SRAM & PLL.
authorJean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
Wed, 6 Oct 2021 22:58:03 +0000 (00:58 +0200)
committerJean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
Wed, 6 Oct 2021 22:58:03 +0000 (00:58 +0200)
With Coriolis layer assignment correction and configuration tuning,
the P&R stage should now take less than one hour. It do not complete,
still. More adjustments are to be done.

experiments9/LibreSOCMem.py
experiments9/coriolis2/settings.py
experiments9/doDesign.py
experiments9/pll.py

index 4c4753daf8104e93c0aafc9cb934680de6a9c52d..2552e8427dbe51f24cf7be89ecd6c5ea36fa6504 100644 (file)
-# Autogenerated file. Changes will be overwritten.
 
-import CRL, Hurricane, Viewer, Cfg
-from Hurricane import (
-    Technology, DataBase, DbU, Library,
-    Layer, BasicLayer,
-    Cell, Net, Vertical, Rectilinear, Box, Point,
-    Instance, Transformation,
-    NetExternalComponents,
-)
-from common.colors import toRGB
-from common.patterns import toHexa
-from helpers import u, l
+import CRL
+import Hurricane
+import Viewer
+import Cfg
+from   Hurricane import Technology, DataBase, DbU, Library,     \
+                        Layer, BasicLayer, Cell, Net, Vertical, \
+                        Rectilinear, Box, Point, Instance,      \
+                        Transformation, NetExternalComponents,  \
+                        Horizontal, Pad
+from common.colors      import toRGB
+from common.patterns    import toHexa
+from helpers            import u, l
 from helpers.technology import setEnclosures
-from helpers.overlay import CfgCache, UpdateSession
+from helpers.overlay    import CfgCache, UpdateSession
 
-__all__ = ["setup"]
-
-def createRL(tech, net, layer, coords):
-    return
-    coords = [Point(u(x), u(y)) for x,y in coords]
-    Rectilinear.create(net, tech.getLayer(layer), coords)
-
-def _routing():
-    return # all commented-out for now
-    af = CRL.AllianceFramework.get()
-    db = DataBase.getDB()
-    tech = db.getTechnology()
-
-    rg = CRL.RoutingGauge.create('LibreSOCMem')
-    rg.setSymbolic(False)
-    metal = tech.getLayer('metal1')
-    via = tech.getLayer('metal1_via1_metal2')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.PinOnly, 0, 0.0,
-        u(0.0), u(0.21), u(0.065), u(0.065), u(0.065), u(0.065),
-    ))
-    metal = tech.getLayer('metal2')
-    via = tech.getLayer('metal1_via1_metal2')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    via = tech.getLayer('metal2_via2_metal3')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 1, 0.0,
-        u(0.0), u(0.21), u(0.14), u(0.07), u(0.07), u(0.07),
-    ))
-    metal = tech.getLayer('metal3')
-    via = tech.getLayer('metal2_via2_metal3')
-    setEnclosures(via, metal, (u(0.035), u(0.0)))
-    via = tech.getLayer('metal3_via3_metal4')
-    setEnclosures(via, metal, (u(0.035), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 2, 0.0,
-        u(0.0), u(0.21), u(0.14), u(0.07), u(0.07), u(0.07),
-    ))
-    metal = tech.getLayer('metal4')
-    via = tech.getLayer('metal3_via3_metal4')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal4_via4_metal5')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 3, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal5')
-    via = tech.getLayer('metal4_via4_metal5')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal5_via5_metal6')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 4, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal6')
-    via = tech.getLayer('metal5_via5_metal6')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal6_via6_metal7')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 5, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal7')
-    via = tech.getLayer('metal6_via6_metal7')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal7_via7_metal8')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 6, 0.0,
-        u(0.0), u(0.8), u(0.4), u(0.4), u(0.4), u(0.4),
-    ))
-    metal = tech.getLayer('metal8')
-    via = tech.getLayer('metal7_via7_metal8')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal8_via8_metal9')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 7, 0.0,
-        u(0.0), u(0.8), u(0.4), u(0.4), u(0.4), u(0.4),
-    ))
-    metal = tech.getLayer('metal9')
-    via = tech.getLayer('metal8_via8_metal9')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal9_via9_metal10')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 8, 0.0,
-        u(0.0), u(1.6), u(0.8), u(0.8), u(0.8), u(0.8),
-    ))
-    metal = tech.getLayer('metal10')
-    via = tech.getLayer('metal9_via9_metal10')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 9, 0.0,
-        u(0.0), u(1.6), u(0.8), u(0.8), u(0.8), u(0.8),
-    ))
-    af.addRoutingGauge(rg)
-    af.setRoutingGauge('LibreSOCMem')
 
-    cg = CRL.CellGauge.create(
-        'LibreSOCMem', 'metal2',
-        u(0.4), u(4.0), u(0.4),
-    )
-    af.addCellGauge(cg)
-    af.setCellGauge('LibreSOCMem')
-
-    # Place & Route setup
-    with CfgCache(priority=Cfg.Parameter.Priority.ConfigurationFile) as cfg:
-        cfg.lefImport.minTerminalWidth = 0.0
-        cfg.crlcore.groundName = 'vss'
-        cfg.crlcore.powerName = 'vdd'
-        cfg.etesian.aspectRatio = 1.00
-        cfg.etesian.aspectRatio = [10, 1000]
-        cfg.etesian.spaceMargin = 0.10
-        cfg.etesian.uniformDensity = False
-        cfg.etesian.routingDriven = False
-        cfg.etesian.feedNames = 'tie_x0,fill_x0'
-        cfg.etesian.cell.zero = 'zero_x0'
-        cfg.etesian.cell.one = 'one_x0'
-        cfg.etesian.bloat = 'disabled'
-        cfg.etesian.effort = 2
-        cfg.etesian.effort = (
-            ('Fast', 1),
-            ('Standard', 2),
-            ('High', 3 ),
-            ('Extreme', 4 ),
-        )
-        cfg.etesian.graphics = 2
-        cfg.etesian.graphics = (
-            ('Show every step', 1),
-            ('Show lower bound', 2),
-            ('Show result only', 3),
-        )
-        cfg.anabatic.routingGauge = 'LibreSOCMem'
-        cfg.anabatic.globalLengthThreshold = 1450
-        cfg.anabatic.saturateRatio = 90
-        cfg.anabatic.saturateRp = 10
-        cfg.anabatic.topRoutingLayer = 'metal10'
-        cfg.anabatic.edgeLength = 48
-        cfg.anabatic.edgeWidth = 8
-        cfg.anabatic.edgeCostH = 9.0
-        cfg.anabatic.edgeCostK = -10.0
-        cfg.anabatic.edgeHInc = 1.0
-        cfg.anabatic.edgeHScaling = 1.0
-        cfg.anabatic.globalIterations = 10
-        cfg.anabatic.globalIterations = [ 1, 100 ]
-        cfg.anabatic.gcell.displayMode = 1
-        cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2))
-        cfg.katana.hTracksReservedLocal = 4
-        cfg.katana.hTracksReservedLocal = [0, 20]
-        cfg.katana.vTracksReservedLocal = 3
-        cfg.katana.vTracksReservedLocal = [0, 20]
-        cfg.katana.termSatReservedLocal = 8
-        cfg.katana.termSatThreshold = 9
-        cfg.katana.eventsLimit = 4000002
-        cfg.katana.ripupCost = 3
-        cfg.katana.ripupCost = [0, None]
-        cfg.katana.strapRipupLimit = 16
-        cfg.katana.strapRipupLimit = [1, None]
-        cfg.katana.localRipupLimit = 9
-        cfg.katana.localRipupLimit = [1, None]
-        cfg.katana.globalRipupLimit = 5
-        cfg.katana.globalRipupLimit = [1, None]
-        cfg.katana.longGlobalRipupLimit = 5
-        cfg.chip.padCoreSide = 'South'
-
-    # Plugins setup
-    with CfgCache(priority=Cfg.Parameter.Priority.ConfigurationFile) as cfg:
-        cfg.chip.block.rails.count = 5
-        cfg.chip.block.rails.hWidth = u(2.68)
-        cfg.chip.block.rails.vWidth = u(2.68)
-        cfg.chip.block.rails.hSpacing = u(0.7)
-        cfg.chip.block.rails.vSpacing = u(0.7)
-        cfg.clockTree.minimumSide = l(600)
-        cfg.clockTree.buffer = 'buf_x2'
-        cfg.clockTree.placerEngine = 'Etesian'
-        cfg.block.spareSide = 10
-        cfg.spares.buffer = 'buf_x8'
-        cfg.spares.maxSinks = 31
+__all__ = ["setup"]
 
 
 def _load():
-    af = CRL.AllianceFramework.get()
-    db = DataBase.getDB()
-    tech = db.getTechnology()
-    rootlib = db.getRootLibrary()
-
-    lib = Library.create(rootlib, 'LibreSOCMem')
-
-    cell = Cell.create(lib, 'spblock_512w64b8w')
-    space = 0.1
+    print( '  o  LibreSOCMem.py: create dummy abstract of "spblock_512w64b8w".' ) 
+
+    af          = CRL.AllianceFramework.get()
+    rg          = af.getRoutingGauge()
+    cg          = af.getCellGauge()
+    db          = DataBase.getDB()
+    tech        = db.getTechnology()
+    rootlib     = db.getRootLibrary()
+    sliceHeight = cg.getSliceHeight()
+    METAL2      = tech.getLayer( 'METAL2' )
+    METAL3      = tech.getLayer( 'METAL3' )
+    BLOCKAGE1   = tech.getLayer( 'BLOCKAGE1' )
+    BLOCKAGE2   = tech.getLayer( 'BLOCKAGE2' )
+    BLOCKAGE3   = tech.getLayer( 'BLOCKAGE3' )
 
     with UpdateSession():
-        cell.setAbutmentBox(Box(
-            #u(0.0), u(0.0), u(110.025), u(2.025),
-            u(0.0), u(0.0), u(space*1000), u(space*25),
-        ))
-        nets = {
-            '*': Net.create(cell, '*'),
-            'clk': Net.create(cell, 'clk'),
-            'vdd': Net.create(cell, 'vdd'),
-            'vss': Net.create(cell, 'vss'),
-        }
-        nets['vss'].setGlobal(True)
-        nets['vdd'].setGlobal(True)
-        for name, qty in (('a', 9),
-                          ('d', 64),
-                          ('q', 64),
-                          ('we', 8),
-                      ):
-            for i in range(qty):
-                cname = "%s(%d)" % (name, i)
-                nets[cname] = Net.create(cell, cname)
-
-        # create series of stepped pins
-        x = space*20
-        wid = space
-        step = wid*5
-        for name, qty in (('a', 9),
-                          ('d', 64),
-                          ('q', 64),
-                          ('we', 8),
-                      ):
-            for i in range(qty):
-                cname = "%s(%d)" % (name, i)
-                net = nets[cname]
-                pin = Vertical.create(
-                    net, tech.getLayer('metal1'),
-                    u(x), u(wid), u(0), u(space*25),
-                )
-                x += step
-                net.setExternal(True)
-                NetExternalComponents.setExternal(pin)
-                # q is an output, has to be explicitly set as output
-                # everything else set to input
+        lib  = Library.create( rootlib, 'LibreSOCMem' )
+        cell = Cell.create( lib, 'spblock_512w64b8w' )
+
+        cell.setAbutmentBox( Box( 0, 0, (55+2)*sliceHeight, (45+2)*sliceHeight ) )
+        nets = { 'clk'        : Net.create( cell, 'clk' )
+               , 'vdd'        : Net.create( cell, 'vdd' )
+               , 'vss'        : Net.create( cell, 'vss' )
+               , 'blockageNet': Net.create( cell, 'blockageNet' )
+               }
+        nets['clk'].setType( Net.Type.CLOCK )
+        nets['clk'].setExternal( True )
+        nets['clk'].setDirection( Net.Direction.IN )
+        nets['vdd'].setType( Net.Type.POWER )
+        nets['vdd'].setExternal( True )
+        nets['vdd'].setDirection( Net.Direction.IN )
+        nets['vss'].setType( Net.Type.GROUND )
+        nets['vss'].setExternal( True )
+        nets['vss'].setDirection( Net.Direction.IN )
+        blockageArea = Box( cell.getAbutmentBox() )
+        blockageArea.inflate( -sliceHeight )
+        for layer in (BLOCKAGE1, BLOCKAGE2, BLOCKAGE3):
+            Pad.create( nets['blockageNet'], layer, blockageArea )
+        for name, width in ( ('a', 9), ('d', 64), ('q', 64), ('we', 8) ):
+            for bit in range(width):
+                bitName = '{}({})'.format( name, bit )
+                nets[ bitName ] = Net.create( cell, bitName )
+                nets[ bitName ].setExternal( True )
+                direction = Net.Direction.IN
                 if name == 'q':
-                    net.setDirection( Net.Direction.OUT )
-                else:
-                    net.setDirection( Net.Direction.IN )
-            # separate the pin groups
-            x += step * 3
-
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((1.105,1.0),(1.4375,1.0),(1.4375,0.24),(0.9625,0.24),(0.9625,1.0),(1.105,1.0)),
-        )
-        net = nets['*']
-        createRL(
-            tech, net, 'nimplant',
-            ((1.105,0.235),(0.895,0.235),(0.895,0.17),(0.705,0.17),(0.705,0.235),(0.55,0.235),(0.55,0.615),(0.495,0.615),(0.495,0.55),(0.305,0.55),(0.305,0.615),(0.1575,0.615),(0.1575,1.385),(0.305,1.385),(0.305,1.45),(0.495,1.45),(0.495,1.385),(0.65,1.385),(0.65,1.005),(0.705,1.005),(0.705,1.07),(0.895,1.07),(0.895,1.005),(1.105,1.005),(1.105,1.07),(1.295,1.07),(1.295,1.005),(1.4425,1.005),(1.4425,0.235),(1.295,0.235),(1.295,0.17),(1.105,0.17),(1.105,0.235)),
-        )
-        createRL(
-            tech, net, 'nimplant',
-            ((0.515,3.595),(0.515,3.765),(0.685,3.765),(0.685,3.595),(0.515,3.595)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((1.105,0.17),(1.105,1.07),(1.295,1.07),(1.295,0.17),(1.105,0.17)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((1.105,2.13),(1.105,3.87),(1.295,3.87),(1.295,2.13),(1.105,2.13)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((0.305,0.55),(0.305,1.45),(0.495,1.45),(0.495,0.55),(0.305,0.55)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((0.305,2.53),(0.305,3.47),(0.495,3.47),(0.495,2.53),(0.305,2.53)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((0.705,0.17),(0.705,1.07),(0.895,1.07),(0.895,0.17),(0.705,0.17)),
-        )
-        createRL(
-            tech, net, 'vthg',
-            ((0.705,2.53),(0.705,3.47),(0.895,3.47),(0.895,2.53),(0.705,2.53)),
-        )
-        createRL(
-            tech, net, 'pimplant',
-            ((1.105,2.195),(0.9575,2.195),(0.9575,2.595),(0.895,2.595),(0.895,2.53),(0.705,2.53),(0.705,2.595),(0.7,2.595),(0.495,2.595),(0.495,2.53),(0.305,2.53),(0.305,2.595),(0.15,2.595),(0.15,3.6825),(0.25,3.6825),(0.25,3.405),(0.305,3.405),(0.305,3.47),(0.495,3.47),(0.495,3.405),(0.5,3.405),(0.705,3.405),(0.705,3.47),(0.895,3.47),(0.895,3.405),(0.95,3.405),(0.95,3.7875),(0.9575,3.7875),(0.9575,3.805),(1.105,3.805),(1.105,3.87),(1.295,3.87),(1.295,3.805),(1.4425,3.805),(1.4425,2.195),(1.295,2.195),(1.295,2.13),(1.105,2.13),(1.105,2.195)),
-        )
-        createRL(
-            tech, net, 'pimplant',
-            ((0.115,0.195),(0.115,0.365),(0.285,0.365),(0.285,0.195),(0.115,0.195)),
-        )
-        if False:
-            net = nets['vss']
-            createRL(
-                tech, net, 'pwell',
-                ((-0.12,-0.32),(-0.12,1.92),(1.72,1.92),(1.72,-0.32),(-0.12,-0.32)),
-            )
-            createRL(
-                tech, net, 'metal1',
-                ((0.0,0.0),(0.0,0.48),(1.6,0.48),(1.6,0.0),(0.0,0.0)),
-            )
-            if False:
-                Vertical.create(
-                    net, tech.getLayer('metal1.pin'),
-                    u(0.8), u(1.6), u(0.0), u(0.48),
-                )
-            pin = Vertical.create(
-                net, tech.getLayer('metal1'),
-                u(0.8), u(1.6), u(0.0), u(0.48),
-            )
-            net.setExternal(True)
-            NetExternalComponents.setExternal(pin)
-            createRL(
-                tech, net, 'active',
-                ((0.12,0.2),(0.12,0.36),(0.28,0.36),(0.28,0.2),(0.12,0.2)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.9625,0.3075),(1.0375,0.3075),(1.0375,0.3825),(0.9625,0.3825),(0.9625,0.3075)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.1675,0.2475),(0.2325,0.2475),(0.2325,0.3125),(0.1675,0.3125),(0.1675,0.2475)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,0.3125),(1.0325,0.3125),(1.0325,0.3775),(0.9675,0.3775),(0.9675,0.3125)),
-            )
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((1.105,3.8),(1.4375,3.8),(1.4375,2.2),(0.9625,2.2),(0.9625,3.8),(1.105,3.8)),
-        )
-        if False:
+                    direction = Net.Direction.OUT
+                nets[ bitName ].setDirection( direction )
+        METAL2pitch   = rg.getLayerGauge( METAL2 ).getPitch()
+        METAL3pitch   = rg.getLayerGauge( METAL3 ).getPitch()
+        METAL2width   = rg.getLayerGauge( METAL2 ).getWireWidth()
+        METAL3width   = rg.getLayerGauge( METAL3 ).getWireWidth()
+        southSideStep = 16
+        yref = cell.getAbutmentBox().getYMin() + sliceHeight - METAL2pitch
+        for bitpair in range(32):
+            xref = cell.getAbutmentBox().getXMax() \
+                   - sliceHeight - ( (bitpair+1)*southSideStep + 2 )*METAL3pitch 
+
+            pinSpecs = [ ('q', (63-bitpair*2)  ,  0)
+                       , ('d', (63-bitpair*2)  , 10)
+                       , ('d', (63-bitpair*2)-1, 12)
+                       , ('q', (63-bitpair*2)-1, 14)
+                       ]
+            if bitpair%4 == 3:
+                pinSpecs.append( ('we', 7-bitpair//4, 8) )
+            for name, bit, deltaPitch in pinSpecs:
+                net     = nets[ '{}({})'.format(name,bit) ]
+                xaxis   = xref - METAL3pitch*deltaPitch
+                segment = Vertical.create( net
+                                         , METAL3
+                                         , xaxis
+                                         , METAL3width
+                                         , yref
+                                         , yref+8*METAL2pitch )
+                segment = Vertical.create( net
+                                         , METAL3
+                                         , xaxis
+                                         , METAL3width
+                                         , yref
+                                         , yref+METAL2pitch )
+                NetExternalComponents.setExternal( segment )
+        segment = Vertical.create( nets['clk']
+                                 , METAL3
+                                 , cell.getAbutmentBox().getXMin()
+                                   + sliceHeight + 5*METAL3pitch
+                                 , METAL3width
+                                 , yref
+                                 , yref+8*METAL2pitch )
+        segment = Vertical.create( nets['clk']
+                                 , METAL3
+                                 , cell.getAbutmentBox().getXMin()
+                                   + sliceHeight + 5*METAL3pitch
+                                 , METAL3width
+                                 , yref
+                                 , yref+METAL2pitch )
+        NetExternalComponents.setExternal( segment )
+
+        xref = cell.getAbutmentBox().getXMin() + sliceHeight - METAL3pitch
+        yref = cell.getAbutmentBox().getYMax() - sliceHeight
+        for bit in range(9):
+            net   = nets[ '{}({})'.format('a',8-bit) ]
+            yaxis = yref - 2*sliceHeight*bit - METAL3pitch*5
+            if bit > 4:
+                yaxis -= 20*sliceHeight
+            segment = Horizontal.create( net
+                                       , METAL2
+                                       , yaxis
+                                       , METAL2width
+                                       , xref
+                                       , xref+8*METAL3pitch )
+            segment = Horizontal.create( net
+                                       , METAL2
+                                       , yaxis
+                                       , METAL2width
+                                       , xref
+                                       , xref+METAL3pitch )
+            NetExternalComponents.setExternal( segment )
+
+        xmin = cell.getAbutmentBox().getXMin() + 2*sliceHeight
+        xmax = cell.getAbutmentBox().getXMax() - 2*sliceHeight
+        yref = cell.getAbutmentBox().getYMin() + 2*sliceHeight
+        for i in range(44):
             net = nets['vdd']
-            createRL(
-                tech, net, 'nwell',
-                ((-0.12,1.92),(-0.12,4.32),(1.72,4.32),(1.72,1.92),(-0.12,1.92)),
-            )
-            createRL(
-                tech, net, 'metal1',
-                ((0.0,3.52),(0.0,4.0),(1.6,4.0),(1.6,3.52),(0.0,3.52)),
-            )
-            if False:
-                Vertical.create(
-                    net, tech.getLayer('metal1.pin'),
-                    u(0.8), u(1.6), u(3.52), u(4.0),
-                )
-            pin = Vertical.create(
-                net, tech.getLayer('metal1'),
-                u(0.8), u(1.6), u(3.52), u(4.0),
-            )
-            net.setExternal(True)
-            NetExternalComponents.setExternal(pin)
-            createRL(
-                tech, net, 'active',
-                ((0.52,3.6),(0.52,3.76),(0.68,3.76),(0.68,3.6),(0.52,3.6)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.9625,3.5675),(1.0375,3.5675),(1.0375,3.7825),(0.9625,3.7825),(0.9625,3.5675)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.1625,3.6025),(0.2375,3.6025),(0.2375,3.6775),(0.1625,3.6775),(0.1625,3.6025)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.5675,3.6475),(0.6325,3.6475),(0.6325,3.7125),(0.5675,3.7125),(0.5675,3.6475)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,3.5725),(1.0325,3.5725),(1.0325,3.6375),(0.9675,3.6375),(0.9675,3.5725)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,3.7125),(1.0325,3.7125),(1.0325,3.7775),(0.9675,3.7775),(0.9675,3.7125)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.1675,3.6075),(0.2325,3.6075),(0.2325,3.6725),(0.1675,3.6725),(0.1675,3.6075)),
-            )
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((0.305,1.38),(0.495,1.38),(0.495,0.62),(0.1625,0.62),(0.1625,1.38),(0.305,1.38)),
-        )
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((0.425,2.6),(0.155,2.6),(0.155,3.6775),(0.245,3.6775),(0.245,3.4),(0.705,3.4),(0.705,2.6),(0.425,2.6)),
-        )
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((0.705,1.0),(1.0375,1.0),(1.0375,0.24),(0.555,0.24),(0.555,1.0),(0.705,1.0)),
-        )
-        net = nets['clk']
-        createRL(
-            tech, net, 'poly',
-            ((0.775,0.185),(0.775,1.2375),(0.9975,1.2375),(0.9975,1.1625),(0.825,1.1625),(0.825,0.185),(0.775,0.185)),
-        )
-        createRL(
-            tech, net, 'poly',
-            ((0.775,2.545),(0.775,3.455),(0.825,3.455),(0.825,2.0375),(0.9975,2.0375),(0.9975,1.9625),(0.775,1.9625),(0.775,2.545)),
-        )
-        createRL(
-            tech, net, 'metal1',
-            ((0.9675,1.2675),(0.9675,1.9325),(0.9275,1.9325),(0.9275,2.0675),(0.9675,2.0675),(0.9675,3.455),(1.0325,3.455),(1.0325,0.545),(0.9675,0.545),(0.9675,1.1325),(0.9275,1.1325),(0.9275,1.2675),(0.9675,1.2675)),
-        )
-        if False:
-            Vertical.create(
-                net, tech.getLayer('metal1.pin'),
-                u(1.0), u(0.065), u(0), u(3.455),
-            )
-        pin = Vertical.create(
-            net, tech.getLayer('metal1'),
-            u(1.0), u(0.065), u(0), u(3.455),
-        )
-        net.setExternal(True)
-        NetExternalComponents.setExternal(pin)
-        createRL(
-            tech, net, 'contact',
-            ((0.9275,1.1675),(0.9925,1.1675),(0.9925,1.2325),(0.9275,1.2325),(0.9275,1.1675)),
-        )
-        createRL(
-            tech, net, 'contact',
-            ((0.9275,1.9675),(0.9925,1.9675),(0.9925,2.0325),(0.9275,2.0325),(0.9275,1.9675)),
-        )
-        net = nets['*']
-        createRL(
-            tech, net, 'active',
-            ((0.775,2.6),(0.705,2.6),(0.705,3.4),(0.955,3.4),(0.955,3.7825),(1.045,3.7825),(1.045,2.6),(0.775,2.6)),
-        )
-
-
-    af.wrapLibrary(lib, 0)
+            if i % 2:
+                net = nets['vss']
+            segment = Horizontal.create( net
+                                       , METAL3
+                                       , yref + sliceHeight*i
+                                       , l(24.0)
+                                       , xmin
+                                       , xmax )
+            NetExternalComponents.setExternal( segment )
+            
+    af.wrapLibrary( lib, 0 )
 
     return lib
 
 def setup():
     lib = _load()
-    _routing()
-
     return lib
index 57a8b32080246e94168545667ed15b5c75efcdad..8effefd6d307b3a2fe1b461d8b2cf1b9ec012c8a 100644 (file)
@@ -14,7 +14,7 @@ import LibreSOCMem, pll
 LibreSOCMem.setup()
 pll.setup()
 
-if os.environ.has_key('CELLS_TOP'):
+if 'CELLS_TOP' in os.environ:
     cellsTop = os.environ['CELLS_TOP']
 else:
     cellsTop = '../../../alliance-check-toolkit/cells'
@@ -23,78 +23,6 @@ db = DataBase.getDB()
 af = AllianceFramework.get()
 
 
-def createPLLBlackbox ():
-    global db, af
-    print( '  o  Creating PLL blackboxes for "ls180" design.' )
-    rootlib  = db.getRootLibrary()
-    lib      = rootlib.getLibrary( 'pll' )
-    pllName = 'pll'
-    pll     = lib.getCell( pllName )
-    if not pll:
-        raise ErrorMessage( 1, 'settings.createPLLBlackBox(): '
-                                'PLL Cell "{}" not found.' \
-                               .format(pllName) )
-    pll.setAbstractedSupply( True )
-    blackboxName = 'real_pll'
-    cell     = Cell.create( lib, blackboxName )
-    instance = Instance.create( cell, 'real_pll', pll )
-    state    = af.getCatalog().getState( blackboxName, True )
-    state.setCell( cell )
-    state.setLogical( True )
-    state.setInMemory( True )
-    print( '     - {}.'.format(cell) )
-    for masterNet in pll.getNets():
-        if not masterNet.isExternal():
-            continue
-        net = Net.create( cell, masterNet.getName() )
-        net.setDirection( masterNet.getDirection() )
-        net.setType( masterNet.getType() )
-        net.setExternal( True )
-        net.setGlobal( masterNet.isGlobal() )
-        if masterNet.isSupply():
-            continue
-        plug = instance.getPlug( masterNet )
-        plug.setNet( net )
-
-def createSramBlackbox ():
-    global db, af
-    print( '  o  Creating SRAM blackboxes for "ls180" design.' )
-    rootlib  = db.getRootLibrary()
-    lib      = rootlib.getLibrary( 'LibreSOCMem' )
-    sramName = 'spblock_512w64b8w'
-    sram     = lib.getCell( sramName )
-    if not sram:
-        raise ErrorMessage( 1, 'settings.createSramBlocks(): '
-                                'SRAM Cell "{}" not found.' \
-                               .format(sramName) )
-    sram.setAbstractedSupply( True )
-    blackboxeNames = [ 'spblock_512w64b8w_0',
-                       'spblock_512w64b8w_1',
-                       'spblock_512w64b8w_2',
-                       'spblock_512w64b8w_3',
-                     ]
-    for blackboxName in blackboxeNames:
-        cell     = Cell.create( lib, blackboxName )
-        instance = Instance.create( cell, 'real_sram', sram )
-        state    = af.getCatalog().getState( blackboxName, True )
-        state.setCell( cell )
-        state.setLogical( True )
-        state.setInMemory( True )
-        print( '     - {}.'.format(cell) )
-        for masterNet in sram.getNets():
-            if not masterNet.isExternal():
-                continue
-            net = Net.create( cell, masterNet.getName() )
-            net.setDirection( masterNet.getDirection() )
-            net.setType( masterNet.getType() )
-            net.setExternal( True )
-            net.setGlobal( masterNet.isGlobal() )
-            if masterNet.isSupply():
-                continue
-            plug = instance.getPlug( masterNet )
-            plug.setNet( net )
-
-
 with CfgCache('', priority=Cfg.Parameter.Priority.UserFile) as cfg:
     cfg.misc.catchCore               = False
     cfg.misc.info                    = False
@@ -157,7 +85,7 @@ with CfgCache('', priority=Cfg.Parameter.Priority.UserFile) as cfg:
     cfg.conductor.useFixedAbHeight   = False
 
     env = CRL.AllianceFramework.get().getEnvironment()
-    env.setCLOCK( '^sys_pllclk$|^ck|^jtag_tck$' )
+    env.setCLOCK( '^ck|^pll_clk|^jtag_tck$' )
     env.addSYSTEM_LIBRARY(library=cellsTop+'/niolib',
                            mode=CRL.Environment.Prepend )
     env.addSYSTEM_LIBRARY(library=cellsTop+'/nsxlib',
@@ -167,13 +95,6 @@ with CfgCache('', priority=Cfg.Parameter.Priority.UserFile) as cfg:
 
 Viewer.Graphics.setStyle('Alliance.Classic [black]')
 
-# XXX cannot run this in non-NDA'd mode because there is no
-# equivalent to NDA.node180.tsmc_c018.LibreSOCMem (or PLL)
-# TODO: create a fake one
-with overlay.UpdateSession():
-    createSramBlackbox()
-    createPLLBlackbox()
-
 print( '  o  Successfully run "<>/coriolis2/settings.py".' )
 print( '     - CELLS_TOP = "{}"'.format(cellsTop) )
 
index 4222efe174b7e5d50122f19ab96fb9b318f18d59..25d35b08636d47adee410aa5b3df56bcb41be46c 100644 (file)
@@ -1,19 +1,18 @@
 
-from   __future__ import print_function
-
 import os
 import json
 import sys
 import traceback
 import CRL
 import helpers
+from   helpers    import trace, overlay, l, u, n
 from   helpers.io import ErrorMessage, WarningMessage
-from   helpers    import trace, l, u, n
 import plugins
-from   Hurricane  import DbU
+from   Hurricane  import Breakpoint, DbU, DataBase, Instance, Transformation
 from   plugins.alpha.block.configuration import IoPin, GaugeConf
 from   plugins.alpha.block.iospecs       import IoSpecs
 from   plugins.alpha.block.block         import Block
+from   plugins.alpha.block.spares        import Spares
 from   plugins.alpha.core2chip.niolib    import CoreToChip
 from   plugins.alpha.chip.configuration  import ChipConf
 from   plugins.alpha.chip.chip           import Chip
@@ -21,17 +20,18 @@ from   plugins.alpha.chip.chip           import Chip
 
 af  = CRL.AllianceFramework.get()
 
-def scriptMain (**kw):
+def scriptMain ( **kw ):
     """The mandatory function to be called by Coriolis CGT/Unicorn."""
     global af
-    rvalue = True
-    coreSize = 65000 
-    cwd = os.path.split( os.path.abspath(__file__) )[0]
-    ioSpecs = IoSpecs()
+    rvalue   = True
+    coreSize = 380*100.0
+    cwd      = os.path.split( os.path.abspath(__file__) )[0]
+    ioSpecs  = IoSpecs()
     ioSpecs.loadFromPinmux( '%s/ls180/litex_pinpads.json' % cwd,
                             cheat_dont_do_analog=True)
     try:
         #helpers.setTraceLevel( 550 )
+        #Breakpoint.setStopLevel( 100 )
         cell, editor = plugins.kwParseMain( **kw )
         cell = af.getCell( 'ls180', CRL.Catalog.State.Logical )
         if cell is None:
@@ -44,25 +44,26 @@ def scriptMain (**kw):
         ls180Conf.cfg.etesian.uniformDensity = True
         ls180Conf.cfg.etesian.aspectRatio = 1.0
         ls180Conf.cfg.etesian.spaceMargin = 0.05
-        #ls180Conf.cfg.katana.hTracksReservedLocal = 6
-        #ls180Conf.cfg.katana.vTracksReservedLocal = 3
-        ls180Conf.cfg.katana.hTracksReservedMin = 6
-        ls180Conf.cfg.katana.vTracksReservedMin = 1
+        ls180Conf.cfg.katana.hTracksReservedLocal = 6
+        ls180Conf.cfg.katana.vTracksReservedLocal = 6
+        ls180Conf.cfg.katana.hTracksReservedMin = 0
+        ls180Conf.cfg.katana.vTracksReservedMin = 0
         ls180Conf.cfg.block.spareSide = l(700)
         ls180Conf.cfg.chip.padCoreSide = 'North'
+        ls180Conf.cfg.chip.supplyRailWidth = l(50)
+        ls180Conf.cfg.chip.supplyRailPitch = l(300)
         ls180Conf.editor = editor
         ls180Conf.useSpares = True
         ls180Conf.useClockTree = True
+        ls180Conf.useHFNS = True
         ls180Conf.bColumns = 2
         ls180Conf.bRows = 2
         ls180Conf.chipConf.name = 'chip'
         ls180Conf.chipConf.ioPadGauge = 'niolib'
-        ls180Conf.coreSize = (l(coreSize     ), l(coreSize     ))
-        ls180Conf.chipSize = (l(coreSize+3360), l(coreSize+3360))
-        # ooo, how annoying.  nsxlib (only 6 METAL) cannot cope with 3 clocks!
-        #ls180Conf.useHTree('core.por_clk') # output from the PLL, needs to be H-Tree
+        ls180Conf.coreSize = (l(coreSize      ), l(coreSize      ))
+        ls180Conf.chipSize = (l(coreSize+4000.0), l(coreSize+4000.0))
+        ls180Conf.useHTree( 'core.pll_clk', Spares.HEAVY_LEAF_LOAD )
         ls180Conf.useHTree('jtag_tck_from_pad')
-        ls180Conf.useHTree('sys_pllclk_from_pad')
 
         ls180ToChip = CoreToChip( ls180Conf )
         ls180ToChip.buildChip()
@@ -70,10 +71,39 @@ def scriptMain (**kw):
         chipBuilder = Chip( ls180Conf )
         chipBuilder.doChipFloorplan()
 
+        tiPath    = 'test_issuer.ti.'
+        sramDatas = [ 'test_issuer.ti.sram4k_0.spblock_512w64b8w'
+                    , 'test_issuer.ti.sram4k_1.spblock_512w64b8w'
+                    , 'test_issuer.ti.sram4k_2.spblock_512w64b8w'
+                    , 'test_issuer.ti.sram4k_3.spblock_512w64b8w'
+                    ]
+
+        with overlay.UpdateSession():
+            sram        = DataBase.getDB().getCell( 'spblock_512w64b8w' )
+            sramAb      = sram.getAbutmentBox()
+            coreAb      = cell.getAbutmentBox()
+            sliceHeight = chipBuilder.conf.sliceHeight
+            sliceStep   = chipBuilder.conf.sliceStep
+            originX     = coreAb.getXMin() 
+            for i in range(len(sramDatas)):
+                block = chipBuilder.rgetCoreInstance( sramDatas[i] )
+                block.setTransformation(  
+                    Transformation( originX
+                                  , coreAb.getYMax() - sramAb.getHeight()
+                                  , Transformation.Orientation.ID ) )
+                block.setPlacementStatus( Instance.PlacementStatus.FIXED )
+                originX += sramAb.getWidth()
+            block = chipBuilder.rgetCoreInstance( 'test_issuer.wrappll.pll' )
+            block.setTransformation(  
+                Transformation( coreAb.getXMax()
+                              , coreAb.getYMax() - block.getAbutmentBox().getHeight()
+                              , Transformation.Orientation.MX ) )
+            block.setPlacementStatus( Instance.PlacementStatus.FIXED )
+
         rvalue = chipBuilder.doPnR()
         chipBuilder.save()
-        CRL.Gds.save(ls180Conf.chip)
-    except Exception, e:
+       #CRL.Gds.save(ls180Conf.chip)
+    except Exception as e:
         helpers.io.catch(e)
         rvalue = False
     sys.stdout.flush()
index d485d5681907a8f56f4b15448b84ccdca54b80fe..119645f31b0315a0f567939d8bb5ca6e8896ad99 100644 (file)
-# Autogenerated file. Changes will be overwritten.
 
-import CRL, Hurricane, Viewer, Cfg
-from Hurricane import (
-    Technology, DataBase, DbU, Library,
-    Layer, BasicLayer,
-    Cell, Net, Vertical, Rectilinear, Box, Point,
-    Instance, Transformation,
-    NetExternalComponents,
-)
-from common.colors import toRGB
-from common.patterns import toHexa
-from helpers import u, l
-from helpers.technology import setEnclosures
-from helpers.overlay import CfgCache, UpdateSession
+import CRL
+import Hurricane
+import Viewer
+import Cfg
+from   Hurricane import Technology, DataBase, DbU, Library,     \
+                        Layer, BasicLayer, Cell, Net, Vertical, \
+                        Rectilinear, Box, Point, Instance,      \
+                        Transformation, NetExternalComponents,  \
+                        Horizontal, Pad
+from helpers            import u, l
+from helpers.overlay    import UpdateSession
 
-__all__ = ["setup"]
 
-def createRL(tech, net, layer, coords):
-    return
-    coords = [Point(u(x), u(y)) for x,y in coords]
-    Rectilinear.create(net, tech.getLayer(layer), coords)
-
-def _routing():
-    return # all commented-out for now
-    af = CRL.AllianceFramework.get()
-    db = DataBase.getDB()
-    tech = db.getTechnology()
-
-    rg = CRL.RoutingGauge.create('pll')
-    rg.setSymbolic(False)
-    metal = tech.getLayer('metal1')
-    via = tech.getLayer('metal1_via1_metal2')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.PinOnly, 0, 0.0,
-        u(0.0), u(0.21), u(0.065), u(0.065), u(0.065), u(0.065),
-    ))
-    metal = tech.getLayer('metal2')
-    via = tech.getLayer('metal1_via1_metal2')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    via = tech.getLayer('metal2_via2_metal3')
-    setEnclosures(via, metal, (u(0.0), u(0.035)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 1, 0.0,
-        u(0.0), u(0.21), u(0.14), u(0.07), u(0.07), u(0.07),
-    ))
-    metal = tech.getLayer('metal3')
-    via = tech.getLayer('metal2_via2_metal3')
-    setEnclosures(via, metal, (u(0.035), u(0.0)))
-    via = tech.getLayer('metal3_via3_metal4')
-    setEnclosures(via, metal, (u(0.035), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 2, 0.0,
-        u(0.0), u(0.21), u(0.14), u(0.07), u(0.07), u(0.07),
-    ))
-    metal = tech.getLayer('metal4')
-    via = tech.getLayer('metal3_via3_metal4')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal4_via4_metal5')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 3, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal5')
-    via = tech.getLayer('metal4_via4_metal5')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal5_via5_metal6')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 4, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal6')
-    via = tech.getLayer('metal5_via5_metal6')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal6_via6_metal7')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 5, 0.0,
-        u(0.0), u(0.28), u(0.14), u(0.14), u(0.14), u(0.14),
-    ))
-    metal = tech.getLayer('metal7')
-    via = tech.getLayer('metal6_via6_metal7')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal7_via7_metal8')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 6, 0.0,
-        u(0.0), u(0.8), u(0.4), u(0.4), u(0.4), u(0.4),
-    ))
-    metal = tech.getLayer('metal8')
-    via = tech.getLayer('metal7_via7_metal8')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal8_via8_metal9')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 7, 0.0,
-        u(0.0), u(0.8), u(0.4), u(0.4), u(0.4), u(0.4),
-    ))
-    metal = tech.getLayer('metal9')
-    via = tech.getLayer('metal8_via8_metal9')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    via = tech.getLayer('metal9_via9_metal10')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Vertical, CRL.RoutingLayerGauge.Default, 8, 0.0,
-        u(0.0), u(1.6), u(0.8), u(0.8), u(0.8), u(0.8),
-    ))
-    metal = tech.getLayer('metal10')
-    via = tech.getLayer('metal9_via9_metal10')
-    setEnclosures(via, metal, (u(0.0), u(0.0)))
-    rg.addLayerGauge(CRL.RoutingLayerGauge.create(
-        metal, CRL.RoutingLayerGauge.Horizontal, CRL.RoutingLayerGauge.Default, 9, 0.0,
-        u(0.0), u(1.6), u(0.8), u(0.8), u(0.8), u(0.8),
-    ))
-    af.addRoutingGauge(rg)
-    af.setRoutingGauge('LibreSOCMem')
-
-    cg = CRL.CellGauge.create(
-        'LibreSOCMem', 'metal2',
-        u(0.4), u(4.0), u(0.4),
-    )
-    af.addCellGauge(cg)
-    af.setCellGauge('LibreSOCMem')
-
-    # Place & Route setup
-    with CfgCache(priority=Cfg.Parameter.Priority.ConfigurationFile) as cfg:
-        cfg.lefImport.minTerminalWidth = 0.0
-        cfg.crlcore.groundName = 'vss'
-        cfg.crlcore.powerName = 'vdd'
-        cfg.etesian.aspectRatio = 1.00
-        cfg.etesian.aspectRatio = [10, 1000]
-        cfg.etesian.spaceMargin = 0.10
-        cfg.etesian.uniformDensity = False
-        cfg.etesian.routingDriven = False
-        cfg.etesian.feedNames = 'tie_x0,fill_x0'
-        cfg.etesian.cell.zero = 'zero_x0'
-        cfg.etesian.cell.one = 'one_x0'
-        cfg.etesian.bloat = 'disabled'
-        cfg.etesian.effort = 2
-        cfg.etesian.effort = (
-            ('Fast', 1),
-            ('Standard', 2),
-            ('High', 3 ),
-            ('Extreme', 4 ),
-        )
-        cfg.etesian.graphics = 2
-        cfg.etesian.graphics = (
-            ('Show every step', 1),
-            ('Show lower bound', 2),
-            ('Show result only', 3),
-        )
-        cfg.anabatic.routingGauge = 'LibreSOCMem'
-        cfg.anabatic.globalLengthThreshold = 1450
-        cfg.anabatic.saturateRatio = 90
-        cfg.anabatic.saturateRp = 10
-        cfg.anabatic.topRoutingLayer = 'metal10'
-        cfg.anabatic.edgeLength = 48
-        cfg.anabatic.edgeWidth = 8
-        cfg.anabatic.edgeCostH = 9.0
-        cfg.anabatic.edgeCostK = -10.0
-        cfg.anabatic.edgeHInc = 1.0
-        cfg.anabatic.edgeHScaling = 1.0
-        cfg.anabatic.globalIterations = 10
-        cfg.anabatic.globalIterations = [ 1, 100 ]
-        cfg.anabatic.gcell.displayMode = 1
-        cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2))
-        cfg.katana.hTracksReservedLocal = 4
-        cfg.katana.hTracksReservedLocal = [0, 20]
-        cfg.katana.vTracksReservedLocal = 3
-        cfg.katana.vTracksReservedLocal = [0, 20]
-        cfg.katana.termSatReservedLocal = 8
-        cfg.katana.termSatThreshold = 9
-        cfg.katana.eventsLimit = 4000002
-        cfg.katana.ripupCost = 3
-        cfg.katana.ripupCost = [0, None]
-        cfg.katana.strapRipupLimit = 16
-        cfg.katana.strapRipupLimit = [1, None]
-        cfg.katana.localRipupLimit = 9
-        cfg.katana.localRipupLimit = [1, None]
-        cfg.katana.globalRipupLimit = 5
-        cfg.katana.globalRipupLimit = [1, None]
-        cfg.katana.longGlobalRipupLimit = 5
-        cfg.chip.padCoreSide = 'South'
-
-    # Plugins setup
-    with CfgCache(priority=Cfg.Parameter.Priority.ConfigurationFile) as cfg:
-        cfg.chip.block.rails.count = 5
-        cfg.chip.block.rails.hWidth = u(2.68)
-        cfg.chip.block.rails.vWidth = u(2.68)
-        cfg.chip.block.rails.hSpacing = u(0.7)
-        cfg.chip.block.rails.vSpacing = u(0.7)
-        cfg.clockTree.minimumSide = l(600)
-        cfg.clockTree.buffer = 'buf_x2'
-        cfg.clockTree.placerEngine = 'Etesian'
-        cfg.block.spareSide = 10
-        cfg.spares.buffer = 'buf_x8'
-        cfg.spares.maxSinks = 31
+__all__ = [ "setup" ]
 
 
 def _load():
-    af = CRL.AllianceFramework.get()
-    db = DataBase.getDB()
-    tech = db.getTechnology()
-    rootlib = db.getRootLibrary()
-
-    lib = Library.create(rootlib, 'pll')
-
-    space = 0.1
+    print( '  o  pll.py: Create dummy abstract of "pll".' ) 
+
+    af          = CRL.AllianceFramework.get()
+    rg          = af.getRoutingGauge()
+    cg          = af.getCellGauge()
+    db          = DataBase.getDB()
+    tech        = db.getTechnology()
+    rootlib     = db.getRootLibrary()
+    sliceHeight = cg.getSliceHeight()
+    METAL2      = tech.getLayer( 'METAL2' )
+    METAL3      = tech.getLayer( 'METAL3' )
+    METAL4      = tech.getLayer( 'METAL4' )
+    METAL5      = tech.getLayer( 'METAL5' )
+    BLOCKAGE1   = tech.getLayer( 'BLOCKAGE1' )
+    BLOCKAGE2   = tech.getLayer( 'BLOCKAGE2' )
+    BLOCKAGE3   = tech.getLayer( 'BLOCKAGE3' )
+    BLOCKAGE4   = tech.getLayer( 'BLOCKAGE4' )
+    BLOCKAGE5   = tech.getLayer( 'BLOCKAGE5' )
 
-    cell = Cell.create(lib, 'pll')
     with UpdateSession():
-        cell.setAbutmentBox(Box(
-            #u(0.0), u(0.0), u(13.5), u(2.025),
-            u(0.0), u(0.0), u(space*125), u(space*25),
-        ))
-        nets = {
-            #'*': Net.create(cell, '*'),
-            'ref_v': Net.create(cell, 'ref_v'),
-            'div_out_test': Net.create(cell, 'div_out_test'),
-            'a0': Net.create(cell, 'a0'),
-            'a1': Net.create(cell, 'a1'),
-            'vco_test_ana': Net.create(cell, 'vco_test_ana'),
-            'out_v': Net.create(cell, 'out_v'),
-            'vdd': Net.create(cell, 'vdd'),
-            'vss': Net.create(cell, 'vss'),
-        }
-        nets['vdd'].setGlobal(True)
-        nets['vss'].setGlobal(True)
-
-        # set net directions
-        nets['ref_v'].setDirection( Net.Direction.IN )
-        nets['a0'].setDirection( Net.Direction.IN )
-        nets['a1'].setDirection( Net.Direction.IN )
-        nets['div_out_test'].setDirection( Net.Direction.OUT )
-        nets['vco_test_ana'].setDirection( Net.Direction.OUT )
-        nets['out_v'].setDirection( Net.Direction.OUT )
-        nets['vdd'].setType( Net.Type.POWER )
-        nets['vdd'].setDirection( Net.Direction.IN )
-        nets['vss'].setType( Net.Type.GROUND )
-        nets['vss'].setDirection( Net.Direction.IN )
-
-        # create series of stepped pins
-        x = space*20
-        wid = space
-        step = wid*5
-        for cname in ['ref_v', 'div_out_test', 'a0', 'a1', 'vco_test_ana',
-                      'out_v', 'vdd', 'vss']:
-            net = nets[cname]
-            pin = Vertical.create(
-                net, tech.getLayer('metal1'),
-                u(x), u(wid), u(0), u(space*15),
-            )
-            x += step
-            net.setExternal(True)
-            NetExternalComponents.setExternal(pin)
-
-        if False:
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((1.105,1.0),(1.4375,1.0),(1.4375,0.24),(0.9625,0.24),(0.9625,1.0),(1.105,1.0)),
-            )
-            net = nets['*']
-            createRL(
-                tech, net, 'nimplant',
-                ((1.105,0.235),(0.895,0.235),(0.895,0.17),(0.705,0.17),(0.705,0.235),(0.55,0.235),(0.55,0.615),(0.495,0.615),(0.495,0.55),(0.305,0.55),(0.305,0.615),(0.1575,0.615),(0.1575,1.385),(0.305,1.385),(0.305,1.45),(0.495,1.45),(0.495,1.385),(0.65,1.385),(0.65,1.005),(0.705,1.005),(0.705,1.07),(0.895,1.07),(0.895,1.005),(1.105,1.005),(1.105,1.07),(1.295,1.07),(1.295,1.005),(1.4425,1.005),(1.4425,0.235),(1.295,0.235),(1.295,0.17),(1.105,0.17),(1.105,0.235)),
-            )
-            createRL(
-                tech, net, 'nimplant',
-                ((0.515,3.595),(0.515,3.765),(0.685,3.765),(0.685,3.595),(0.515,3.595)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((1.105,0.17),(1.105,1.07),(1.295,1.07),(1.295,0.17),(1.105,0.17)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((1.105,2.13),(1.105,3.87),(1.295,3.87),(1.295,2.13),(1.105,2.13)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((0.305,0.55),(0.305,1.45),(0.495,1.45),(0.495,0.55),(0.305,0.55)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((0.305,2.53),(0.305,3.47),(0.495,3.47),(0.495,2.53),(0.305,2.53)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((0.705,0.17),(0.705,1.07),(0.895,1.07),(0.895,0.17),(0.705,0.17)),
-            )
-            createRL(
-                tech, net, 'vthg',
-                ((0.705,2.53),(0.705,3.47),(0.895,3.47),(0.895,2.53),(0.705,2.53)),
-            )
-            createRL(
-                tech, net, 'pimplant',
-                ((1.105,2.195),(0.9575,2.195),(0.9575,2.595),(0.895,2.595),(0.895,2.53),(0.705,2.53),(0.705,2.595),(0.7,2.595),(0.495,2.595),(0.495,2.53),(0.305,2.53),(0.305,2.595),(0.15,2.595),(0.15,3.6825),(0.25,3.6825),(0.25,3.405),(0.305,3.405),(0.305,3.47),(0.495,3.47),(0.495,3.405),(0.5,3.405),(0.705,3.405),(0.705,3.47),(0.895,3.47),(0.895,3.405),(0.95,3.405),(0.95,3.7875),(0.9575,3.7875),(0.9575,3.805),(1.105,3.805),(1.105,3.87),(1.295,3.87),(1.295,3.805),(1.4425,3.805),(1.4425,2.195),(1.295,2.195),(1.295,2.13),(1.105,2.13),(1.105,2.195)),
-            )
-            createRL(
-                tech, net, 'pimplant',
-                ((0.115,0.195),(0.115,0.365),(0.285,0.365),(0.285,0.195),(0.115,0.195)),
-            )
-        if False:
-            net = nets['vss']
-            createRL(
-                tech, net, 'pwell',
-                ((-0.12,-0.32),(-0.12,1.92),(1.72,1.92),(1.72,-0.32),(-0.12,-0.32)),
-            )
-            createRL(
-                tech, net, 'metal1',
-                ((0.0,0.0),(0.0,0.48),(1.6,0.48),(1.6,0.0),(0.0,0.0)),
-            )
-            if False:
-                Vertical.create(
-                    net, tech.getLayer('metal1.pin'),
-                    u(0.8), u(1.6), u(0.0), u(0.48),
-                )
-            pin = Vertical.create(
-                net, tech.getLayer('metal1'),
-                u(0.8), u(1.6), u(0.0), u(0.48),
-            )
-            net.setExternal(True)
-            NetExternalComponents.setExternal(pin)
-            createRL(
-                tech, net, 'active',
-                ((0.12,0.2),(0.12,0.36),(0.28,0.36),(0.28,0.2),(0.12,0.2)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.9625,0.3075),(1.0375,0.3075),(1.0375,0.3825),(0.9625,0.3825),(0.9625,0.3075)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.1675,0.2475),(0.2325,0.2475),(0.2325,0.3125),(0.1675,0.3125),(0.1675,0.2475)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,0.3125),(1.0325,0.3125),(1.0325,0.3775),(0.9675,0.3775),(0.9675,0.3125)),
-            )
-        if False:
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((1.105,3.8),(1.4375,3.8),(1.4375,2.2),(0.9625,2.2),(0.9625,3.8),(1.105,3.8)),
-            )
-        if False:
+        lib  = Library.create( rootlib, 'pll' )
+        cell = Cell.create( lib, 'pll' )
+
+        cell.setAbutmentBox( Box( 0, 0, (15+2)*sliceHeight, (13+2)*sliceHeight ) )
+        nets     = {}
+        netSpecs = ( ( 'a0'          , None           , Net.Direction.IN , True )
+                   , ( 'a1'          , None           , Net.Direction.IN , True )
+                   , ( 'ref_v'       , None           , Net.Direction.IN , True )
+                   , ( 'out_v'       , None           , Net.Direction.OUT, True )
+                   , ( 'vco_test_ana', None           , Net.Direction.OUT, True )
+                   , ( 'div_out_test', None           , Net.Direction.OUT, True )
+                   , ( 'vdd'         , Net.Type.POWER , Net.Direction.IN , True )
+                   , ( 'vss'         , Net.Type.GROUND, Net.Direction.IN , True )
+                   , ( 'blockageNet' , None           , Net.Direction.IN , True )
+                   )
+        for name, netType, direction, external in netSpecs:
+            nets[ name ] = Net.create( cell, name )
+            if netType   is not None: nets[name].setType     ( netType )
+            if direction is not None: nets[name].setDirection( direction )
+            if external  is not None: nets[name].setExternal ( external )
+        blockageArea = Box( cell.getAbutmentBox() )
+        blockageArea.inflate( -sliceHeight )
+        for layer in (BLOCKAGE1, BLOCKAGE2, BLOCKAGE3, BLOCKAGE4):
+            Pad.create( nets['blockageNet'], layer, blockageArea )
+        METAL2pitch   = rg.getLayerGauge( METAL2 ).getPitch()
+        METAL3pitch   = rg.getLayerGauge( METAL3 ).getPitch()
+        METAL2width   = rg.getLayerGauge( METAL2 ).getWireWidth()
+        METAL3width   = rg.getLayerGauge( METAL3 ).getWireWidth()
+
+        xref = cell.getAbutmentBox().getXMin() + sliceHeight
+        yref = cell.getAbutmentBox().getYMax() - sliceHeight + METAL2pitch
+        for name, xpitchs in (('a0',20), ('ref_v',75), ('a1',130)):
+            segment = Vertical.create( nets[name]
+                                     , METAL3
+                                     , xref + xpitchs*METAL3pitch
+                                     , METAL3width
+                                     , yref
+                                     , yref - sliceHeight )
+            segment = Vertical.create( nets[name]
+                                     , METAL3
+                                     , xref + xpitchs*METAL3pitch
+                                     , METAL3width
+                                     , yref
+                                     , yref - METAL2pitch )
+            NetExternalComponents.setExternal( segment )
+
+        xref = cell.getAbutmentBox().getXMin() + sliceHeight - METAL3pitch
+        yref = cell.getAbutmentBox().getYMin() + sliceHeight
+        for name, ypitchs in (('vco_test_ana',65), ('div_out_test',120)):
+            segment = Horizontal.create( nets[name]
+                                       , METAL2
+                                       , yref + ypitchs*METAL2pitch
+                                       , METAL2width
+                                       , xref
+                                       , xref + sliceHeight )
+            segment = Horizontal.create( nets[name]
+                                       , METAL2
+                                       , yref + ypitchs*METAL2pitch
+                                       , METAL2width
+                                       , xref
+                                       , xref + METAL3pitch )
+            NetExternalComponents.setExternal( segment )
+
+        xref = cell.getAbutmentBox().getXMax() - 2*sliceHeight + METAL3pitch
+        yref = cell.getAbutmentBox().getYMin() +  sliceHeight
+        for name, ypitchs in (('out_v',120),):
+            segment = Horizontal.create( nets[name]
+                                       , METAL2
+                                       , yref + ypitchs*METAL2pitch
+                                       , METAL2width
+                                       , xref
+                                       , xref + sliceHeight )
+            segment = Horizontal.create( nets[name]
+                                       , METAL2
+                                       , yref + ypitchs*METAL2pitch
+                                       , METAL2width
+                                       , xref + sliceHeight
+                                       , xref + sliceHeight - METAL3pitch )
+            NetExternalComponents.setExternal( segment )
+
+        xmin = cell.getAbutmentBox().getXMin() +   sliceHeight
+        xmax = cell.getAbutmentBox().getXMax() -   sliceHeight
+        yref = cell.getAbutmentBox().getYMin() + 2*sliceHeight
+        for i in range(4):
             net = nets['vdd']
-            createRL(
-                tech, net, 'nwell',
-                ((-0.12,1.92),(-0.12,4.32),(1.72,4.32),(1.72,1.92),(-0.12,1.92)),
-            )
-            createRL(
-                tech, net, 'metal1',
-                ((0.0,3.52),(0.0,4.0),(1.6,4.0),(1.6,3.52),(0.0,3.52)),
-            )
-            if False:
-                Vertical.create(
-                    net, tech.getLayer('metal1.pin'),
-                    u(0.8), u(1.6), u(3.52), u(4.0),
-                )
-            pin = Vertical.create(
-                net, tech.getLayer('metal1'),
-                u(0.8), u(1.6), u(3.52), u(4.0),
-            )
-            net.setExternal(True)
-            NetExternalComponents.setExternal(pin)
-            createRL(
-                tech, net, 'active',
-                ((0.52,3.6),(0.52,3.76),(0.68,3.76),(0.68,3.6),(0.52,3.6)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.9625,3.5675),(1.0375,3.5675),(1.0375,3.7825),(0.9625,3.7825),(0.9625,3.5675)),
-            )
-            createRL(
-                tech, net, 'active',
-                ((0.1625,3.6025),(0.2375,3.6025),(0.2375,3.6775),(0.1625,3.6775),(0.1625,3.6025)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.5675,3.6475),(0.6325,3.6475),(0.6325,3.7125),(0.5675,3.7125),(0.5675,3.6475)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,3.5725),(1.0325,3.5725),(1.0325,3.6375),(0.9675,3.6375),(0.9675,3.5725)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.9675,3.7125),(1.0325,3.7125),(1.0325,3.7775),(0.9675,3.7775),(0.9675,3.7125)),
-            )
-            createRL(
-                tech, net, 'contact',
-                ((0.1675,3.6075),(0.2325,3.6075),(0.2325,3.6725),(0.1675,3.6725),(0.1675,3.6075)),
-            )
-        if False:
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((0.305,1.38),(0.495,1.38),(0.495,0.62),(0.1625,0.62),(0.1625,1.38),(0.305,1.38)),
-            )
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((0.425,2.6),(0.155,2.6),(0.155,3.6775),(0.245,3.6775),(0.245,3.4),(0.705,3.4),(0.705,2.6),(0.425,2.6)),
-            )
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((0.705,1.0),(1.0375,1.0),(1.0375,0.24),(0.555,0.24),(0.555,1.0),(0.705,1.0)),
-            )
-            createRL(
-                tech, net, 'poly',
-                ((0.775,2.545),(0.775,3.455),(0.825,3.455),(0.825,2.0375),(0.9975,2.0375),(0.9975,1.9625),(0.775,1.9625),(0.775,2.545)),
-            )
-            createRL(
-                tech, net, 'metal1',
-                ((0.9675,1.2675),(0.9675,1.9325),(0.9275,1.9325),(0.9275,2.0675),(0.9675,2.0675),(0.9675,3.455),(1.0325,3.455),(1.0325,0.545),(0.9675,0.545),(0.9675,1.1325),(0.9275,1.1325),(0.9275,1.2675),(0.9675,1.2675)),
-            )
-        if False:
-            Vertical.create(
-                net, tech.getLayer('metal1.pin'),
-                u(1.0), u(0.065), u(0), u(3.455),
-            )
-        pin = Vertical.create(
-            net, tech.getLayer('metal1'),
-            u(1.0), u(0.065), u(0), u(3.455),
-        )
-        net.setExternal(True)
-        NetExternalComponents.setExternal(pin)
-        createRL(
-            tech, net, 'contact',
-            ((0.9275,1.1675),(0.9925,1.1675),(0.9925,1.2325),(0.9275,1.2325),(0.9275,1.1675)),
-        )
-        createRL(
-            tech, net, 'contact',
-            ((0.9275,1.9675),(0.9925,1.9675),(0.9925,2.0325),(0.9275,2.0325),(0.9275,1.9675)),
-        )
-        if False:
-            net = nets['*']
-            createRL(
-                tech, net, 'active',
-                ((0.775,2.6),(0.705,2.6),(0.705,3.4),(0.955,3.4),(0.955,3.7825),(1.045,3.7825),(1.045,2.6),(0.775,2.6)),
-            )
-
-
-    af.wrapLibrary(lib, 0)
+            if i % 2:
+                net = nets['vss']
+            segment = Horizontal.create( net
+                                       , METAL5
+                                       , yref + sliceHeight*3*i
+                                       , 2*sliceHeight
+                                       , xmin
+                                       , xmax )
+            NetExternalComponents.setExternal( segment )
+            
+    af.wrapLibrary( lib, 0 )
 
     return lib
 
 def setup():
     lib = _load()
-    _routing()
-
     return lib