Support for separated NDA tree. Big cleanup of the Python init system.

* Change: In Hurricane::Script, when running a script, no longer do it
    inside a Python sun-interpreter, use the current one. This way we
    no longer have our modules initialized twice or more, which was
    starting to be unmanageable (with the NDA support).
      The settings were re-read multiple time to the same value, so it
    was working, but still...
      I hope I didn't left some dangling Python objects now.
* Bug: In Hurricane::LayoutGenerator::drawLayout(), get the device abutment
    box though a Pyhon object *before* finalizing which removes that objet.
* New: In cumulus/plugins/__init__.py, add a "loadPlugins()" and static
    initialisation to preload plugins modules.
      We use that pre-loading step to append to the module __path__ attribute
    the alternate directory where a NDA covered may be found. This assume that
    the directory tree under the NDA root is identical to the one under the
    public root.
* New: In cumulus/plugins/chip/__init__.py, small utility function
    importContants() to import the constants inside another module namespace,
    to have more consise notations.
* Change: In cumulus/plugins/, in the various plugins sub-modules import
    use the full path from plugins, that is, for example:
      from plugins.core2chip.CoreToChip import IoPad
* Change: In Unicorn/python/unicornInit.py, no longer directly load the
    plugins modules, this is now done by cumulus/plugins/__init__.py.
      Instead, iterate through sys.modules for the ones starting by "plugins/"
    and try to execute a Unicorn hook, if present.
* Change: In Karakaze/python/AnalogDesign.py, update for the new Instance.create()
    prototype (added placement parameter).
This commit is contained in:
Jean-Paul Chaput 2019-10-11 17:36:54 +02:00
parent ae98b117ba
commit 5bbeb0b062
20 changed files with 322 additions and 216 deletions

View File

@ -217,9 +217,6 @@ layersExtensionsTable = \
)
for entry in layersExtensionsTable:
print entry
# Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number)
gdsLayersTable = \

View File

@ -29,6 +29,7 @@ import helpers.io
quiet = False
sysConfDir = None
ndaConfDir = None
ndaDir = None
techno = 'symbolic/cmos'
technoDir = None
unitsLambda = True
@ -65,8 +66,8 @@ def textStackTrace ( trace, showIndent=True, scriptPath=None ):
s = ''
if scriptPath:
if len(scriptPath) > 70:
filename = scriptPath[-70:]
if len(scriptPath) > 100:
filename = scriptPath[-100:]
filename = '.../' + filename[ filename.find('/')+1 : ]
if showIndent: s += '[ERROR] '
@ -78,8 +79,8 @@ def textStackTrace ( trace, showIndent=True, scriptPath=None ):
maxdepth = len( trace )
for depth in range( maxdepth ):
filename, line, function, code = trace[ maxdepth-depth-1 ]
if len(filename) > 38:
filename = filename[-38:]
if len(filename) > 58:
filename = filename[-58:]
filename = '.../' + filename[ filename.find('/')+1 : ]
#s += indent + '[%02d] %45s:%-5d in \"%s()\"' % ( maxdepth-depth-1, filename, line, function )
s += indent + '#%d in %25s() at %s:%d\n' % ( depth, function, filename, line )
@ -94,8 +95,8 @@ def showStackTrace ( trace ):
def textPythonTrace ( scriptPath=None, e=None, tryContinue=True ):
s = ''
if scriptPath:
if len(scriptPath) > 70:
filename = scriptPath[-70:]
if len(scriptPath) > 100:
filename = scriptPath[-100:]
filename = '.../' + filename[ filename.find('/')+1 : ]
else:
filename = scriptPath
@ -250,6 +251,7 @@ def n ( value ): return Hurricane.DbU.fromPhysical( value, Hurricane.DbU.UnitPow
def initTechno ( argQuiet ):
global quiet
global ndaDir
global ndaConfDir
global technoDir
global techno
@ -273,6 +275,7 @@ def initTechno ( argQuiet ):
print '[WARNING] The technology is not set. Using <%s>.' % techno
if moduleGlobals.has_key('NdaDirectory'):
ndaDir = NdaDirectory
ndaConfDir = os.path.join( NdaDirectory, 'etc/coriolis2' )
else:
ndaConfDir = sysConfDir
@ -288,7 +291,9 @@ def staticInitialization ( quiet=False ):
global _trace
global unitsLambda
if sysConfDir != None: return
if sysConfDir != None:
#if not quiet: print ' o helpers.staticInitialization() Already run, exit.'
return
unitsLamba = True
tab = Tab()
@ -300,7 +305,7 @@ def staticInitialization ( quiet=False ):
for path in sys.path:
if reSysConfDir.match(path):
sysConfDir = path
#if not quiet: print ' - <%s>' % sysConfDir
if not quiet: print ' - "%s"' % sysConfDir
break
if not sysConfDir:
@ -313,7 +318,7 @@ def staticInitialization ( quiet=False ):
raise ErrorMessage( 1, [ 'Cannot locate the directoty holding the configuration files.'
, 'The path is something ending by <.../etc/coriolis2>.'] )
if not quiet: print ' - <%s>' % sysConfDir
if not quiet: print ' - "%s"' % sysConfDir
initTechno( quiet )
return

View File

@ -7,7 +7,6 @@
set ( pyPlugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.py
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_c35b4.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_phlib80.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py
@ -23,7 +22,6 @@
set ( pyPluginC2C ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/cmos.py
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/c35b4.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/phlib80.py
)
set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.py

View File

@ -21,7 +21,7 @@ try:
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
import chip.Chip
import chip
except ImportError, e:
serror = str(e)
if serror.startswith('No module named'):

View File

@ -14,7 +14,10 @@
# +-----------------------------------------------------------------+
import os
import sys
import Cfg
import helpers
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
from Hurricane import Contact
@ -29,6 +32,7 @@ from CRL import RoutingLayerGauge
NoFlags = 0000
ShowWarnings = 0001
WarningsAreErrors = 0002
loaded = False
@ -185,3 +189,78 @@ class StackedVia ( object ):
) )
#print ' Sub-via: ', self._vias[-1]
return
def loadPlugins ( pluginsDir ):
sys.path.append( pluginsDir )
sys.modules['plugins'].__path__.append( pluginsDir )
if not os.path.isdir(pluginsDir):
print ErrorMessage( 3, 'cumulus.__init__.py: Cannot find <cumulus/plugins> directory:' \
, '<%s>' % pluginsDir )
return
moduleNames = []
for entry in os.listdir( pluginsDir ):
if entry == "__init__.py": continue
if not entry.endswith('.py'):
path = os.path.join(pluginsDir,entry)
if os.path.isdir(path):
packageName = "plugins." + entry
if not sys.modules.has_key(packageName):
module = __import__( packageName, globals(), locals() )
else:
module = sys.modules[packageName]
#print ' - P "%s" %s %s' % (packageName,module.__name__,path)
module.__path__.append( path )
#for element in module.__path__:
# print element
continue
moduleNames.append( entry[:-3] )
#names = []
#for moduleName in sys.modules: names.append( moduleName )
#names.sort()
#for name in names: print '| "%s"' % name
moduleNames.sort()
for moduleName in moduleNames:
try:
print ' - "%s"' % moduleName
module = __import__( moduleName, globals(), locals() )
except ErrorMessage, e:
print e
helpers.showStackTrace( e.trace )
except Exception, e:
helpers.showPythonTrace( __file__, e )
return
def staticInitialization ():
global loaded
if loaded: return
helpers.staticInitialization( quiet=False )
try:
print ' o Preload standard plugins.'
pluginsDir = os.path.dirname(__file__)
loadPlugins( pluginsDir )
if helpers.ndaDir:
print ' o Preload NDA protected plugins.'
pluginsDir = os.path.join( helpers.ndaDir, 'python2.7/site-packages/cumulus/plugins' )
loadPlugins( pluginsDir )
else:
print ' o No NDA protected plugins.'
except Exception, e:
helpers.showPythonTrace( __file__, e )
loaded = True
return
staticInitialization()

