235 lines
7.8 KiB
Python
Executable File
235 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import Cfg
|
|
from Hurricane3 import DbU, Point, Box, DataBase, Technology, LayerMask, \
|
|
BasicLayer, ViaLayer, RegularLayer
|
|
from overlay import CfgCache
|
|
from technology import createBL
|
|
|
|
def flush ():
|
|
sys.stdout.flush()
|
|
sys.stderr.flush()
|
|
|
|
#def u ( value ): return value
|
|
#def l ( value ): return value
|
|
def l ( value ): return DbU.fromLambda( value )
|
|
def u ( value ): return DbU.fromPhysical( value, DbU.UnitPowerMicro )
|
|
def n ( value ): return DbU.fromPhysical( value, DbU.UnitPowerNano )
|
|
|
|
def cfg_setup():
|
|
print( "" )
|
|
print( "Test Cfg module" )
|
|
print( "========================================" )
|
|
# 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.latchUpDistance = u(30.0 - 1.0)
|
|
cfg.etesian.latchUpDistance = 0
|
|
cfg.etesian.antennaInsertThreshold = 0.50
|
|
cfg.etesian.antennaMaxWL = u(250.0)
|
|
cfg.etesian.antennaGateMaxWL = u(250.0)
|
|
cfg.etesian.antennaDiodeMaxWL = u(550.0)
|
|
cfg.etesian.tieName = 'tiepoly_x0'
|
|
cfg.etesian.feedNames = 'tiepoly_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 = 'FlexLib'
|
|
cfg.anabatic.globalLengthThreshold = 1450
|
|
cfg.anabatic.saturateRatio = 0.90
|
|
cfg.anabatic.saturateRp = 10
|
|
cfg.anabatic.topRoutingLayer = 'METAL6'
|
|
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.viewer.minimumSize = 500
|
|
cfg.viewer.pixelThreshold = 20
|
|
cfg.chip.block.rails.count = 0
|
|
cfg.chip.block.rails.hWidth = u(2.68)
|
|
cfg.chip.block.rails.vWidth = u(2.68)
|
|
cfg.chip.block.rails.hSpacing = 0 #u(0.7)
|
|
cfg.chip.block.rails.vSpacing = 0 #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
|
|
|
|
|
|
def testDbU ():
|
|
print( "" )
|
|
print( "Test Hurricane::DbU" )
|
|
print( "========================================" )
|
|
DbU.setPrecision( 2 )
|
|
DbU.setPhysicalsPerGrid( 0.5, DbU.UnitPowerMicro )
|
|
DbU.setGridsPerLambda( 2.0 )
|
|
DbU.setSymbolicSnapGridStep( DbU.fromLambda(1.0) )
|
|
DbU.setPolygonStep(DbU.fromGrid( 2.0) )
|
|
DbU.setStringMode( DbU.StringModeSymbolic, DbU.UnitPowerMicro )
|
|
value = DbU.fromPhysical( 10.0, DbU.UnitPowerMicro )
|
|
print( "value={}".format( DbU.getValueString(value) ))
|
|
|
|
|
|
def testPoint ():
|
|
print( "" )
|
|
print( "Test Hurricane::Point" )
|
|
print( "========================================" )
|
|
p1 = Point( 1000, 2000 )
|
|
print( p1 )
|
|
p2 = Point( 1000, 2000 )
|
|
print( p1 == p2 )
|
|
p3 = Point( 2000, 2000 )
|
|
print( p1 == p3 )
|
|
p4 = Point( p3 )
|
|
print( p4 )
|
|
|
|
|
|
def testBox ():
|
|
print( "" )
|
|
print( "Test Hurricane::Box" )
|
|
print( "========================================" )
|
|
b1 = Box()
|
|
print( b1 )
|
|
b1.merge( Point(1000,1000) )
|
|
print( 'b1.merge(Point(1000,1000)={}'.format(b1) )
|
|
b1.merge( Box(Point(2000,2000)) )
|
|
print( 'b1.merge(Box(Point(1000,1000))={}'.format(b1) )
|
|
print( 'b1.getCenter()={}'.format(b1.getCenter()) )
|
|
p1 = Point( 1000, 1000 )
|
|
b2 = Box( p1 )
|
|
print( b2 )
|
|
|
|
|
|
def testDB ():
|
|
print( "" )
|
|
print( "Test Hurricane::DataBase" )
|
|
print( "========================================" )
|
|
db = DataBase.create()
|
|
print( 'DataBase.getDB()={}'.format(DataBase.getDB()) )
|
|
print( 'DataBase.Flags.CreateLib={}'.format(DataBase.Flags.CreateLib) )
|
|
|
|
|
|
def testTechnology ():
|
|
print( "" )
|
|
print( "Test Hurricane::Technology" )
|
|
print( "========================================" )
|
|
tech = Technology.create( DataBase.getDB(), 'test_techno' )
|
|
print( 'tech={}'.format(tech) )
|
|
|
|
|
|
def testLayerMask ():
|
|
print( "" )
|
|
print( "Test Hurricane::Layer::Mask" )
|
|
print( "========================================" )
|
|
mask16 = LayerMask( 16 )
|
|
print( 'mask16= {}'.format(mask16) )
|
|
mask32 = LayerMask( 16+32 )
|
|
print( 'mask16= {}'.format(mask32) )
|
|
maskAnd = mask16 & mask32
|
|
print( 'maskAnd={}'.format(maskAnd) )
|
|
try:
|
|
maskAnd = mask16 & 4
|
|
print( 'maskAnd={}'.format(maskAnd) )
|
|
except Exception as e:
|
|
print( 'Catched and exception...' )
|
|
print( e )
|
|
maskShift = maskAnd << 1
|
|
print( 'maskShift={}'.format(maskShift) )
|
|
maskNot = ~maskAnd
|
|
print( 'maskNot={}'.format(maskNot) )
|
|
print( 'maskAnd={}'.format(maskAnd) )
|
|
mask64 = LayerMask( 64+16 )
|
|
print( 'mask64={}'.format(mask64) )
|
|
mask64 &= LayerMask( 64 )
|
|
print( 'mask64={}'.format(mask64) )
|
|
mask64 |= LayerMask( 16 )
|
|
print( 'mask64={}'.format(mask64) )
|
|
mask64.fromString( '0x0000ffff' )
|
|
print( 'mask64={}'.format(mask64) )
|
|
|
|
|
|
def testBasicLayer ():
|
|
print( "" )
|
|
print( "Test Hurricane::BasicLayer" )
|
|
print( "========================================" )
|
|
db = DataBase.getDB()
|
|
tech = db.getTechnology()
|
|
nWell = createBL( tech, 'nWell' , BasicLayer.Material.nWell )
|
|
pWell = createBL( tech, 'pWell' , BasicLayer.Material.pWell )
|
|
cut1 = createBL( tech, 'cut1' , BasicLayer.Material.cut )
|
|
metal1 = createBL( tech, 'metal1', BasicLayer.Material.metal )
|
|
metal2 = createBL( tech, 'metal2', BasicLayer.Material.metal )
|
|
METAL1 = RegularLayer.create( tech, 'METAL1', metal1 )
|
|
METAL2 = RegularLayer.create( tech, 'METAL2', metal2 )
|
|
VIA12 = ViaLayer .create( tech, 'VIA12' , metal1, cut1, metal2 )
|
|
print( 'nWell={}'.format(nWell) )
|
|
print( 'pWell={}'.format(pWell) )
|
|
print( dir(nWell) )
|
|
print( 'Technology.getLayers():' )
|
|
flush()
|
|
for layer in tech.getLayers():
|
|
flush()
|
|
print( '| basicLayer={}'.format(layer) )
|
|
flush()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
testDbU()
|
|
cfg_setup()
|
|
testPoint()
|
|
testBox()
|
|
testDB()
|
|
testTechnology()
|
|
testLayerMask()
|
|
testBasicLayer()
|
|
sys.exit( 0 )
|