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: # Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number) # (Symbolic_Name, CIF_Name, GDSII_Number)
gdsLayersTable = \ gdsLayersTable = \

View File

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

View File

@ -7,7 +7,6 @@
set ( pyPlugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py set ( pyPlugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.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/CoreToChip_phlib80.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py
@ -23,7 +22,6 @@
set ( pyPluginC2C ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/__init__.py set ( pyPluginC2C ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/cmos.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 ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/phlib80.py
) )
set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.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 ErrorMessage
from helpers.io import WarningMessage from helpers.io import WarningMessage
import plugins import plugins
import chip.Chip import chip
except ImportError, e: except ImportError, e:
serror = str(e) serror = str(e)
if serror.startswith('No module named'): if serror.startswith('No module named'):

View File

@ -14,7 +14,10 @@
# +-----------------------------------------------------------------+ # +-----------------------------------------------------------------+
import os
import sys
import Cfg import Cfg
import helpers
from helpers.io import ErrorMessage from helpers.io import ErrorMessage
from helpers.io import WarningMessage from helpers.io import WarningMessage
from Hurricane import Contact from Hurricane import Contact
@ -29,6 +32,7 @@ from CRL import RoutingLayerGauge
NoFlags = 0000 NoFlags = 0000
ShowWarnings = 0001 ShowWarnings = 0001
WarningsAreErrors = 0002 WarningsAreErrors = 0002
loaded = False
@ -185,3 +189,78 @@ class StackedVia ( object ):
) ) ) )
#print ' Sub-via: ', self._vias[-1] #print ' Sub-via: ', self._vias[-1]
return 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 from helpers.io import WarningMessage
import plugins import plugins
from plugins import StackedVia from plugins import StackedVia
import chip.BlockPower import chip
chip.importConstants( globals() )
class IntervalSet ( object ): class IntervalSet ( object ):
@ -372,8 +375,8 @@ class SouthSide ( HorizontalSide ):
return self.innerBb.getYMin() - self.hRailWidth/2 - self.hRailSpace \ return self.innerBb.getYMin() - self.hRailWidth/2 - self.hRailSpace \
- i*(self.hRailWidth + self.hRailSpace) - i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthWest][i] def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[chip.SouthEast][i] def corner1 ( self, i ): return self.corners[SouthEast][i]
class NorthSide ( HorizontalSide ): class NorthSide ( HorizontalSide ):
@ -386,8 +389,8 @@ class NorthSide ( HorizontalSide ):
return self.innerBb.getYMax() + self.hRailWidth/2 + self.hRailSpace \ return self.innerBb.getYMax() + self.hRailWidth/2 + self.hRailSpace \
+ i*(self.hRailWidth + self.hRailSpace) + i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[chip.NorthWest][i] def corner0 ( self, i ): return self.corners[NorthWest][i]
def corner1 ( self, i ): return self.corners[chip.NorthEast][i] def corner1 ( self, i ): return self.corners[NorthEast][i]
class VerticalSide ( Side ): class VerticalSide ( Side ):
@ -449,8 +452,8 @@ class WestSide ( VerticalSide ):
return self.innerBb.getXMin() - self.vRailWidth/2 - self.vRailSpace \ return self.innerBb.getXMin() - self.vRailWidth/2 - self.vRailSpace \
- i*(self.vRailWidth + self.vRailSpace) - i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthWest][i] def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[chip.NorthWest ][i] def corner1 ( self, i ): return self.corners[NorthWest ][i]
def addBlockages ( self ): def addBlockages ( self ):
sideXMin = self.getOuterRail(0).axis - self.vRailWidth sideXMin = self.getOuterRail(0).axis - self.vRailWidth
@ -469,8 +472,8 @@ class EastSide ( VerticalSide ):
return self.innerBb.getXMax() + self.vRailWidth/2 + self.vRailSpace \ return self.innerBb.getXMax() + self.vRailWidth/2 + self.vRailSpace \
+ i*(self.vRailWidth + self.vRailSpace) + i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[chip.SouthEast][i] def corner0 ( self, i ): return self.corners[SouthEast][i]
def corner1 ( self, i ): return self.corners[chip.NorthEast ][i] def corner1 ( self, i ): return self.corners[NorthEast ][i]
def addBlockages ( self ): def addBlockages ( self ):
sideXMin = self.getInnerRail(0).axis - self.vRailWidth sideXMin = self.getInnerRail(0).axis - self.vRailWidth
@ -532,10 +535,10 @@ class Corona ( object ):
def connectBlock ( self ): def connectBlock ( self ):
for plane in self.block.planes.values(): for plane in self.block.planes.values():
for side in plane.sides.values(): for side in plane.sides.values():
self.southSide.connect( side[chip.South] ) self.southSide.connect( side[South] )
self.northSide.connect( side[chip.North] ) self.northSide.connect( side[North] )
self.westSide .connect( side[chip.West ] ) self.westSide .connect( side[West ] )
self.eastSide .connect( side[chip.East ] ) self.eastSide .connect( side[East ] )
return return
def connectPads ( self, padsCorona ): def connectPads ( self, padsCorona ):
@ -546,10 +549,10 @@ class Corona ( object ):
return return
def doLayout ( self ): def doLayout ( self ):
self.corners = { chip.SouthWest : [] self.corners = { SouthWest : []
, chip.SouthEast : [] , SouthEast : []
, chip.NorthWest : [] , NorthWest : []
, chip.NorthEast : [] , NorthEast : []
} }
contactDepth = self.horizontalDepth contactDepth = self.horizontalDepth
@ -575,28 +578,28 @@ class Corona ( object ):
trBox.merge( xTR, yTR ) trBox.merge( xTR, yTR )
self.routingGauge.getContactLayer(contactDepth) self.routingGauge.getContactLayer(contactDepth)
self.corners[chip.SouthWest].append( self.corners[SouthWest].append(
Contact.create( net Contact.create( net
, self.routingGauge.getContactLayer(contactDepth) , self.routingGauge.getContactLayer(contactDepth)
, xBL, yBL , xBL, yBL
, self.hRailWidth , self.hRailWidth
, self.vRailWidth , self.vRailWidth
) ) ) )
self.corners[chip.NorthWest].append( self.corners[NorthWest].append(
Contact.create( net Contact.create( net
, self.routingGauge.getContactLayer(contactDepth) , self.routingGauge.getContactLayer(contactDepth)
, xBL, yTR , xBL, yTR
, self.hRailWidth , self.hRailWidth
, self.vRailWidth , self.vRailWidth
) ) ) )
self.corners[chip.SouthEast].append( self.corners[SouthEast].append(
Contact.create( net Contact.create( net
, self.routingGauge.getContactLayer(contactDepth) , self.routingGauge.getContactLayer(contactDepth)
, xTR, yBL , xTR, yBL
, self.hRailWidth , self.hRailWidth
, self.vRailWidth , self.vRailWidth
) ) ) )
self.corners[chip.NorthEast].append( self.corners[NorthEast].append(
Contact.create( net Contact.create( net
, self.routingGauge.getContactLayer(contactDepth) , self.routingGauge.getContactLayer(contactDepth)
, xTR, yTR , xTR, yTR

View File

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

View File

@ -53,10 +53,10 @@ try:
import Unicorn import Unicorn
import plugins import plugins
import clocktree.ClockTree import clocktree.ClockTree
import chip.Configuration import chip
import chip.PadsCorona
import chip.BlockPower import chip.BlockPower
import chip.BlockCorona import chip.BlockCorona
import chip.PadsCorona
except ImportError, e: except ImportError, e:
serror = str(e) serror = str(e)
if serror.startswith('No module named'): 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,long): return ChipConf._toSymbolic( v, rounding )
if isinstance(v,Box): if isinstance(v,Box):
if rounding & chip.Inwards: if rounding & chip.Inwards:
roundings = [ chip.Superior, chip.Superior, chip.Inferior, chip.Inferior ] roundings = [ chip.Superior
, chip.Superior
, chip.Inferior
, chip.Inferior ]
else: 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] ) xMin = ChipConf._toSymbolic( v.getXMin(), roundings[0] )
yMin = ChipConf._toSymbolic( v.getYMin(), roundings[1] ) yMin = ChipConf._toSymbolic( v.getYMin(), roundings[1] )
xMax = ChipConf._toSymbolic( v.getXMax(), roundings[2] ) xMax = ChipConf._toSymbolic( v.getXMax(), roundings[2] )

View File

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

View File

@ -14,6 +14,9 @@
# +-----------------------------------------------------------------+ # +-----------------------------------------------------------------+
from helpers.io import WarningMessage
# Common constants used through all <chip> modules. # Common constants used through all <chip> modules.
# For Corona's sides. # For Corona's sides.
@ -34,3 +37,16 @@ Inferior = 0x0020
Inwards = 0x0040 Inwards = 0x0040
OnHorizontalPitch = 0x0080 OnHorizontalPitch = 0x0080
OnVerticalPitch = 0x0100 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 CRL import AllianceFramework
from helpers import netDirectionToStr from helpers import netDirectionToStr
from helpers.io import ErrorMessage from helpers.io import ErrorMessage
import chip.Chip import chip
# ------------------------------------------------------------------- # -------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@ -108,7 +108,8 @@ extern "C" {
, PyInt_AsPlacementStatus(arg4) , PyInt_AsPlacementStatus(arg4)
); );
} else { } 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; return NULL;
} }
HCATCH HCATCH