View File

@ -37,7 +37,10 @@ from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
from plugins import StackedVia
import chip.BlockPower
import chip
chip.importConstants( globals() )
class IntervalSet ( object ):
@ -372,8 +375,8 @@ class SouthSide ( HorizontalSide ):
return self.innerBb.getYMin() - self.hRailWidth/2 - self.hRailSpace \
- i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthWest][i]
def corner1 ( self, i ): return self.corners[chip.SouthEast][i]
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[SouthEast][i]
class NorthSide ( HorizontalSide ):
@ -386,8 +389,8 @@ class NorthSide ( HorizontalSide ):
return self.innerBb.getYMax() + self.hRailWidth/2 + self.hRailSpace \
+ i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[chip.NorthWest][i]
def corner1 ( self, i ): return self.corners[chip.NorthEast][i]
def corner0 ( self, i ): return self.corners[NorthWest][i]
def corner1 ( self, i ): return self.corners[NorthEast][i]
class VerticalSide ( Side ):
@ -449,8 +452,8 @@ class WestSide ( VerticalSide ):
return self.innerBb.getXMin() - self.vRailWidth/2 - self.vRailSpace \
- i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthWest][i]
def corner1 ( self, i ): return self.corners[chip.NorthWest ][i]
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[NorthWest ][i]
def addBlockages ( self ):
sideXMin = self.getOuterRail(0).axis - self.vRailWidth
@ -469,8 +472,8 @@ class EastSide ( VerticalSide ):
return self.innerBb.getXMax() + self.vRailWidth/2 + self.vRailSpace \
+ i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthEast][i]
def corner1 ( self, i ): return self.corners[chip.NorthEast ][i]
def corner0 ( self, i ): return self.corners[SouthEast][i]
def corner1 ( self, i ): return self.corners[NorthEast ][i]
def addBlockages ( self ):
sideXMin = self.getInnerRail(0).axis - self.vRailWidth
@ -532,10 +535,10 @@ class Corona ( object ):
def connectBlock ( self ):
for plane in self.block.planes.values():
for side in plane.sides.values():
self.southSide.connect( side[chip.South] )
self.northSide.connect( side[chip.North] )
self.westSide .connect( side[chip.West ] )
self.eastSide .connect( side[chip.East ] )
self.southSide.connect( side[South] )
self.northSide.connect( side[North] )
self.westSide .connect( side[West ] )
self.eastSide .connect( side[East ] )
return
def connectPads ( self, padsCorona ):
@ -546,10 +549,10 @@ class Corona ( object ):
return
def doLayout ( self ):
self.corners = { chip.SouthWest : []
, chip.SouthEast : []
, chip.NorthWest : []
, chip.NorthEast : []
self.corners = { SouthWest : []
, SouthEast : []
, NorthWest : []
, NorthEast : []
}
contactDepth = self.horizontalDepth
@ -575,28 +578,28 @@ class Corona ( object ):
trBox.merge( xTR, yTR )
self.routingGauge.getContactLayer(contactDepth)
self.corners[chip.SouthWest].append(
self.corners[SouthWest].append(
Contact.create( net
, self.routingGauge.getContactLayer(contactDepth)
, xBL, yBL
, self.hRailWidth
, self.vRailWidth
) )
self.corners[chip.NorthWest].append(
self.corners[NorthWest].append(
Contact.create( net
, self.routingGauge.getContactLayer(contactDepth)
, xBL, yTR
, self.hRailWidth
, self.vRailWidth
) )
self.corners[chip.SouthEast].append(
self.corners[SouthEast].append(
Contact.create( net
, self.routingGauge.getContactLayer(contactDepth)
, xTR, yBL
, self.hRailWidth
, self.vRailWidth
) )
self.corners[chip.NorthEast].append(
self.corners[NorthEast].append(
Contact.create( net
, self.routingGauge.getContactLayer(contactDepth)
, xTR, yTR

View File

@ -33,7 +33,10 @@ import helpers
from helpers import trace
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import chip.Configuration
import plugins
import chip
chip.importConstants( globals() )
class Side ( object ):
@ -81,26 +84,26 @@ class Side ( object ):
return
def doLayout ( self ):
if self.side == chip.West:
if self.side == West:
width = 0
x = self.block.bb.getXMin()
elif self.side == chip.East:
elif self.side == East:
width = 0
x = self.block.bb.getXMax()
elif self.side == chip.South:
elif self.side == South:
height = 0
y = self.block.bb.getYMin()
elif self.side == chip.North:
elif self.side == North:
height = 0
y = self.block.bb.getYMax()
minWidth = DbU.fromLambda( 6.0 )
for terminal in self.terminals:
if self.side == chip.West or self.side == chip.East:
if self.side == West or self.side == East:
center = Point( x, terminal[0].getCenter() )
height = terminal[0].getSize() - self.deltaWidth
if height < minWidth: height = minWidth
elif self.side == chip.North or self.side == chip.South:
elif self.side == North or self.side == South:
center = Point( terminal[0].getCenter(), y )
width = terminal[0].getSize() - self.deltaWidth
if width < minWidth: width = minWidth
@ -125,24 +128,24 @@ class Plane ( object ):
def addTerminal ( self, net, direction, bb ):
if not self.sides.has_key(net):
self.sides[ net ] = { chip.North : Side(self.block,chip.North,net,self.metal)
, chip.South : Side(self.block,chip.South,net,self.metal)
, chip.East : Side(self.block,chip.East ,net,self.metal)
, chip.West : Side(self.block,chip.West ,net,self.metal)
self.sides[ net ] = { North : Side(self.block,North,net,self.metal)
, South : Side(self.block,South,net,self.metal)
, East : Side(self.block,East ,net,self.metal)
, West : Side(self.block,West ,net,self.metal)
}
sides = self.sides[ net ]
if direction == Plane.Horizontal:
if bb.getXMin() <= self.block.bb.getXMin():
sides[chip.West].addTerminal( bb.getCenter().getY(), bb.getHeight() )
sides[West].addTerminal( bb.getCenter().getY(), bb.getHeight() )
if bb.getXMax() >= self.block.bb.getXMax():
sides[chip.East].addTerminal( bb.getCenter().getY(), bb.getHeight() )
sides[East].addTerminal( bb.getCenter().getY(), bb.getHeight() )
if direction == Plane.Vertical:
if bb.getYMin() <= self.block.bb.getYMin():
sides[chip.South].addTerminal( bb.getCenter().getX(), bb.getWidth() )
sides[South].addTerminal( bb.getCenter().getX(), bb.getWidth() )
if bb.getYMax() >= self.block.bb.getYMax():
sides[chip.North].addTerminal( bb.getCenter().getX(), bb.getWidth() )
sides[North].addTerminal( bb.getCenter().getX(), bb.getWidth() )
return
def doLayout ( self ):
@ -166,8 +169,8 @@ class GoCb ( object ):
if not direction: return
rootNet = None
if go.getNet().getType() == Net.Type.POWER: rootNet = self.block.conf.coronaVdd
if go.getNet().getType() == Net.Type.GROUND: rootNet = self.block.conf.coronaVss
if go.getNet().getType() == long(Net.Type.POWER): rootNet = self.block.conf.coronaVdd
if go.getNet().getType() == long(Net.Type.GROUND): rootNet = self.block.conf.coronaVss
if not rootNet: return
if self.block.activePlane:

View File

@ -53,10 +53,10 @@ try:
import Unicorn
import plugins
import clocktree.ClockTree
import chip.Configuration
import chip
import chip.PadsCorona
import chip.BlockPower
import chip.BlockCorona
import chip.PadsCorona
except ImportError, e:
serror = str(e)
if serror.startswith('No module named'):

View File

@ -478,9 +478,15 @@ class ChipConf ( object ):
if isinstance(v,long): return ChipConf._toSymbolic( v, rounding )
if isinstance(v,Box):
if rounding & chip.Inwards:
roundings = [ chip.Superior, chip.Superior, chip.Inferior, chip.Inferior ]
roundings = [ chip.Superior
, chip.Superior
, chip.Inferior
, chip.Inferior ]
else:
roundings = [ chip.Inferior, chip.Inferior, chip.Superior, chip.Superior ]
roundings = [ chip.Inferior
, chip.Inferior
, chip.Superior
, chip.Superior ]
xMin = ChipConf._toSymbolic( v.getXMin(), roundings[0] )
yMin = ChipConf._toSymbolic( v.getYMin(), roundings[1] )
xMax = ChipConf._toSymbolic( v.getXMax(), roundings[2] )

View File

@ -42,7 +42,9 @@ import helpers
from helpers import trace
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import chip.Configuration
import chip
chip.importConstants( globals() )
class Corner ( object ):
@ -59,22 +61,22 @@ class Corner ( object ):
def _getPoints ( self, axis ):
if self.type == chip.SouthWest:
if self.type == SouthWest:
xCorner = self.conf.chipSize.getXMin() + axis
yCorner = self.conf.chipSize.getYMin() + axis
xBb = self.conf.chipSize.getXMin() + self.conf.getIoPadHeight()
yBb = self.conf.chipSize.getYMin() + self.conf.getIoPadHeight()
elif self.type == chip.SouthEast:
elif self.type == SouthEast:
xCorner = self.conf.chipSize.getXMax() - axis
yCorner = self.conf.chipSize.getYMin() + axis
xBb = self.conf.chipSize.getXMax() - self.conf.getIoPadHeight()
yBb = self.conf.chipSize.getYMin() + self.conf.getIoPadHeight()
elif self.type == chip.NorthEast:
elif self.type == NorthEast:
xCorner = self.conf.chipSize.getXMax() - axis
yCorner = self.conf.chipSize.getYMax() - axis
xBb = self.conf.chipSize.getXMax() - self.conf.getIoPadHeight()
yBb = self.conf.chipSize.getYMax() - self.conf.getIoPadHeight()
elif self.type == chip.NorthWest:
elif self.type == NorthWest:
xCorner = self.conf.chipSize.getXMin() + axis
yCorner = self.conf.chipSize.getYMax() - axis
xBb = self.conf.chipSize.getXMin() + self.conf.getIoPadHeight()
@ -99,7 +101,7 @@ class Corner ( object ):
def _getTransformation ( self ):
if self.type == chip.SouthWest:
if self.type == SouthWest:
name = 'padcorner_sw'
x = self.conf.chipSize.getXMin()
y = self.conf.chipSize.getYMin()
@ -109,7 +111,7 @@ class Corner ( object ):
orientation = Transformation.Orientation.R1
x += self.padCorner.getAbutmentBox().getWidth()
elif self.type == chip.SouthEast:
elif self.type == SouthEast:
name = 'padcorner_se'
x = self.conf.chipSize.getXMax()
y = self.conf.chipSize.getYMin()
@ -120,7 +122,7 @@ class Corner ( object ):
x += self.padCorner.getAbutmentBox().getWidth()
y += self.padCorner.getAbutmentBox().getHeight()
elif self.type == chip.NorthEast:
elif self.type == NorthEast:
name = 'padcorner_ne'
x = self.conf.chipSize.getXMax()
y = self.conf.chipSize.getYMax()
@ -131,7 +133,7 @@ class Corner ( object ):
x -= self.padCorner.getAbutmentBox().getwidth()
y -= self.padCorner.getAbutmentBox().getHeight()
elif self.type == chip.NorthWest:
elif self.type == NorthWest:
name = 'padcorner_nw'
x = self.conf.chipSize.getXMin()
y = self.conf.chipSize.getYMax()
@ -172,22 +174,22 @@ class Side ( object ):
self.gap = 0
self.coreWires = []
if self.type == chip.North:
if self.type == North:
self.pads = self.conf.northPads
self.sideName = 'north'
self.sideLength = self.conf.chipSize.getWidth()
elif self.type == chip.South:
elif self.type == South:
self.pads = self.conf.southPads
self.sideName = 'south'
self.sideLength = self.conf.chipSize.getWidth()
elif self.type == chip.East:
elif self.type == East:
self.pads = self.conf.eastPads
self.sideName = 'east'
self.sideLength = self.conf.chipSize.getHeight()
elif self.type == chip.West:
elif self.type == West:
self.pads = self.conf.westPads
self.sideName = 'west'
self.sideLength = self.conf.chipSize.getHeight()
@ -207,10 +209,10 @@ class Side ( object ):
def getAxis ( self, i ):
if self.type == chip.North: return self.conf.chipSize.getYMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2]
elif self.type == chip.South: return self.conf.chipSize.getYMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2]
elif self.type == chip.East: return self.conf.chipSize.getXMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2]
elif self.type == chip.West: return self.conf.chipSize.getXMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2]
if self.type == North: return self.conf.chipSize.getYMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2]
elif self.type == South: return self.conf.chipSize.getYMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2]
elif self.type == East: return self.conf.chipSize.getXMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2]
elif self.type == West: return self.conf.chipSize.getXMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2]
else:
raise ErrorMessage( 1, 'PadsCorona.Side.__init__(): Invalid value for sideType (%d)' % sideType )
return 0
@ -236,10 +238,10 @@ class Side ( object ):
def _check ( self, checkSize, checkName ):
sideName = 'unknown'
chipSize = 0
if self.type == chip.North or self.type == chip.South:
if self.type == North or self.type == South:
chipSize = self.conf.chipSize.getWidth()
sideName = 'wide'
elif self.type == chip.East or self.type == chip.West:
elif self.type == East or self.type == West:
chipSize = self.conf.chipSize.getHeight()
sideName = 'tall'
@ -258,20 +260,20 @@ class Side ( object ):
def check ( self ):
self.validated = True
if self.type == chip.North:
if self.type == North:
self.validated = self._check( self.conf.coreSize.getWidth()
+ 2*self.conf.minCorona
+ 2*self.conf.getIoPadHeight()
, 'core' )
checkName = 'north pads'
elif self.type == chip.East:
elif self.type == East:
self.validated = self._check( self.conf.coreSize.getHeight()
+ 2*self.conf.minCorona
+ 2*self.conf.getIoPadHeight()
, 'core' )
checkName = 'east pads'
elif self.type == chip.South: checkName = 'south pads'
elif self.type == chip.West: checkName = 'west pads'
elif self.type == South: checkName = 'south pads'
elif self.type == West: checkName = 'west pads'
self.validated = self._check( len(self.pads) * self.conf.gaugeConf.getIoPadStep ()
+ 2*self.conf.gaugeConf.getIoPadHeight()
@ -391,7 +393,7 @@ class Side ( object ):
def _placePad ( self, padInstance ):
if self.type == chip.North:
if self.type == North:
x = self.conf.chipSize.getXMin() + self.u
y = self.conf.chipSize.getYMax()
@ -401,7 +403,7 @@ class Side ( object ):
orientation = Transformation.Orientation.ID
y -= self.conf.getIoPadHeight()
elif self.type == chip.South:
elif self.type == South:
x = self.conf.chipSize.getXMin() + self.u
y = self.conf.chipSize.getYMin()
@ -411,7 +413,7 @@ class Side ( object ):
orientation = Transformation.Orientation.MY
y += self.conf.getIoPadHeight()
elif self.type == chip.West:
elif self.type == West:
x = self.conf.chipSize.getXMin()
y = self.conf.chipSize.getYMin() + self.u
@ -422,7 +424,7 @@ class Side ( object ):
orientation = Transformation.Orientation.R1
x += padInstance.getMasterCell().getAbutmentBox().getHeight()
elif self.type == chip.East:
elif self.type == East:
x = self.conf.chipSize.getXMax()
y = self.conf.chipSize.getYMin() + self.u
@ -490,13 +492,13 @@ class Side ( object ):
def _getUMin ( self, box ):
if self.type == chip.North or self.type == chip.South:
if self.type == North or self.type == South:
return box.getXMin()
return box.getYMin()
def _getUMax ( self, box ):
if self.type == chip.North or self.type == chip.South:
if self.type == North or self.type == South:
return box.getXMax()
return box.getYMax()
@ -511,22 +513,22 @@ class Side ( object ):
uMin -= width/2
uMax += width/2
if self.type == chip.North or self.type == chip.South:
if self.type == chip.North:
if self.type == North or self.type == South:
if self.type == North:
axis = self.conf.chipSize.getYMax() - axis
Horizontal.create( net, layer, axis, width, uMin, uMax )
else:
if self.type == chip.East:
if self.type == East:
axis = self.conf.chipSize.getXMax() - axis
Vertical.create( net, layer, axis, width, uMin, uMax )
return
def _routePads ( self ):
if self.type == chip.South or self.type == chip.North:
if self.type == South or self.type == North:
startCorner = self.conf.chipSize.getXMin()
stopCorner = self.conf.chipSize.getXMax()
elif self.type == chip.West or self.type == chip.East:
elif self.type == West or self.type == East:
startCorner = self.conf.chipSize.getYMin()
stopCorner = self.conf.chipSize.getYMax()
else:
@ -571,10 +573,10 @@ class Side ( object ):
def drawCoreWires ( self ):
trace( 550, ',+', '\tSide.drawCoreWire()\n' )
if self.type == chip.West or self.type == chip.East:
if self.type == West or self.type == East:
trace( 550, 'Sort East/West' )
self.coreWires.sort( key=lambda wire: wire.bbSegment.getCenter().getY() )
if self.type == chip.North or self.type == chip.South:
if self.type == North or self.type == South:
trace( 550, 'Sort North/South' )
self.coreWires.sort( key=lambda wire: wire.bbSegment.getCenter().getX() )
@ -597,14 +599,14 @@ class Side ( object ):
self.coreWires[ -(offset+1) ].setOffset( i+1, CoreWire.AtEnd )
for wire in self.coreWires:
if self.type == chip.West or self.type == chip.East:
if self.type == West or self.type == East:
trace( 550, '\t| %s %s %d %s inRange:%s\n' % ( wire.chipNet.getName()
, DbU.getValueString(wire.bbSegment.getCenter().getY())
, wire.count
, wire.padSegment.getLayer()
, wire.inCoronaRange ) )
if self.type == chip.North or self.type == chip.South:
if self.type == North or self.type == South:
trace( 550, '\t| %s %s %d %s inRange:%s\n' % ( wire.chipNet.getName()
, DbU.getValueString(wire.bbSegment.getCenter().getX())
, wire.count
@ -647,12 +649,12 @@ class CoreWire ( object ):
def updateInCorona ( self ):
coronaAb = self.conf.getInstanceAb( self.conf.icorona )
if self.side == chip.South or self.side == chip.North:
if self.side == South or self.side == North:
xCoronaPin = self.bbSegment.getCenter().getX()
if xCoronaPin <= coronaAb.getXMin(): self.inCoronaRange = False
elif xCoronaPin >= coronaAb.getXMax(): self.inCoronaRange = False
if self.side == chip.East or self.side == chip.West:
if self.side == East or self.side == West:
yCoronaPin = self.bbSegment.getCenter().getY()
if yCoronaPin <= coronaAb.getYMin(): self.inCoronaRange = False
elif yCoronaPin >= coronaAb.getYMax(): self.inCoronaRange = False
@ -681,7 +683,7 @@ class CoreWire ( object ):
if self.preferredDir:
self.symContactLayer = self.symSegmentLayer
if self.side & (chip.West|chip.East):
if self.side & (West|East):
self.symContactSize = ( layerGauge.getWireWidth(), self.bbSegment.getHeight() )
else:
self.symContactSize = ( self.bbSegment.getWidth(), layerGauge.getWireWidth() )
@ -694,7 +696,7 @@ class CoreWire ( object ):
self.symSegmentLayer = rg.getLayerGauge( depth+1 ).getLayer()
self.symContactLayer = rg.getContactLayer( depth )
if self.side & (chip.West|chip.East):
if self.side & (West|East):
self.symContactSize = ( self.bbSegment.getHeight(), self.bbSegment.getHeight() )
else:
self.symContactSize = ( self.bbSegment.getWidth(), self.bbSegment.getWidth() )
@ -710,7 +712,7 @@ class CoreWire ( object ):
% (DbU.toLambda(contactMinSize),DbU.toLambda(arrayWidth),arrayCount) )
if arrayCount < 0: arrayCount = 0
if arrayCount < 3:
if self.side & (chip.North|chip.South):
if self.side & (North|South):
self.arraySize = ( arrayCount+1, 2 )
else:
self.arraySize = ( 2, arrayCount+1 )
@ -737,8 +739,8 @@ class CoreWire ( object ):
if not isinstance(padLayer,BasicLayer):
padLayer = padLayer.getBasicLayer()
if self.side == chip.West or self.side == chip.East:
flags = chip.OnHorizontalPitch
if self.side == West or self.side == East:
flags = OnHorizontalPitch
hPitch = self.conf.gaugeConf.getPitch( self.symSegmentLayer )
vPitch = self.conf.gaugeConf.getPitch( self.padSegment.getLayer() )
@ -749,7 +751,7 @@ class CoreWire ( object ):
else:
yCore -= 2*hPitch*self.offset
if self.side == chip.West:
if self.side == West:
accessDirection = Pin.Direction.WEST
xPadMin = self.bbSegment.getXMin()
xContact = self.corona.coreSymBb.getXMin() - self.offset * 2*vPitch
@ -813,7 +815,7 @@ class CoreWire ( object ):
)
if self.arraySize:
if self.side == chip.West: xContact = min( xContact, vStrapBb.getXMin() )
if self.side == West: xContact = min( xContact, vStrapBb.getXMin() )
else: xContact = max( xContact, vStrapBb.getXMax() )
self.conf.coronaHorizontal( self.chipNet
@ -834,7 +836,7 @@ class CoreWire ( object ):
, self.bbSegment.getHeight()
)
else:
flags = chip.OnVerticalPitch
flags = OnVerticalPitch
hPitch = self.conf.gaugeConf.getPitch( self.padSegment.getLayer() )
vPitch = self.conf.gaugeConf.getPitch( self.symSegmentLayer )
@ -847,7 +849,7 @@ class CoreWire ( object ):
else:
xCore -= 2*vPitch*self.offset
if self.side == chip.South:
if self.side == South:
accessDirection = Pin.Direction.SOUTH
yPadMin = self.bbSegment.getYMin()
yPadMax = self.corona.coreSymBb.getYMin() - self.offset * 2*hPitch
@ -911,7 +913,7 @@ class CoreWire ( object ):
)
if self.arraySize:
if self.side == chip.South: yContact = min( yContact, hStrapBb.getYMin() )
if self.side == South: yContact = min( yContact, hStrapBb.getYMin() )
else: yContact = max( yContact, hStrapBb.getYMax() )
trace( 550, '\txCore: %sl %s\n' % (DbU.toLambda(xCore), DbU.getValueString(xCore)) )
@ -932,10 +934,10 @@ class CoreWire ( object ):
, DbU.fromLambda( 1.0 )
)
if self.side & chip.North: self.corona.northSide.pins.append( pin )
if self.side & chip.South: self.corona.southSide.pins.append( pin )
if self.side & chip.East : self.corona.eastSide .pins.append( pin )
if self.side & chip.West : self.corona.westSide .pins.append( pin )
if self.side & North: self.corona.northSide.pins.append( pin )
if self.side & South: self.corona.southSide.pins.append( pin )
if self.side & East : self.corona.eastSide .pins.append( pin )
if self.side & West : self.corona.westSide .pins.append( pin )
trace( 550, '-' )
return
@ -953,14 +955,14 @@ class Corona ( object ):
self.conf = conf
self.validated = False
self.northSide = Side( self, chip.North )
self.southSide = Side( self, chip.South )
self.eastSide = Side( self, chip.East )
self.westSide = Side( self, chip.West )
self.corners = { chip.SouthWest : Corner( self, chip.SouthWest )
, chip.SouthEast : Corner( self, chip.SouthEast )
, chip.NorthWest : Corner( self, chip.NorthWest )
, chip.NorthEast : Corner( self, chip.NorthEast )
self.northSide = Side( self, North )
self.southSide = Side( self, South )
self.eastSide = Side( self, East )
self.westSide = Side( self, West )
self.corners = { SouthWest : Corner( self, SouthWest )
, SouthEast : Corner( self, SouthEast )
, NorthWest : Corner( self, NorthWest )
, NorthEast : Corner( self, NorthEast )
}
self.padLib = None
self.padOrient = Transformation.Orientation.ID
@ -1131,7 +1133,7 @@ class Corona ( object ):
gapWidth = 0
segments = None
inPreferredDir = False
if side.type == chip.North or side.type == chip.South:
if side.type == North or side.type == South:
if len(vsegments):
inPreferredDir = True
segments = vsegments[ min(vsegments.keys()) ]
@ -1148,7 +1150,7 @@ class Corona ( object ):
if segments:
for segment, bb in segments:
if not inPreferredDir:
if side.type == chip.North or side.type == chip.South:
if side.type == North or side.type == South:
trace( 550, '\tNorth/South "%s" but RDir H, gapWidth: %s\n'
% (chipIntNet.getName(),DbU.getValueString(bb.getWidth()) ) )
side.updateGap( bb.getWidth() )
@ -1213,10 +1215,10 @@ class Corona ( object ):
self.conf.setupCorona( self.westSide.gap, self.southSide.gap, self.eastSide.gap, self.northSide.gap )
self.coreSymBb = self.conf.getInstanceAb( self.conf.icorona )
self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap /2, chip.Superior )
, self.conf.toSymbolic( self.southSide.gap/2, chip.Superior )
, self.conf.toSymbolic( self.eastSide.gap /2, chip.Inferior )
, self.conf.toSymbolic( self.northSide.gap/2, chip.Inferior ) )
self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap /2, Superior )
, self.conf.toSymbolic( self.southSide.gap/2, Superior )
, self.conf.toSymbolic( self.eastSide.gap /2, Inferior )
, self.conf.toSymbolic( self.northSide.gap/2, Inferior ) )
self.southSide.drawCoreWires()
self.northSide.drawCoreWires()

View File

@ -14,6 +14,9 @@
# +-----------------------------------------------------------------+
from helpers.io import WarningMessage
# Common constants used through all <chip> modules.
# For Corona's sides.
@ -34,3 +37,16 @@ Inferior = 0x0020
Inwards = 0x0040
OnHorizontalPitch = 0x0080
OnVerticalPitch = 0x0100
def importConstants ( symbols ):
if not isinstance(symbols,dict):
print WarningMessage( 'plugins.chip.__init__.importConstants(), argument is not a symbol table.' )
return
for symbol in globals().items():
if isinstance(symbol[1],int) or isinstance(symbol[1],long):
if not symbols.has_key(symbol[0]):
symbols[ symbol[0] ] = symbol[1]
return

View File

@ -22,7 +22,7 @@ from CRL import Catalog
from CRL import AllianceFramework
from helpers import netDirectionToStr
from helpers.io import ErrorMessage
import chip.Chip
import chip
# -------------------------------------------------------------------

View File

@ -14,6 +14,7 @@
# | Python : "./plugins/core2chip/cmos.py" |
# +-----------------------------------------------------------------+
import sys
import re
from Hurricane import DbU
from Hurricane import DataBase
@ -26,8 +27,8 @@ import Viewer
from CRL import Catalog
from CRL import AllianceFramework
from helpers.io import ErrorMessage
from core2chip.CoreToChip import IoPad
from core2chip.CoreToChip import CoreToChip
from plugins.core2chip.CoreToChip import IoPad
from plugins.core2chip.CoreToChip import CoreToChip
class cmos ( CoreToChip ):