View File

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

View File

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

View File

@ -21,6 +21,7 @@ try:
import helpers import helpers
from helpers.io import ErrorMessage from helpers.io import ErrorMessage
from helpers.io import WarningMessage from helpers.io import WarningMessage
import plugins
import Viewer import Viewer
except ImportError, e: except ImportError, e:
serror = str(e) serror = str(e)
@ -41,6 +42,9 @@ except Exception, e:
sys.exit(2) sys.exit(2)
#helpers.staticInitialization( quiet=True )
def unicornConfigure ( **kw ): def unicornConfigure ( **kw ):
editor = None editor = None
if kw.has_key('editor'): 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.' ) print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' )
return 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' ): if editor.hasMenu( 'plugins' ):
print WarningMessage( 'The <plugins> menu has already been created.' ) print WarningMessage( 'The <plugins> menu has already been created.' )
return return
#editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu ) #editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu )
moduleNames = [] for moduleName in sys.modules:
for pluginFile in os.listdir( pluginsDir ): if moduleName.startswith('plugins.'):
if pluginFile == "__init__.py": continue
if not pluginFile.endswith('.py'): continue
moduleNames.append( os.path.basename(pluginFile)[:-3] )
moduleNames.sort()
for moduleName in moduleNames:
try: 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'): 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 ) % moduleName )
continue continue
module.__dict__['unicornHook']( **kw ) module.__dict__['unicornHook']( **kw )
except ErrorMessage, e: except ErrorMessage, e:
print e print e
helpers.showStackTrace( e.trace ) helpers.showStackTrace( e.trace )