View File

@ -27,8 +27,8 @@ import Viewer
from CRL import Catalog
from CRL import AllianceFramework
from helpers.io import ErrorMessage
from core2chip.CoreToChip import IoPad
from core2chip.CoreToChip import CoreToChip
from plugins.core2chip.CoreToChip import IoPad
from plugins.core2chip.CoreToChip import CoreToChip
class phlib80 ( CoreToChip ):

View File

@ -171,10 +171,10 @@ namespace Analog {
// Eric passed by here
//cerr << "Python driven Layout successfully drawn." << endl;
finalize( ShowTimeTag|StatusOk );
_device->setAbutmentBox( getDeviceBox() );
finalize( ShowTimeTag|StatusOk );
//string message = _device->checkLayoutOnPhysicalGrid();
//if (not message.empty())
// popError( message.c_str() );

View File

@ -108,7 +108,8 @@ extern "C" {
, PyInt_AsPlacementStatus(arg4)
);
} else {
PyErr_SetString( ConstructorError, "Instance.create(): Bad type of parameter(s)." );
string message = "Instance.create(): Bad type of parameter(s), \"" + __cs.getObjectIds() + "\".";
PyErr_SetString( ConstructorError, message.c_str() );
return NULL;
}
HCATCH

View File

@ -227,7 +227,8 @@ namespace Isobar {
if (Py_IsInitialized()) {
// Python is already running. Launch a sub-interpreter.
_globalState = PyThreadState_Get();
_subInterpreter = Py_NewInterpreter();
//_subInterpreter = Py_NewInterpreter();
_subInterpreter = _globalState;
} else
Py_Initialize();
@ -257,14 +258,18 @@ namespace Isobar {
if (not (_flags & Initialized)) return;
_flags &= ~Initialized;
if (_subInterpreter != NULL) {
//if (_subInterpreter == _globalState) return;
if ( (_subInterpreter != NULL) and (_subInterpreter != _globalState) ) {
Py_EndInterpreter(_subInterpreter);
PyThreadState_Swap(_globalState);
_subInterpreter = NULL;
} else {
if (_subInterpreter != _globalState) {
if ( _userModule != NULL ) { Py_DECREF ( _userModule ); }
if ( _hurricaneModule != NULL ) { Py_DECREF ( _hurricaneModule ); }
if ( _sysModule != NULL ) { Py_DECREF ( _sysModule ); }
}
if ( _pyResult != NULL ) { Py_DECREF ( _pyResult ); }
if ( _pyArgs != NULL ) { Py_DECREF ( _pyArgs ); }
if ( _pyFunction != NULL ) { Py_DECREF ( _pyFunction ); }

View File

@ -326,8 +326,11 @@ class AnalogDesign ( object ):
self.generator.setDevice ( device )
self.generator.drawLayout()
instance = Instance.create( self.cell, dspec[1], device, Transformation() )
instance.setPlacementStatus( Instance.PlacementStatus.UNPLACED )
instance = Instance.create( self.cell
, dspec[1]
, device
, Transformation()
, Instance.PlacementStatus.UNPLACED )
self.__dict__[ dspec[1] ] = instance
return

View File

@ -21,6 +21,7 @@ try:
import helpers
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
import Viewer
except ImportError, e:
serror = str(e)
@ -41,6 +42,9 @@ except Exception, e:
sys.exit(2)
#helpers.staticInitialization( quiet=True )
def unicornConfigure ( **kw ):
editor = None
if kw.has_key('editor'):
@ -49,46 +53,29 @@ def unicornConfigure ( **kw ):
print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' )
return
cumulusDir = None
for path in sys.path:
if path.endswith('/cumulus'):
cumulusDir = path
if not cumulusDir:
print ErrorMessage( 3, 'unicornConfigure.py: Cannot find <cumulus> in PYTHONPATH.' )
return
pluginsDir = os.path.join( cumulusDir, 'plugins' )
if not os.path.isdir(pluginsDir):
print ErrorMessage( 3, 'unicornConfigure.py: Cannot find <cumulus/plugins> directory:' \
, '<%s>' % pluginsDir )
return
sys.path.append( pluginsDir )
if editor.hasMenu( 'plugins' ):
print WarningMessage( 'The <plugins> menu has already been created.' )
return
#editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu )
moduleNames = []
for pluginFile in os.listdir( pluginsDir ):
if pluginFile == "__init__.py": continue
if not pluginFile.endswith('.py'): continue
moduleNames.append( os.path.basename(pluginFile)[:-3] )
moduleNames.sort()
for moduleName in moduleNames:
for moduleName in sys.modules:
if moduleName.startswith('plugins.'):
try:
module = __import__( moduleName, globals(), locals(), moduleName )
module = sys.modules[ moduleName ]
if not module:
#print WarningMessage( 'Plugin "%s" not found in Python sys/modules[].' \
# % moduleName )
continue
if not module.__dict__.has_key('unicornHook'):
print WarningMessage( 'Plugin <%s> do not provides the unicornHook() method, skipped.' \
elements = module.__file__.split( os.sep )
if elements[-2] == 'plugins':
print WarningMessage( 'Plugin "%s" do not provides the unicornHook() method, skipped.' \
% moduleName )
continue
module.__dict__['unicornHook']( **kw )
except ErrorMessage, e:
print e
helpers.showStackTrace( e.trace )