Complete replacement of the Chip placement Python scripts.

Finally get rid of the demonic code from Wu Yifei...
* New: In Isobar, added encapsulation of Interval (don't know how have
    forgotten it for so long).
* Change: In Isobar, In PyLayer, new PyLink_LayerDerived() function to
    create/link the C++ object to the correct derived class and not the
    base one (PyLayer) which then prevent to use the specialized methods.
    Must replace PyLink_Layer() througout all the code.
* Change: In Isobar, in PyPoint the "setX()" & "setY()" methods where
    still capitalized.
* Change: In Isobar, in PyQuery, complete the exportation of the C++
    interface. remove the code belonging to a more "boost" way of
    building the Python interface (will do that in a far future).
* New: In CRL Core, In PyAllianceFramework, export isPad() method.
* Change: In Unicorn, in unicornInit.py, protect the loading of each
    single plugin by a "try" / "except" clause to the failing of one
    plugins do not stop the loading of the next one.
      Pass the same dictionnary argument to unicornHook() as for
    ScripMain(), this is more uniform this way.
* New: In Cumulus, complete replacement of the chip placement scripts
    from Wu Yifei (at last!). The clock-tree integration is still to
    be done.
________________________________________________________________________
This commit is contained in:
Jean-Paul Chaput 2014-07-21 13:18:34 +02:00
parent d0d045b55b
commit 25e82fc701
33 changed files with 2562 additions and 514 deletions

View File

@ -0,0 +1,16 @@
# -*- Mode:Python; explicit-buffer-name: "plugins.conf<cmos>" -*-
import helpers
# Contains the layout (shared by all technologies).
#execfile( helpers.sysConfDir+'/common/plugins.conf' )
# Parameters for chip plugin.
parametersTable = \
( ("chip.block.rails.count" ,TypeInt ,4 )
, ("chip.block.rails.hWidth" ,TypeInt ,12 )
, ("chip.block.rails.vWidth" ,TypeInt ,12 )
, ("chip.block.rails.hSpacing" ,TypeInt ,6 )
, ("chip.block.rails.vSpacing" ,TypeInt ,6 )
)

View File

@ -111,6 +111,7 @@ def coriolisConfigure():
, (helpers.sysConfDir+'/'+symbolicTechno+'/mauka.conf' , SystemFile|ConfigurationHelper)
, (helpers.sysConfDir+'/'+symbolicTechno+'/kite.conf' , SystemFile|ConfigurationHelper)
, (helpers.sysConfDir+'/'+symbolicTechno+'/stratus1.conf', SystemFile|ConfigurationHelper)
, (helpers.sysConfDir+'/'+symbolicTechno+'/plugins.conf' , SystemFile|ConfigurationHelper)
]
if os.getenv('HOME'):
confFiles += [ (os.getenv('HOME')+'/.coriolis2.conf', 0) ]

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2010-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -260,6 +259,27 @@ extern "C" {
}
static PyObject* PyAllianceFramework_isPad ( PyAllianceFramework* self, PyObject* args )
{
trace << "PyAllianceFramework_isPad ()" << endl;
char* name = NULL;
HTRY
METHOD_HEAD("AllianceFramework.isPad()")
if ( not PyArg_ParseTuple(args,"s",&name) ) {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Cell AllianceFramework.isPad().");
return NULL;
}
if (af->isPad(name)) Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
extern PyObject* PyAllianceFramework_addRoutingGauge ( PyAllianceFramework* self, PyObject* args )
{
trace << "PyAllianceFramework_addRoutingGauge ()" << endl;
@ -366,6 +386,8 @@ extern "C" {
, "Saves an Alliance Cell." }
, { "createCell" , (PyCFunction)PyAllianceFramework_createCell , METH_VARARGS
, "Create a Cell in the Alliance framework." }
, { "isPad" , (PyCFunction)PyAllianceFramework_isPad , METH_VARARGS
, "Tells if a cell name is a Pad." }
, { "addCellGauge" , (PyCFunction)PyAllianceFramework_addCellGauge , METH_VARARGS
, "Add a new cell gauge." }
, { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS

View File

@ -44,7 +44,7 @@ namespace CRL {
using Isobar::Converter;
using Isobar::PyLayer;
using Isobar::PyTypeLayer;
using Isobar::PyLayer_Link;
using Isobar::PyLayer_LinkDerived;
using Isobar::PyTechnology;
using Isobar::PyTypeTechnology;
using Isobar::PyTechnology_Link;
@ -238,7 +238,7 @@ extern "C" {
}
HCATCH
return PyLayer_Link(layer);
return PyLayer_LinkDerived(layer);
}
@ -265,7 +265,7 @@ extern "C" {
}
HCATCH
return PyLayer_Link(layer);
return PyLayer_LinkDerived(layer);
}

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
// Copyright (c) UPMC 2012-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -42,7 +41,7 @@ namespace CRL {
using Isobar::__cs;
using Isobar::PyLayer;
using Isobar::PyTypeLayer;
using Isobar::PyLayer_Link;
using Isobar::PyLayer_LinkDerived;
extern "C" {
@ -146,7 +145,7 @@ extern "C" {
layer = const_cast<Layer*>(rlg->getLayer());
HCATCH
return PyLayer_Link(layer);
return PyLayer_LinkDerived(layer);
}
@ -161,7 +160,7 @@ extern "C" {
layer = const_cast<Layer*>(rlg->getBlockageLayer());
HCATCH
return PyLayer_Link(layer);
return PyLayer_LinkDerived(layer);
}

View File

@ -1,12 +1,19 @@
# -*- explicit-buffer-name: "CMakeLists.txt<cumulus/src>" -*-
set ( pysources ${CMAKE_CURRENT_SOURCE_DIR}/placeandroute.py
${CMAKE_CURRENT_SOURCE_DIR}/ref.py
set ( pySources ${CMAKE_CURRENT_SOURCE_DIR}/placeandroute.py
${CMAKE_CURRENT_SOURCE_DIR}/ref.py
)
set ( pyplugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTree.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/Chip.py
set ( pyPlugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTree.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlugin.py
)
set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/BlockPower.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/BlockCorona.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/PadsCorona.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/Configuration.py
)
install ( FILES ${pysources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus )
install ( FILES ${pyplugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins )
install ( FILES ${pySources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus )
install ( FILES ${pyPlugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins )
install ( FILES ${pyPluginChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/chip )

View File

@ -0,0 +1,171 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/ChipPlugin.py" |
# +-----------------------------------------------------------------+
try:
import sys
import traceback
import os.path
import optparse
import math
import Cfg
import Hurricane
from Hurricane import DataBase
from Hurricane import DbU
from Hurricane import Point
from Hurricane import Transformation
from Hurricane import Box
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
from Hurricane import Breakpoint
from Hurricane import Net
from Hurricane import RoutingPad
from Hurricane import Contact
from Hurricane import Horizontal
from Hurricane import Vertical
from Hurricane import Instance
from Hurricane import HyperNet
from Hurricane import Query
import Viewer
import CRL
from CRL import RoutingLayerGauge
from helpers import ErrorMessage
from helpers import WarningMessage
import Nimbus
import Metis
import Mauka
import Katabatic
import Kite
import Unicorn
import plugins
import chip.Configuration
import chip.BlockPower
import chip.BlockCorona
import chip.PadsCorona
except ImportError, e:
module = str(e).split()[-1]
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
print ' Please check the integrity of the <coriolis> package.'
sys.exit(1)
except Exception, e:
print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python'
print ' modules. Something may be wrong at Python/C API level.\n'
print ' %s' % e
sys.exit(2)
# --------------------------------------------------------------------
# Plugin working part.
class PlaceCore ( chip.Configuration.Wrapper ):
def __init__ ( self, confWrapper ):
chip.Configuration.Wrapper.__init__( self, confWrapper.conf )
self.validated = False
return
def validate ( self ):
self.validated = True
if len(self.cores) < 1: self.validated = False
coreAb = self.cores[0].getMasterCell().getAbutmentBox()
if (not coreAb.isEmpty()):
if coreAb.getWidth () < self.coreSize.getWidth() \
and coreAb.getHeight() < self.coreSize.getHeight():
self.coreSize = coreAb
else:
print ErrorMessage( 1, [ 'Core %s already have an abutment box, bigger than the requested one:'
% self.cores[0].getName()
, " Cell abutment box: %s" % str(coreAb)
, " Maximum abutment box: %s" % str(self.coreSize) ] )
self.validated = False
return self.validated
def doFloorplan ( self ):
if not self.validated: return
UpdateSession.open()
self.cores[0].getMasterCell().setAbutmentBox( self.coreSize )
x = (self.chipSize.getWidth () - self.coreSize.getWidth ()) / 2
y = (self.chipSize.getHeight() - self.coreSize.getHeight()) / 2
self.cores[0].setTransformation ( Transformation(x,y,Transformation.Orientation.ID) )
self.cores[0].setPlacementStatus( Instance.PlacementStatus.FIXED )
UpdateSession.close()
return
def doPlacement ( self ):
if not self.validated: return
checkUnplaced = plugins.CheckUnplaced( self.cores[0].getMasterCell(), plugins.NoFlags )
if not checkUnplaced.check(): return
mauka = Mauka.MaukaEngine.create( self.cores[0].getMasterCell() )
mauka.run()
mauka.destroy()
return
# --------------------------------------------------------------------
# Plugin hook functions, unicornHook:menus, ScritMain:call
def unicornHook ( **kw ):
plugins.kwUnicornHook( 'plugins.chip'
, 'Chip Placement'
, 'Place a Complete Chip (pads && core)'
, sys.modules[__name__].__file__
, **kw
)
return
def ScriptMain ( **kw ):
try:
cell, editor = plugins.kwParseMain( **kw )
conf = chip.Configuration.loadConfiguration( cell )
if not conf.isValid(): return
padsCorona = chip.PadsCorona.Corona( conf )
if not padsCorona.validate(): return
padsCorona.doLayout()
placeCore = PlaceCore( conf )
placeCore.validate()
placeCore.doFloorplan()
placeCore.doPlacement()
corePower = chip.BlockPower.Block( Path(conf.cores[0]), conf.vddi, conf.vssi )
corePower.queryPower()
corePower.doLayout()
coreCorona = chip.BlockCorona.Corona( corePower )
coreCorona.connectPads( padsCorona )
coreCorona.connectBlock()
coreCorona.doLayout()
editor.fit()
except ErrorMessage, e:
print e; errorCode = e.code
editor.fit()
except Exception, e:
print '\n\n', e; errorCode = 1
traceback.print_tb(sys.exc_info()[2])
return 0

View File

@ -1,4 +1,17 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/ClockTree.cpp" |
# +-----------------------------------------------------------------+
try:
import sys
@ -32,6 +45,7 @@ try:
import Katabatic
import Kite
import Unicorn
import plugins
except ImportError, e:
module = str(e).split()[-1]
@ -444,19 +458,20 @@ class HTreeNode ( object ):
return
def route ( self ):
sourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess )
blContact = self.topTree._rpAccessByPlugName( self.blBuffer , 'i', self.ckNet )
brContact = self.topTree._rpAccessByPlugName( self.brBuffer , 'i', self.ckNet )
tlContact = self.topTree._rpAccessByPlugName( self.tlBuffer , 'i', self.ckNet )
trContact = self.topTree._rpAccessByPlugName( self.trBuffer , 'i', self.ckNet )
leftContact = self.topTree._createContact( self.ckNet, blContact.getX(), sourceContact.getY() )
rightContact = self.topTree._createContact( self.ckNet, brContact.getX(), sourceContact.getY() )
self.topTree._createHorizontal( leftContact , sourceContact, sourceContact.getY() )
self.topTree._createHorizontal( sourceContact, rightContact , sourceContact.getY() )
self.topTree._createVertical ( leftContact , blContact , leftContact.getX() )
self.topTree._createVertical ( tlContact , leftContact , leftContact.getX() )
self.topTree._createVertical ( rightContact , brContact , rightContact.getX() )
self.topTree._createVertical ( trContact , rightContact , rightContact.getX() )
leftSourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess )
rightSourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess )
blContact = self.topTree._rpAccessByPlugName( self.blBuffer , 'i', self.ckNet )
brContact = self.topTree._rpAccessByPlugName( self.brBuffer , 'i', self.ckNet )
tlContact = self.topTree._rpAccessByPlugName( self.tlBuffer , 'i', self.ckNet )
trContact = self.topTree._rpAccessByPlugName( self.trBuffer , 'i', self.ckNet )
leftContact = self.topTree._createContact( self.ckNet, blContact.getX(), leftSourceContact.getY() )
rightContact = self.topTree._createContact( self.ckNet, brContact.getX(), rightSourceContact.getY() )
self.topTree._createHorizontal( leftContact , leftSourceContact, leftSourceContact.getY() )
self.topTree._createHorizontal( rightSourceContact, rightContact , rightSourceContact.getY() )
self.topTree._createVertical ( leftContact , blContact , leftContact.getX() )
self.topTree._createVertical ( tlContact , leftContact , leftContact.getX() )
self.topTree._createVertical ( rightContact , brContact , rightContact.getX() )
self.topTree._createVertical ( trContact , rightContact , rightContact.getX() )
for child in self.childs: child.route()
return
@ -497,22 +512,17 @@ def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ):
return abutmentBox
def unicornHook ( editor ):
#print ' o Hooking up ClockTree script.'
moduleFile = sys.modules[__name__].__file__
if moduleFile.endswith('.pyc') or moduleFile.endswith('.pyo'):
moduleFile = moduleFile[:-1]
editor.addToMenu( 'plugins.clockTree'
, 'ClockTree'
, 'Build a buffered H-Tree for the clock'
, moduleFile
)
#print ' <%s>' % moduleFile
def unicornHook ( **kw ):
plugins.kwUnicornHook( 'plugins.clockTree'
, 'ClockTree'
, 'Build a buffered H-Tree for the clock'
, sys.modules[__name__].__file__
, **kw
)
return
def ScriptMain ( cell=None ):
def ScriptMain ( **kw ):
try:
errorCode = 0
@ -522,10 +532,14 @@ def ScriptMain ( cell=None ):
print ' - <%s>' % fileName
os.unlink(fileName)
cell = None
if kw.has_key('cell') and kw['cell']:
cell = kw['cell']
editor = None
if globals().has_key('__editor'):
if kw.has_key('editor') and kw['editor']:
editor = kw['editor']
print ' o Editor detected, running in graphic mode.'
editor = __editor
if cell == None: cell = editor.getCell()
if cell == None:

View File

@ -0,0 +1,155 @@
# -*- explicit-buffer-name: "__init__.py<cumulus/plugins>" -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/__init__.py" |
# +-----------------------------------------------------------------+
import Cfg
from helpers import ErrorMessage
from helpers import WarningMessage
from Hurricane import Contact
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import Instance
import CRL
from CRL import RoutingLayerGauge
NoFlags = 0000
ShowWarnings = 0001
WarningsAreErrors = 0002
def kwParseMain ( **kw ):
cell = None
if kw.has_key('cell') and kw['cell']:
cell = kw['cell']
editor = None
if kw.has_key('editor') and kw['editor']:
editor = kw['editor']
if cell == None: cell = editor.getCell()
if cell == None:
raise ErrorMessage( 3, 'Chip: No cell loaded yet.' )
return cell, editor
def kwUnicornHook ( menuPath, menuName, menuTip, moduleFile, **kw ):
editor = kw['editor']
if moduleFile.endswith('.pyc') or moduleFile.endswith('.pyo'):
moduleFile = moduleFile[:-1]
editor.addToMenu( menuPath, menuName, menuTip, moduleFile )
return
def getParameter ( pluginName, key ):
if not Cfg.hasParameter(key):
raise ErrorMessage( 1, 'Mandatory parameter <%s> for for plugin <%s> is missing in configuration.'
% (key,pluginName) )
return Cfg.Configuration.get().getParameter(key)
class CheckUnplaced ( object ):
def __init__ ( self, cell, flags=NoFlags ):
self.cell = cell
self.flags = flags
self.unplaceds = []
return
def _rcheckUnplaced ( self, path, cell ):
for instance in cell.getInstances():
if instance.getPlacementStatus() == Instance.PlacementStatus.UNPLACED:
self.unplaceds.append( Occurrence(instance,path) )
rpath = Path( path, instance )
self._rcheckUnplaced( rpath, instance.getMasterCell() )
return
def check ( self ):
self._rcheckUnplaced( Path(), self.cell )
if self.unplaceds:
if self.flags & (ShowWarnings | WarningsAreErrors):
message = [ 'Some instances are unplaceds:' ]
for occurrence in self.unplaceds:
message += [ '%s' % (occurrence.getCompactString()) ]
error = ErrorMessage( 3, message )
if self.flags & WarningsAreErrors: raise error
else: print error
return self.unplaceds
class StackedVia ( object ):
def __init__ ( self, net, depth, x, y, width, height ):
self._hasLayout = False
self._net = net
self._bottomDepth = depth
self._topDepth = depth
self._x = x
self._y = y
self._width = width
self._height = height
self._vias = []
return
def mergeDepth ( self, depth ):
if self._hasLayout:
print WarningMessage( 'StackedVia.mergeDepth(): Cannot be called *after* StackVia.doLayout()' )
return
if depth < self._bottomDepth: self._bottomDepth = depth
if depth > self._topDepth: self._topDepth = depth
return
def getVia ( self, metal ):
if not self._hasLayout: return None
for via in self._vias:
if via.getLayer().contains(metal): return via
return None
def doLayout ( self ):
if self._hasLayout: return
self._hasLayout = True
routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
if self._bottomDepth == self._topDepth:
self._vias.append( Contact.create( self._net
, routingGauge.getRoutingLayer(self._bottomDepth)
, self._x , self._y
, self._width, self._height
) )
else:
for depth in range(self._bottomDepth,self._topDepth):
if depth == self._bottomDepth:
self._vias.append( Contact.create( self._net
, routingGauge.getContactLayer(depth)
, self._x , self._y
, self._width, self._height
) )
else:
self._vias.append( Contact.create( self._vias[-1]
, routingGauge.getContactLayer(depth)
, 0 , 0
, self._width, self._height
) )
#print ' Sub-via: ', self._vias[-1]
return

View File

@ -0,0 +1,489 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/chip/BlockCorona.py" |
# +-----------------------------------------------------------------+
import bisect
from operator import methodcaller
import Cfg
from Hurricane import DbU
from Hurricane import Point
from Hurricane import Transformation
from Hurricane import Box
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
from Hurricane import Net
from Hurricane import Contact
from Hurricane import Horizontal
from Hurricane import Vertical
import CRL
from CRL import RoutingLayerGauge
from helpers import ErrorMessage
from helpers import WarningMessage
from plugins import StackedVia
import chip.BlockPower
class Rail ( object ):
def __init__ ( self, side, order, axis ):
self.side = side
self.order = order
self.axis = axis
self.vias = { } # Key:pos Element: [pos,railContact,blockContact]
return
@property
def net ( self ): return self.side.getRailNet(self.order)
class HorizontalRail ( Rail ):
def __init__ ( self, side, order, axis ):
Rail.__init__( self, side, order, axis )
return
def connect ( self, contact ):
contactBb = contact.getBoundingBox()
if contactBb.getXMin() < self.side.innerBb.getXMin() \
or contactBb.getXMax() > self.side.innerBb.getXMax():
raise ErrorMessage( 1, [ '%s is outside rail/corona X range,' % str(contact)
, 'power pad is likely to be to far off west or east.'
, '(corona:%s)' % str(self.side.innerBb) ] )
#print ' HorizontalRail.connect() net:%s contact:%s' % (self.net.getName(),str(contact))
if self.net != contact.getNet(): return False
if self.vias.has_key(contact.getX()): return False
keys = self.vias.keys()
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getX() )
if len(keys) > 0:
if insertIndex < len(keys):
insertPosition = keys[ insertIndex ]
if contactBb.getXMax() >= self.vias[insertPosition][2].getBoundingBox().getXMin():
#print 'Reject contact %s intersect NEXT' % str(contact)
return False
if insertIndex > 0:
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getXMax() >= contactBb.getXMin():
#print 'Reject contact %s intersect PREVIOUS' % str(contact)
return False
self.vias[ contact.getX() ] = [ contact.getX()
, StackedVia( self.net
, self.side.getLayerDepth(self.side.getHLayer())
, contact.getX()
, self.axis
, contact.getWidth()
, self.side.hRailWidth
)
, contact ]
#print ' ADD contact @ [%d %d]' % (DbU.toLambda(contact.getX()), DbU.toLambda(self.axis))
self.vias[ contact.getX() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
return True
def doLayout ( self ):
for via in self.vias.values():
via[1].doLayout()
Horizontal.create( self.side.corner0(self.order)
, self.side.corner1(self.order)
, self.side.getHLayer()
, self.axis
, self.side.hRailWidth
)
return
def doLayout ( self ):
#print 'HorizontalRail[%s] @%d' % (self.order,DbU.toLambda(self.axis))
railVias = [ self.side.corner0(self.order)
, self.side.corner1(self.order) ]
for via in self.vias.values():
via[1].doLayout()
#print ' Connect:', via[2], via[1].getVia( via[2].getLayer() )
Vertical.create( via[1].getVia( via[2].getLayer() )
, via[2]
, via[2].getLayer()
, via[2].getX()
, via[2].getWidth()
)
railVias.append( via[1].getVia( self.side.getVLayer()) )
railVias.sort( key=methodcaller('getY') )
for i in range(1,len(railVias)):
Horizontal.create( railVias[i-1]
, railVias[i]
, self.side.getHLayer()
, self.axis
, self.side.hRailWidth
)
return
class VerticalRail ( Rail ):
def __init__ ( self, side, order, axis ):
Rail.__init__( self, side, order, axis )
return
def doLayout ( self ):
#print 'VerticalRail[%s] @%d' % (self.order,DbU.toLambda(self.axis))
railVias = [ self.side.corner0(self.order)
, self.side.corner1(self.order) ]
for via in self.vias.values():
#print ' Connect: ', via[2]
via[1].doLayout()
Horizontal.create( via[1].getVia( via[2].getLayer() )
, via[2]
, via[2].getLayer()
, via[2].getY()
, via[2].getHeight()
)
railVias.append( via[1].getVia( self.side.getVLayer()) )
railVias.sort( key=methodcaller('getY') )
for i in range(1,len(railVias)):
Vertical.create( railVias[i-1]
, railVias[i]
, self.side.getVLayer()
, self.axis
, self.side.vRailWidth
)
return
def connect ( self, contact ):
contactBb = contact.getBoundingBox()
if contactBb.getYMin() < self.side.innerBb.getYMin() \
or contactBb.getYMax() > self.side.innerBb.getYMax():
raise ErrorMessage( 1, [ '%s is outside rail/corona Y range' % str(contact)
, 'power pad is likely to be to far off north or south.'
, '(corona:%s)' % str(self.side.innerBb) ] )
if self.net != contact.getNet(): return False
if self.vias.has_key(contact.getY()): return False
keys = self.vias.keys()
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getY() )
#print 'keys:', keys
if len(keys) > 0:
if insertIndex < len(keys):
insertPosition = keys[ insertIndex ]
#print 'insertIndex:%d' % insertIndex
#print 'Check NEXT contactBb:%s via:%s' \
# % ( str(contactBb)
# , str(self.vias[insertPosition][2].getBoundingBox()) )
if contactBb.getYMax() >= self.vias[insertPosition][2].getBoundingBox().getYMin():
# print 'Reject %s intersect NEXT' % str(contact)
return False
if insertIndex > 0:
#print 'check PREVIOUS contactBb:%s via:%s' \
# % ( str(contactBb)
# , str(self.vias[keys[insertIndex-1]][2].getBoundingBox()) )
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin():
# print 'Reject %s intersect PREVIOUS' % str(contact)
return False
self.vias[ contact.getY() ] = [ contact.getY()
, StackedVia( self.net
, self.side.getLayerDepth(self.side.getVLayer())
, self.axis
, contact.getY()
, self.side.vRailWidth
, contact.getHeight()
)
, contact ]
#print 'ADD %s' % str(contact)
self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
return True
class Side ( object ):
def __init__ ( self, corona ):
self._corona = corona
return
@property
def railsNb ( self ): return self._corona._railsNb
@property
def innerBb ( self ): return self._corona._innerBb
@property
def hRailWidth ( self ): return self._corona._hRailWidth
@property
def hRailSpace ( self ): return self._corona._hRailSpace
@property
def vRailWidth ( self ): return self._corona._vRailWidth
@property
def vRailSpace ( self ): return self._corona._vRailSpace
@property
def corners ( self ): return self._corona._corners
def getLayerDepth ( self, metal ): return self._corona.getLayerDepth(metal)
def getRail ( self, i ): return self._rails[i]
def getRailNet ( self, i ): return self._corona.getRailNet(i)
def getHLayer ( self ): return self._corona.getHLayer()
def getVLayer ( self ): return self._corona.getVLayer()
def getRailAxis ( self, i ):
raise ErrorMessage( 1, 'Side.getRailAxis(): Must never be called on base class.' )
def getInnerRail ( self, i ):
if i >= len(self._rails):
raise ErrorMessage( 1, 'Side.getInnerRail(): no rail %d (only: %d).' % (i,len(self._rails)) )
return self._rails[i]
def getOuterRail ( self, i ):
if i >= len(self._rails):
raise ErrorMessage( 1, 'Side.getOuterRail(): no rail %d (only: %d).' % (i,len(self._rails)) )
return self._rails[-(i+1)]
def connect ( self, blockSide ):
for terminal in blockSide.terminals:
for rail in self._rails:
rail.connect( terminal[1] )
return
def connectPads ( self, padSide ):
halfRails = len(self._rails)/2
for terminal in padSide._powerContacts:
#print 'Connect pad terminal ', terminal
for i in range(halfRails):
#print ' Connect to [-%i] @%d' % (i, DbU.toLambda(self.getOuterRail(i).axis))
self.getOuterRail(i).connect( terminal )
return
def doLayout ( self ):
for rail in self._rails: rail.doLayout()
return
class HorizontalSide ( Side ):
def __init__ ( self, corona ):
#print 'HorizontalSide.__init__()'
Side.__init__( self, corona )
self._rails = []
for i in range(self.railsNb):
self._rails.append( HorizontalRail(self,i,self.getRailAxis(i)) )
#print ' Rail [%i] @%d' % (i,DbU.toLambda(self._rails[-1].axis))
return
class SouthSide ( HorizontalSide ):
def __init__ ( self, corona ):
HorizontalSide.__init__( self, corona )
return
def getRailAxis ( self, i ):
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]
class NorthSide ( HorizontalSide ):
def __init__ ( self, corona ):
HorizontalSide.__init__( self, corona )
return
def getRailAxis ( self, i ):
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]
class VerticalSide ( Side ):
def __init__ ( self, corona ):
Side.__init__( self, corona )
self._rails = []
for i in range(self.railsNb):
self._rails.append( VerticalRail(self,i,self.getRailAxis(i)) )
return
class WestSide ( VerticalSide ):
def __init__ ( self, corona ):
VerticalSide.__init__( self, corona )
return
def getRailAxis ( self, i ):
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]
class EastSide ( VerticalSide ):
def __init__ ( self, corona ):
VerticalSide.__init__( self, corona )
return
def getRailAxis ( self, i ):
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]
class Corona ( object ):
def __init__ ( self, block ):
if not isinstance(block,chip.BlockPower.Block):
raise ErrorMessage( 1, 'Attempt to create a Corona on a non-Block object.' )
self._framework = CRL.AllianceFramework.get()
self._routingGauge = self._framework.getRoutingGauge()
self._block = block
self._innerBb = self._block.bb
self._block.path.getTransformation().applyOn( self._innerBb )
self._railsNb = 4
self._hRailWidth = DbU.fromLambda( 12.0 )
self._vRailWidth = DbU.fromLambda( 12.0 )
self._hRailSpace = DbU.fromLambda( 6.0 )
self._vRailSpace = DbU.fromLambda( 6.0 )
self._topLayerDepth = 0
self._horizontalDepth = 0
self._verticalDepth = 0
self._southSide = SouthSide( self )
self._northSide = NorthSide( self )
self._westSide = WestSide ( self )
self._eastSide = EastSide ( self )
self._guessHvLayers()
return
def _guessHvLayers ( self ):
topLayer = Cfg.getParamString('katabatic.topRoutingLayer').asString()
self._topLayerDepth = 0
for layerGauge in self._routingGauge.getLayerGauges():
if layerGauge.getLayer().getName() == topLayer:
self._topLayerDepth = layerGauge.getDepth()
break
if not self._topLayerDepth:
print WarningMessage( 'Gauge top layer not defined, using top of gauge (%d).' \
% self._routingGauge.getDepth() )
self._topLayerDepth = self._routingGauge.getDepth()
for depth in range(0,self._topLayerDepth+1):
if self._routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal:
self._horizontalDepth = depth
if self._routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Vertical:
self._verticalDepth = depth
return
def getLayerDepth ( self, metal ):
return self._routingGauge.getLayerDepth( metal )
def getRailNet ( self, i ):
if i % 2: return self._block.vssi
return self._block.vddi
def getHLayer ( self ):
return self._routingGauge.getLayerGauge( self._horizontalDepth ).getLayer()
def getVLayer ( self ):
return self._routingGauge.getLayerGauge( self._verticalDepth ).getLayer()
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 ] )
return
def connectPads ( self, padsCorona ):
self._southSide.connectPads( padsCorona.southSide )
self._northSide.connectPads( padsCorona.northSide )
self._eastSide.connectPads( padsCorona.eastSide )
self._westSide.connectPads( padsCorona.westSide )
return
def doLayout ( self ):
self._corners = { chip.SouthWest : []
, chip.SouthEast : []
, chip.NorthWest : []
, chip.NorthEast : []
}
contactDepth = self._horizontalDepth
if self._horizontalDepth > self._verticalDepth:
contactDepth = self._verticalDepth
for i in range(self._railsNb):
xBL = self._westSide .getRail(i).axis
yBL = self._southSide.getRail(i).axis
xTR = self._eastSide .getRail(i).axis
yTR = self._northSide.getRail(i).axis
net = self.getRailNet( i )
self._corners[chip.SouthWest].append(
Contact.create( net
, self._routingGauge.getContactLayer(contactDepth)
, xBL, yBL
, self._hRailWidth
, self._vRailWidth
) )
self._corners[chip.NorthWest].append(
Contact.create( net
, self._routingGauge.getContactLayer(contactDepth)
, xBL, yTR
, self._hRailWidth
, self._vRailWidth
) )
self._corners[chip.SouthEast].append(
Contact.create( net
, self._routingGauge.getContactLayer(contactDepth)
, xTR, yBL
, self._hRailWidth
, self._vRailWidth
) )
self._corners[chip.NorthEast].append(
Contact.create( net
, self._routingGauge.getContactLayer(contactDepth)
, xTR, yTR
, self._hRailWidth
, self._vRailWidth
) )
self._southSide.doLayout()
self._northSide.doLayout()
self._westSide .doLayout()
self._eastSide .doLayout()
return

View File

@ -0,0 +1,218 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/chip/BlockPower.py" |
# +-----------------------------------------------------------------+
from Hurricane import DbU
from Hurricane import Point
from Hurricane import Transformation
from Hurricane import Box
from Hurricane import Interval
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
from Hurricane import Net
from Hurricane import Contact
from Hurricane import Horizontal
from Hurricane import Vertical
from Hurricane import Query
import CRL
from helpers import ErrorMessage
from helpers import WarningMessage
import chip.Configuration
class Side ( object ):
def __init__ ( self, block, side, net, metal ):
self.block = block
self.side = side
self.net = net
self.metal = metal
self.terminals = [ ]
return
def addTerminal ( self, position, width ):
toMerge = Interval( position-width/2, position+width/2 )
length = len(self.terminals)
imerge = length
ichunk = 0
while ichunk < length:
if imerge == length:
if toMerge.getVMax() < self.terminals[ichunk][0].getVMin():
self.terminals.insert( ichunk, [ toMerge, None ] )
imerge = ichunk
length += 1
break
if toMerge.intersect(self.terminals[ichunk][0]):
imerge = ichunk
self.terminals[ichunk][0].merge( toMerge )
else:
if toMerge.getVMax() >= self.terminals[ichunk][0].getVMin():
self.terminals[imerge][0].merge( self.terminals[ichunk][0] )
del self.terminals[ichunk]
length -= 1
continue
else:
break
ichunk += 1
if ichunk == length:
self.terminals.append( [ toMerge, None ] )
return
def doLayout ( self ):
if self.side == chip.West:
width = 0
x = self.block.bb.getXMin()
elif self.side == chip.East:
width = 0
x = self.block.bb.getXMax()
elif self.side == chip.South:
height = 0
y = self.block.bb.getYMin()
elif self.side == chip.North:
height = 0
y = self.block.bb.getYMax()
for terminal in self.terminals:
if self.side == chip.West or self.side == chip.East:
center = Point( x, terminal[0].getCenter() )
height = terminal[0].getSize()
elif self.side == chip.North or self.side == chip.South:
center = Point( terminal[0].getCenter(), y )
width = terminal[0].getSize()
self.block.path.getTransformation().applyOn( center )
contact = Contact.create( self.net, self.metal, center.getX(), center.getY(), width, height )
terminal[ 1 ] = contact
return
class Plane ( object ):
Horizontal = 0001
Vertical = 0002
def __init__ ( self, block, metal ):
self.block = block
self.metal = metal
self.sides = { }
return
def addTerminal ( self, net, direction, bb ):
if not self.sides.has_key(net):
self.sides[ net ] = [ Side(self.block,chip.North,net,self.metal)
, Side(self.block,chip.South,net,self.metal)
, Side(self.block,chip.East ,net,self.metal)
, Side(self.block,chip.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() )
if bb.getXMax() >= self.block.bb.getXMax():
sides[chip.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() )
if bb.getYMax() >= self.block.bb.getYMax():
sides[chip.North].addTerminal( bb.getCenter().getX(), bb.getWidth() )
return
def doLayout ( self ):
for sidesOfNet in self.sides.values():
for side in sidesOfNet:
side.doLayout()
return
class GoCb ( object ):
def __init__ ( self, block ):
self.block = block
return
def __call__ ( self, query, go ):
direction = None
if isinstance(go,Horizontal): direction = Plane.Horizontal
if isinstance(go,Vertical): direction = Plane.Vertical
if not direction: return
rootNet = None
if go.getNet().getType() == Net.Type.POWER: rootNet = self.block.vddi
if go.getNet().getType() == Net.Type.GROUND: rootNet = self.block.vssi
if not rootNet: return
if self.block.activePlane:
bb = go.getBoundingBox( self.block.activePlane.metal.getBasicLayer() )
query.getPath().getTransformation().applyOn( bb )
self.block.activePlane.addTerminal( rootNet, direction, bb )
else:
print WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' )
return
class Block ( object ):
def __init__ ( self, path, vddi, vssi ):
self.path = path
self.cell = self.path.getTailInstance().getMasterCell()
self.bb = self.cell.getAbutmentBox()
self.vddi = vddi
self.vssi = vssi
self.planes = { }
self.activePlane = None
routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
for layerGauge in routingGauge.getLayerGauges():
self.planes[ layerGauge.getLayer().getName() ] = Plane( self, layerGauge.getLayer() )
return
def queryPower ( self ):
if not self.vddi or not self.vssi:
print ErrorMessage( 1, 'Cannot build block power terminals as vddi and/or vss are not known.' )
return
goCb = GoCb( self )
query = Query()
query.setGoCallback( goCb )
query.setCell( self.cell )
query.setArea( self.bb )
query.setFilter( Query.DoComponents|Query.DoTerminalCells )
routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
for layerGauge in routingGauge.getLayerGauges():
self.activePlane = self.planes[ layerGauge.getLayer().getName() ]
query.setBasicLayer( layerGauge.getLayer().getBasicLayer() )
query.doQuery()
self.activePlane = None
return
def doLayout ( self ):
UpdateSession.open()
for plane in self.planes.values():
plane.doLayout()
UpdateSession.close()
return

View File

@ -0,0 +1,363 @@
# -*- explicit-buffer-name: "Configuration.py<cumulus/src/plugins/chip>" -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/chip/Configuration.py" |
# +-----------------------------------------------------------------+
import sys
import os.path
import Cfg
from Hurricane import DbU
from Hurricane import Box
from Hurricane import Net
import CRL
from helpers import ErrorMessage
from helpers import WarningMessage
from plugins import getParameter
class Configuration ( object ):
@staticmethod
def _readChipSize( chipConfig ):
if not chipConfig.has_key('chip.size'): return Box()
chipSize = chipConfig['chip.size']
if not isinstance(chipSize,tuple):
print ErrorMessage( 1, 'The Chip size parameter is *not* a tuple.' )
return Box()
if len(chipSize) != 2:
print ErrorMessage( 1, 'The Chip size parameter is *not* a tuple of exactly two items.' )
return Box()
return Box( 0, 0, DbU.fromLambda(chipSize[0]), DbU.fromLambda(chipSize[1]) )
@staticmethod
def _readCoreSize( chipConfig ):
if not chipConfig.has_key('core.size'):
print ErrorMessage( 1, 'The Core size parameter is missing.' )
return Box()
coreSize = chipConfig['core.size']
if not isinstance(coreSize,tuple):
print ErrorMessage( 1, 'The Core size parameter is *not* a tuple.' )
return Box()
if len(coreSize) != 2:
print ErrorMessage( 1, 'The Core size parameter is *not* a tuple of exactly two items.' )
return Box()
return Box( 0, 0, DbU.fromLambda(coreSize[0]), DbU.fromLambda(coreSize[1]) )
def _readPads ( self, chipConfig, keyword ):
if not chipConfig.has_key(keyword): return []
padNameList = chipConfig[keyword]
if not isinstance(padNameList,list):
print ErrorMessage( 1, 'The "%s" entry is not a list.' )
return []
af = CRL.AllianceFramework.get()
padList = []
for i in range(len(padNameList)):
if not isinstance(padNameList[i],str):
print ErrorMessage( 1, 'The element [%d] of list %s is *not* a string (skipped).'
% (i,keyword) )
continue
instance = self._cell.getInstance( padNameList[i] )
if not instance:
print ErrorMessage( 1, 'The pad [%d] (%s) of list %s do not exists in netlist (skipped).'
% (i,padNameList[i],keyword) )
continue
if (not af.isPad(instance.getMasterCell().getName())):
print ErrorMessage( 1, 'The pad [%d] (%s) of list %s is not an instance of a pad cell (skipped).'
% (i,padNameList[i],keyword) )
continue
padList.append( instance )
if not self._clockPad and instance.getMasterCell().getName() == 'pck_px':
self._clockPad = instance
if not self._powerPad and instance.getMasterCell().getName() == 'pvddick_px':
self._powerPad = instance
return padList
def _guessGlobalNet ( self, name, net ):
if name == self._vddeName: self._vdde = net
if name == self._vddiName: self._vddi = net
if name == self._vsseName: self._vsse = net
if name == self._vssiName: self._vssi = net
if name == self._ckiName: self._cki = net
if name == self._ckoName: self._cko = net
if name == self._ckName: self._ck = net
return
def __init__ ( self, chipConfig, cell ):
if not isinstance(chipConfig,dict):
raise ErrorMessage( 1, 'The "chip" variable is not a dictionnary.' )
self._validated = True
self._routingGauge = None
self._topLayerDepth = 0
self._cell = cell
# Block Corona parameters.
self._railsNb = DbU.fromLambda( getParameter('chip','chip.block.rails.count' ).asInt() )
self._hRailWidth = DbU.fromLambda( getParameter('chip','chip.block.rails.hWidth' ).asInt() )
self._vRailWidth = DbU.fromLambda( getParameter('chip','chip.block.rails.vWidth' ).asInt() )
self._hRailSpace = DbU.fromLambda( getParameter('chip','chip.block.rails.hSpacing').asInt() )
self._vRailSpace = DbU.fromLambda( getParameter('chip','chip.block.rails.vSpacing').asInt() )
# Global net names.
self._vddeName = "vdde"
self._vddiName = "vddi"
self._vsseName = "vsse"
self._vssiName = "vssi"
self._ckiName = "ck"
self._ckoName = "cko"
self._ckName = "pad"
# Global net names.
self._vdde = None
self._vddi = None
self._vsse = None
self._vssi = None
self._cki = None
self._cko = None
self._ck = None
self._clockPad = None
self._powerPad = None
self._cores = []
self._southPads = self._readPads( chipConfig, 'pads.south' )
self._northPads = self._readPads( chipConfig, 'pads.north' )
self._eastPads = self._readPads( chipConfig, 'pads.east' )
self._westPads = self._readPads( chipConfig, 'pads.west' )
self._coreSize = Configuration._readCoreSize( chipConfig )
self._chipSize = Configuration._readChipSize( chipConfig )
self._minCorona = DbU.fromLambda( 100 )
self._padWidth = 0
self._padHeight = 0
self.loadRoutingGauge()
self.checkPads()
self.computeChipSize()
self.findPowerAndClockNets()
return
def loadRoutingGauge ( self ):
self._routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
topLayer = Cfg.getParamString('katabatic.topRoutingLayer').asString()
self._topLayerDepth = 0
for layerGauge in self._routingGauge.getLayerGauges():
if layerGauge.getLayer().getName() == topLayer:
self._topLayerDepth = layerGauge.getDepth()
break
if not self._topLayerDepth:
print WarningMessage( 'Gauge top layer not defined, using top of gauge (%d).' \
% self._routingGauge.getDepth() )
self._topLayerDepth = self._routingGauge.getDepth()
return
def checkPads ( self ):
af = CRL.AllianceFramework.get()
cellPads = []
for instance in self._cell.getInstances():
if (af.isPad(instance.getMasterCell().getName())):
cellPads.append( instance )
else:
self._cores.append( instance )
for pad in cellPads:
if pad in self._southPads: continue
if pad in self._northPads: continue
if pad in self._eastPads: continue
if pad in self._westPads: continue
print ErrorMessage( 1, 'Pad "%s" is not on any side (N/S/E/W).' % pad.getName() )
self._validated = False
if len(self._cores) < 1:
print ErrorMessage( 1, 'Chip "%s" doesn\'t seems to have a core.' % self._cell.getName() )
self._validated = False
if len(self._cores) > 1:
message = [ 'Chip "%s" have more than one core:' % self._cell.getName() ]
for i in range(len(self._cores)):
message.append( '%4d: %s' % (i,self._cores[i].getName()) )
print ErrorMessage( 1, message )
self._validated = False
return
def findPowerAndClockNets ( self ):
if self._powerPad:
for plug in self._powerPad.getPlugs():
masterNet = plug.getMasterNet()
netType = masterNet.getType()
if netType != Net.Type.POWER \
and netType != Net.Type.GROUND \
and netType != Net.Type.CLOCK:
continue
net = plug.getNet()
if not net:
net = self._cell.getNet( masterNet.getName() )
if not net:
print ErrorMessage( 1, 'Missing global net <%s> at chip level.' % masterNet.getName() )
self._validated = False
continue
self._guessGlobalNet( masterNet.getName(), net )
if self._clockPad:
for plug in self._powerPad.getPlugs():
masterNet = plug.getMasterNet()
netType = masterNet.getType()
net = plug.getNet()
if not net:
net = self._cell.getNet( masterNet.getName() )
if not net:
print ErrorMessage( 1, 'Missing global net <%s> at chip level.' % masterNet.getName() )
self._validated = False
continue
if masterNet.getName() == self._ckName:
self._guessGlobalNet( masterNet.getName(), net )
return
def computeChipSize ( self ):
if not self._clockPad:
print ErrorMessage( 1, 'There must be at least one pad of model "pck_px" to be used as reference.' )
self._validated = False
return False
self._padHeight = self._clockPad.getMasterCell().getAbutmentBox().getHeight()
self._padWidth = self._clockPad.getMasterCell().getAbutmentBox().getWidth()
if not self._chipSize.isEmpty(): return
horizontalPads = max( len(self._southPads), len(self._northPads) )
verticalPads = max( len(self._eastPads ), len(self._westPads ) )
self._chipSize = Box( 0
, 0
, self._padWidth * horizontalPads + 2*self._padHeight
, self._padWidth * verticalPads + 2*self._padHeight
)
return
def getSpecialNetRoot ( self, net ):
if net.getName() == self._vddeName: return self._vdde
if net.getName() == self._vsseName: return self._vsse
if net.getType() == Net.Type.POWER: return self._vddi
if net.getType() == Net.Type.GROUND: return self._vssi
return None
class Wrapper ( object ):
def __init__ ( self, conf ):
if not isinstance(conf,Configuration):
raise ErrorMessage('Attempt to create a Wrapper() from non-Configuration object.')
self._conf = conf
return
def isValid ( self ): return self._conf._validated
@property
def conf ( self ): return self._conf
@property
def routingGauge ( self ): return self._conf._routingGauge
@property
def topLayerDepth ( self ): return self._conf._topLayerDepth
@property
def cell ( self ): return self._conf._cell
# Global Net names.
@property
def vddeName ( self ): return self._conf._vddeName
@property
def vsseName ( self ): return self._conf._vsseName
@property
def vddiName ( self ): return self._conf._vddiName
@property
def vssiName ( self ): return self._conf._vssiName
@property
def ckiName ( self ): return self._conf._ckiName
@property
def ckoName ( self ): return self._conf._ckoName
@property
def ckName ( self ): return self._conf._ckName
# Global Nets.
@property
def vdde ( self ): return self._conf._vdde
@property
def vsse ( self ): return self._conf._vsse
@property
def vddi ( self ): return self._conf._vddi
@property
def vssi ( self ): return self._conf._vssi
@property
def cki ( self ): return self._conf._cki
@property
def cko ( self ): return self._conf._cko
@property
def ck ( self ): return self._conf._ck
# Various.
@property
def clockPad ( self ): return self._conf._clockPad
@property
def powerPad ( self ): return self._conf._powerPad
@property
def cores ( self ): return self._conf._cores
@property
def southPads ( self ): return self._conf._southPads
@property
def northPads ( self ): return self._conf._northPads
@property
def eastPads ( self ): return self._conf._eastPads
@property
def westPads ( self ): return self._conf._westPads
@property
def coreSize ( self ): return self._conf._coreSize
@coreSize.setter
def coreSize ( self, ab ): self._conf._coreSize = ab
@property
def chipSize ( self ): return self._conf._chipSize
@property
def minCorona ( self ): return self._conf._minCorona
@property
def padWidth ( self ): return self._conf._padWidth
@property
def padHeight ( self ): return self._conf._padHeight
def loadConfiguration ( cell ):
sys.path.append( os.getcwd() )
confFile = cell.getName()+'_chip'
confModule = __import__( confFile, globals(), locals(), confFile )
if not confModule.__dict__.has_key('chip'):
raise WarningMessage( 'Module <%s> do not provides the chip variable, skipped.' \
% confFile )
return Wrapper( Configuration( confModule.__dict__['chip'], cell ) )

View File

@ -0,0 +1,393 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/chip/PadsCorona.py" |
# +-----------------------------------------------------------------+
from operator import itemgetter
import Cfg
from Hurricane import DbU
from Hurricane import Point
from Hurricane import Transformation
from Hurricane import Box
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
from Hurricane import Net
from Hurricane import Contact
from Hurricane import Horizontal
from Hurricane import Vertical
from Hurricane import Instance
import CRL
from CRL import RoutingLayerGauge
from helpers import ErrorMessage
from helpers import WarningMessage
import chip.Configuration
class Side ( object ):
def __init__ ( self, corona, sideType ):
self._type = sideType
self._corona = corona
self._powerContacts = []
if self._type == chip.North: self._pads = self._corona.northPads
elif self._type == chip.South: self._pads = self._corona.southPads
elif self._type == chip.East: self._pads = self._corona.eastPads
elif self._type == chip.West: self._pads = self._corona.westPads
else:
raise ErrorMessage( 1, 'PadsCorona.Side.__init__(): Invalid value for sideType (%d)' % sideType )
return
def _toGrid ( self, v ): return v - (v % DbU.fromLambda(5.0))
def getAxis ( self, i ):
if self._type == chip.North: return self._corona.chipSize.getXMax() - self._corona.padHeight + self._corona._powerRails[i][2]
elif self._type == chip.South: return self._corona.chipSize.getXMin() + self._corona.padHeight - self._corona._powerRails[i][2]
elif self._type == chip.East: return self._corona.chipSize.getYMax() - self._corona.padHeight + self._corona._powerRails[i][2]
elif self._type == chip.West: return self._corona.chipSize.getYMin() + self._corona.padHeight - self._corona._powerRails[i][2]
else:
raise ErrorMessage( 1, 'PadsCorona.Side.__init__(): Invalid value for sideType (%d)' % sideType )
return 0
def _check ( self, checkSize, checkName ):
sideName = 'unknown'
chipSize = 0
if self._type == chip.North or self._type == chip.South:
chipSize = self._corona.chipSize.getWidth()
sideName = 'wide'
elif self._type == chip.East or self._type == chip.West:
chipSize = self._corona.chipSize.getHeight()
sideName = 'tall'
if checkSize > chipSize:
print ErrorMessage( 1, [ 'Chip is not %s enought to accomodate the %s,' % (sideName,checkName)
, 'needs %dl, but only has %dl.'
% ( DbU.toLambda(checkSize), DbU.toLambda(chipSize) )
] )
return False
return True
def check ( self ):
validated = True
if self._type == chip.North:
self.validated = self._check( self._corona.coreSize.getWidth()
+ 2*self._corona.minCorona
+ 2*self._corona.padHeight
, 'core' )
checkName = 'north pads'
elif self._type == chip.East:
self.validated = self._check( self._corona.coreSize.getHeight()
+ 2*self._corona.minCorona
+ 2*self._corona.padHeight
, 'core' )
checkName = 'east pads'
elif self._type == chip.South: checkName = 'south pads'
elif self._type == chip.West: checkName = 'west pads'
validated = self._check( len(self._pads)*self._corona.padWidth
+ 2*self._corona.padHeight
, checkName ) and validated
return validated
def _createPowerContacts ( self, pad, net ):
if self._type == chip.North or self._type == chip.South:
hvDepth = self._corona.getVDepth()
elif self._type == chip.East or self._type == chip.West:
hvDepth = self._corona.getHDepth()
masterCell = pad.getMasterCell()
for component in masterCell.getNet(net.getName()).getExternalComponents():
if component.getBoundingBox().getYMin() > masterCell.getAbutmentBox().getYMin(): continue
if self._corona.routingGauge.getLayerDepth(component.getLayer()) != hvDepth: continue
if not isinstance(component,Vertical): continue
if self._type == chip.North or self._type == chip.South:
width = component.getWidth()
height = 0
else:
width = 0
height = component.getWidth()
position = Point( component.getX(), masterCell.getAbutmentBox().getYMin() )
pad.getTransformation().applyOn( position )
self._powerContacts.append( Contact.create( net
, component.getLayer()
, position.getX()
, position.getY()
, width
, height
) )
return
def _createAllPowerContacts ( self ):
for pad in self._pads:
masterCell = pad.getMasterCell()
if masterCell.getName() != 'pvddick_px' \
and masterCell.getName() != 'pvssick_px' \
and masterCell.getName() != 'pvddeck_px' \
and masterCell.getName() != 'pvsseck_px':
continue
#print 'Power pad:', pad
self._createPowerContacts( pad, self._corona.vddi )
self._createPowerContacts( pad, self._corona.vssi )
return
def _placePads ( self ):
if self._type == chip.North:
hAdvance = True
orientation = Transformation.Orientation.ID
sideLength = self._corona.chipSize.getWidth()
x = self._corona.padHeight
y = self._corona.chipSize.getHeight() - self._corona.padHeight
elif self._type == chip.South:
hAdvance = True
orientation = Transformation.Orientation.MY
sideLength = self._corona.chipSize.getWidth()
x = self._corona.padHeight
y = self._corona.padHeight
elif self._type == chip.East:
hAdvance = False
orientation = Transformation.Orientation.R3
sideLength = self._corona.chipSize.getHeight()
x = self._corona.chipSize.getWidth() - self._corona.padHeight
y = self._corona.padHeight + self._corona.padWidth
elif self._type == chip.West:
hAdvance = False
orientation = Transformation.Orientation.R1
sideLength = self._corona.chipSize.getHeight()
x = self._corona.padHeight
y = self._corona.padHeight
step = (sideLength - 2*self._corona.padHeight) / len(self._pads)
for pad in self._pads:
pad.setTransformation ( Transformation( self._toGrid(x), self._toGrid(y), orientation ) )
pad.setPlacementStatus( Instance.PlacementStatus.FIXED )
if hAdvance: x += step
else: y += step
return
def _routePads ( self ):
for i in range(len(self._corona._powerRails)):
if self._type == chip.South:
Horizontal.create( self._corona._corners[chip.SouthWest ][i]
, self._corona._corners[chip.SouthEast][i]
, self._corona._powerRails[i][1]
, self.getAxis( i )
, self._corona._powerRails[i][3]
)
elif self._type == chip.North:
Horizontal.create( self._corona._corners[chip.NorthWest ][i]
, self._corona._corners[chip.NorthEast][i]
, self._corona._powerRails[i][1]
, self.getAxis( i )
, self._corona._powerRails[i][3]
)
elif self._type == chip.East:
Vertical.create( self._corona._corners[chip.SouthEast][i]
, self._corona._corners[chip.NorthEast ][i]
, self._corona._powerRails[i][1]
, self.getAxis( i )
, self._corona._powerRails[i][3]
)
elif self._type == chip.West:
Vertical.create( self._corona._corners[chip.SouthWest][i]
, self._corona._corners[chip.NorthWest ][i]
, self._corona._powerRails[i][1]
, self.getAxis( i )
, self._corona._powerRails[i][3]
)
return
def doLayout ( self ):
self._placePads()
self._routePads()
self._createAllPowerContacts()
return
class Corona ( chip.Configuration.Wrapper ):
def __init__ ( self, confWrapper ):
chip.Configuration.Wrapper.__init__( self, confWrapper.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 : []
, chip.SouthEast : []
, chip.NorthWest : []
, chip.NorthEast : []
}
self._powerRails = [] # [ , [net, layer, axis, width] ]
self._locatePadRails()
self._guessHvLayers()
return
@property
def southSide ( self ): return self._southSide
@property
def northSide ( self ): return self._northSide
@property
def eastSide ( self ): return self._eastSide
@property
def westSide ( self ): return self._westSide
def getSwCorner ( self, i ): return self._corners[chip.SouthWest][i]
def getSeCorner ( self, i ): return self._corners[chip.SouthEast][i]
def getNwCorner ( self, i ): return self._corners[chip.NorthWest][i]
def getNeCorner ( self, i ): return self._corners[chip.NorthEast][i]
def getRailNet ( self, i ): return self._powerRails[i][0]
def getRailLayer ( self, i ): return self._powerRails[i][1]
def getRailAxis ( self, i ): return self._powerRails[i][2]
def getRailWidth ( self, i ): return self._powerRails[i][3]
def getHDepth ( self ): return self._horizontalDepth
def getVDepth ( self ): return self._verticalDepth
def validate ( self ):
self.validated = self._northSide.check()
self.validated = self._southSide.check() and self.validated
self.validated = self._eastSide.check() and self.validated
self.validated = self._westSide.check() and self.validated
return self.validated
def _locatePadRails ( self ):
if not self.clockPad:
print ErrorMessage( 1, 'There must be at least one pad of model "pck_px" to guess the pad rails.' )
return False
for plug in self.clockPad.getPlugs():
masterNet = plug.getMasterNet()
netType = masterNet.getType()
net = plug.getNet()
if netType != Net.Type.POWER \
and netType != Net.Type.GROUND \
and netType != Net.Type.CLOCK:
continue
if not net:
net = self.cell.getNet( masterNet.getName() )
if not net:
print ErrorMessage( 1, 'Missing global net <%s> at chip level.' % masterNet.getName() )
continue
for component in masterNet.getExternalComponents():
if not isinstance(component,Horizontal): continue
xs = component.getSourcePosition().getX()
xt = component.getTargetPosition().getX()
if xs < xt: length = xt - xs
else: length = xs - xt
if length < self.padWidth*.6: continue
self._powerRails.append( [ net, component.getLayer(), component.getY(), component.getWidth() ] )
self._powerRails.sort( key=itemgetter(2) )
#for rail in self._powerRails:
# print 'Pad rail %s @%d width:%d layer:%s' % ( str(rail[0].getName())
# , DbU.toLambda(rail[2])
# , DbU.toLambda(rail[3])
# , str(rail[1].getName())
# )
return
def _guessHvLayers ( self ):
if not self.powerPad:
print ErrorMessage( 1, 'There must be at least one pad of model "pvddick_px" to guess the pad power terminals.' )
return False
availableDepths = set()
masterCell = self.powerPad.getMasterCell()
for component in masterCell.getNet('vddi').getExternalComponents():
if component.getBoundingBox().getYMin() <= masterCell.getAbutmentBox().getYMin():
availableDepths.add( self.routingGauge.getLayerDepth(component.getLayer()) )
#print 'available depth:', availableDepths
self._horizontalDepth = 0
self._verticalDepth = 0
for depth in range(0,self.topLayerDepth+1):
if not depth in availableDepths: continue
if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal:
self._horizontalDepth = depth
if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Vertical:
self._verticalDepth = depth
#print 'h:', self._horizontalDepth
#print 'v:', self._verticalDepth
return
def doLayout ( self ):
if not self.validated: return
UpdateSession.open()
self.cell.setAbutmentBox( self.chipSize )
for i in range(len(self._powerRails)):
xBL = self._westSide .getAxis(i)
yBL = self._southSide.getAxis(i)
xTR = self._eastSide .getAxis(i)
yTR = self._northSide.getAxis(i)
self._corners[chip.SouthWest].append(
Contact.create( self.getRailNet(i)
, self.getRailLayer(i)
, xBL, yBL
, self.getRailWidth(i)
, self.getRailWidth(i)
) )
self._corners[chip.NorthWest].append(
Contact.create( self.getRailNet(i)
, self.getRailLayer(i)
, xBL, yTR
, self.getRailWidth(i)
, self.getRailWidth(i)
) )
self._corners[chip.SouthEast].append(
Contact.create( self.getRailNet(i)
, self.getRailLayer(i)
, xTR, yBL
, self.getRailWidth(i)
, self.getRailWidth(i)
) )
self._corners[chip.NorthEast].append(
Contact.create( self.getRailNet(i)
, self.getRailLayer(i)
, xTR, yTR
, self.getRailWidth(i)
, self.getRailWidth(i)
) )
self._northSide.doLayout()
self._southSide.doLayout()
self._eastSide.doLayout()
self._westSide.doLayout()
UpdateSession.close()
return

View File

@ -0,0 +1,29 @@
# -*- explicit-buffer-name: "__init__.py<cumulus/plugins/chip>" -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C u m u l u s - P y t h o n T o o l s |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./plugins/chip/__init__.py" |
# +-----------------------------------------------------------------+
# Common constants used through all <chip> modules.
# For Corona's sides.
North = 0000
South = 0001
East = 0002
West = 0003
# For Corona's corners.
SouthWest = 0000
SouthEast = 0001
NorthWest = 0002
NorthEast = 0003

View File

@ -1,7 +1,6 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2000-2013, All Rights Reserved
// Copyright (c) BULL S.A. 2000-2014, All Rights Reserved
//
// This file is part of Hurricane.
//
@ -19,10 +18,6 @@
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// $Id$
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
// | V L S I B a c k e n d D a t a - B a s e |
@ -35,7 +30,6 @@
#include <limits>
#include "hurricane/BasicLayer.h"
#include "hurricane/Slice.h"
#include "hurricane/Cell.h"
@ -45,15 +39,9 @@
namespace Hurricane {
// -------------------------------------------------------------------
// Slave Class : "QueryState".
// -------------------------------------------------------------------
// Class : "QueryStack".
QueryStack::QueryStack ()
: vector<QueryState*>()
//, _tab (" ")

View File

@ -1,7 +1,6 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2000-2013, All Rights Reserved
// Copyright (c) BULL S.A. 2000-2014, All Rights Reserved
//
// This file is part of Hurricane.
//
@ -19,10 +18,6 @@
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// $Id$
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
// | V L S I B a c k e n d D a t a - B a s e |
@ -34,22 +29,19 @@
// +-----------------------------------------------------------------+
#ifndef __QUERY_H__
#define __QUERY_H__
#ifndef HURRICANE_QUERY_H
#define HURRICANE_QUERY_H
#include <vector>
#include "hurricane/Commons.h"
#include "hurricane/Box.h"
#include "hurricane/Transformation.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
#include <vector>
#include "hurricane/Commons.h"
#include "hurricane/Box.h"
#include "hurricane/Transformation.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
namespace Hurricane {
class BasicLayer;
class Go;
class QueryStack;
@ -58,7 +50,6 @@ namespace Hurricane {
// -------------------------------------------------------------------
// Slave Class : "QueryState".
class QueryState {
private:
inline QueryState ( Locator<Instance*>* locator );
@ -386,8 +377,6 @@ namespace Hurricane {
//inline const Tabulation& Query::getTab () const { return _stack.getTab(); }
} // Hurricane namespace.
} // End of Hurricane namespace.
#endif // __QUERY_H__
#endif // HURRICANE_QUERY_H

View File

@ -9,6 +9,7 @@
)
set ( sources ProxyProperty.cpp
PyBreakpoint.cpp
PyInterval.cpp
PyBox.cpp
PyCell.cpp
PyCellCollection.cpp
@ -72,6 +73,7 @@
)
set ( includes hurricane/isobar/ProxyProperty.h
hurricane/isobar/PyBreakpoint.h
hurricane/isobar/PyInterval.h
hurricane/isobar/PyBox.h
hurricane/isobar/PyCell.h
hurricane/isobar/PyCellCollection.h

View File

@ -103,7 +103,7 @@ extern "C" {
layer = const_cast<Layer*>(component->getLayer ());
HCATCH
return PyLayer_Link ( layer );
return PyLayer_LinkDerived ( layer );
}

View File

@ -20,6 +20,7 @@
#include "hurricane/isobar/PyUpdateSession.h"
#include "hurricane/isobar/PyDbU.h"
#include "hurricane/isobar/PyPoint.h"
#include "hurricane/isobar/PyInterval.h"
#include "hurricane/isobar/PyBox.h"
#include "hurricane/isobar/PyTransformation.h"
#include "hurricane/isobar/PyOrientation.h"
@ -501,6 +502,7 @@ extern "C" {
PyUpdateSession_LinkPyType ();
PyDbU_LinkPyType ();
PyPoint_LinkPyType ();
PyInterval_LinkPyType ();
PyBox_LinkPyType ();
PyTransformation_LinkPyType ();
PyOrientation_LinkPyType ();
@ -560,8 +562,9 @@ extern "C" {
PYTYPE_READY ( DebugSession )
PYTYPE_READY ( UpdateSession )
PYTYPE_READY ( Point )
PYTYPE_READY ( DbU )
PYTYPE_READY ( Point )
PYTYPE_READY ( Interval )
PYTYPE_READY ( Box )
PYTYPE_READY ( Transformation )
PYTYPE_READY ( Orientation )
@ -635,6 +638,7 @@ extern "C" {
PYTYPE_READY_SUB ( Pad , Component)
// Identifier string can take up to 10 characters !
__cs.addType ( "intv" , &PyTypeInterval , "<Interval>" , false );
__cs.addType ( "box" , &PyTypeBox , "<Box>" , false );
__cs.addType ( "ent" , &PyTypeEntity , "<Entity>" , false );
__cs.addType ( "cell" , &PyTypeCell , "<Cell>" , false, "ent" );
@ -706,9 +710,11 @@ extern "C" {
Py_INCREF ( &PyTypeDbU );
PyModule_AddObject ( module, "DbU" , (PyObject*)&PyTypeDbU );
Py_INCREF ( &PyTypePoint );
PyModule_AddObject ( module, "Box" , (PyObject*)&PyTypeBox );
Py_INCREF ( &PyTypePoint );
PyModule_AddObject ( module, "Point" , (PyObject*)&PyTypePoint );
Py_INCREF ( &PyTypeInterval );
PyModule_AddObject ( module, "Interval" , (PyObject*)&PyTypeInterval );
Py_INCREF ( &PyTypeBox );
PyModule_AddObject ( module, "Box" , (PyObject*)&PyTypeBox );
Py_INCREF ( &PyTypeTransformation );
PyModule_AddObject ( module, "Transformation" , (PyObject*)&PyTypeTransformation );
Py_INCREF ( &PyTypePath );
@ -800,6 +806,7 @@ extern "C" {
PyRoutingPad_postModuleInit();
PyNet_postModuleInit();
PyInstance_postModuleInit();
PyQuery_postModuleInit();
trace << "Hurricane.so loaded " << (void*)&typeid(string) << endl;
}

View File

@ -0,0 +1,337 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2014-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyInterval.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyPoint.h"
#include "hurricane/isobar/PyInterval.h"
namespace Isobar {
using namespace Hurricane;
extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Interval,interval,function)
// +=================================================================+
// | "PyInterval" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// Standart Accessors (Attributes).
DirectGetLongAttribute(PyInterval_getVMin ,getVMin ,PyInterval,Interval)
DirectGetLongAttribute(PyInterval_getVMax ,getVMax ,PyInterval,Interval)
DirectGetLongAttribute(PyInterval_getCenter ,getCenter ,PyInterval,Interval)
DirectGetLongAttribute(PyInterval_getSize ,getSize ,PyInterval,Interval)
DirectGetLongAttribute(PyInterval_getHalfSize ,getHalfSize ,PyInterval,Interval)
// Standart Predicates (Attributes).
DirectGetBoolAttribute(PyInterval_isEmpty ,isEmpty ,PyInterval,Interval)
DirectGetBoolAttribute(PyInterval_isPonctual,isPonctual,PyInterval,Interval)
// Standart Destroy (Attribute).
DirectDestroyAttribute(PyInterval_destroy, PyInterval)
// ---------------------------------------------------------------
// Class Method : "PyInterval_NEW ()"
static PyObject* PyInterval_NEW (PyObject *module, PyObject *args) {
trace << "PyInterval_NEW()" << endl;
Interval* interval = NULL;
HTRY
PyObject* arg0;
PyObject* arg1;
PyObject* arg2;
__cs.init ("Interval.Interval");
if (not PyArg_ParseTuple( args, "|O&O&O&:Interval.Interval"
, Converter, &arg0
, Converter, &arg1
, Converter, &arg2 ))
return NULL;
if (__cs.getObjectIds() == NO_ARG ) { interval = new Interval (); }
else if (__cs.getObjectIds() == INTS2_ARG) { interval = new Interval ( PyInt_AsLong(arg0) , PyInt_AsLong(arg1) ); }
else if (__cs.getObjectIds() == INTV_ARG ) { interval = new Interval ( *PYINTERVAL_O(arg0) ); }
else {
PyErr_SetString(ConstructorError, "invalid number of parameters for Interval constructor." );
return NULL;
}
HCATCH
return PyInterval_Link( interval );
}
static int PyInterval_Init ( PyInterval* self, PyObject* args, PyObject* kwargs )
{
trace << "PyInterval_Init(): " << (void*)self << endl;
return 0;
}
static PyObject* PyInterval_getUnion ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_getUnion()" << endl;
METHOD_HEAD ( "Interval.getUnion()" )
PyInterval* otherPyInterval;
if (PyArg_ParseTuple(args,"O!:Interval.getUnion", &PyTypeInterval, &otherPyInterval)) {
HTRY
Interval* interval = new Interval ( interval->getUnion(*PYINTERVAL_O(otherPyInterval)));
HCATCH
return PyInterval_Link( interval );
} else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.getUnion.");
}
return NULL;
}
static PyObject* PyInterval_getIntersection ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_getIntersection()" << endl;
METHOD_HEAD ( "Interval.getIntersection()" )
PyInterval* otherPyInterval = NULL;
if (PyArg_ParseTuple(args,"O!:Interval.getIntersection", &PyTypeInterval, &otherPyInterval)) {
HTRY
Interval* interval = new Interval(interval->getIntersection(*PYINTERVAL_O(otherPyInterval)));
HCATCH
return PyInterval_Link( interval );
} else {
PyErr_SetString(ConstructorError, "invalid number of parameters for Interval.getIntersection.");
}
return NULL;
}
static PyObject* PyInterval_contains ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_contains ()" << endl;
METHOD_HEAD( "Interval.contains()" )
PyObject* arg0;
bool result = false;
HTRY
__cs.init("Interval.contains");
if (not PyArg_ParseTuple(args,"|O&:Interval.contains",Converter,&arg0) )
return NULL;
if (__cs.getObjectIds() == INT_ARG ) { result = interval->contains ( PyInt_AsLong(arg0) ); }
else if (__cs.getObjectIds() == INTV_ARG) { result = interval->contains ( *PYINTERVAL_O(arg0) ); }
else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.contains constructor." );
return NULL;
}
HCATCH
if (result) Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
static PyObject* PyInterval_intersect ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_intersect ()" << endl;
bool result = false;
HTRY
PyInterval* pyInterval = NULL;
METHOD_HEAD ( "Interval.intersect()" )
if (PyArg_ParseTuple(args,"O!:Interval.intersects", &PyTypeInterval, &pyInterval)) {
result = interval->intersect( *PYINTERVAL_O(pyInterval) );
} else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.intersect." );
return NULL;
}
HCATCH
if (result) Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
static PyObject* PyInterval_makeEmpty ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_makeEmpty ()" << endl;
METHOD_HEAD( "Interval.makeEmpty()" )
interval->makeEmpty();
Py_INCREF( self );
return (PyObject*)self;
}
static PyObject* PyInterval_inflate ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_inflate ()" << endl;
METHOD_HEAD( "Interval.inflate()" )
PyObject* arg0;
PyObject* arg1;
HTRY
__cs.init( "Interval.inflate" );
if (not PyArg_ParseTuple(args,"|O&O&:Interval.inflate",Converter,&arg0,Converter,&arg1))
return NULL;
if (__cs.getObjectIds() == INT_ARG ) { interval->inflate( PyInt_AsLong(arg0) ); }
else if (__cs.getObjectIds() == INTS2_ARG) { interval->inflate( PyInt_AsLong(arg0), PyInt_AsLong(arg1) ); }
else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.inflate()" );
return NULL;
}
HCATCH
Py_INCREF( self );
return (PyObject*)self;
}
static PyObject* PyInterval_merge ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_merge ()" << endl;
METHOD_HEAD( "Interval.merge()" )
PyObject* arg0;
PyObject* arg1;
HTRY
__cs.init( "Interval.merge" );
if (not PyArg_ParseTuple(args,"|O&O&:Interval.merge",Converter,&arg0,Converter,&arg1))
return NULL;
if (__cs.getObjectIds() == INT_ARG ) { interval->merge( PyInt_AsLong(arg0) ); }
else if (__cs.getObjectIds() == INTV_ARG) { interval->merge( *PYINTERVAL_O(arg0) ); }
else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.merge()" );
return NULL;
}
HCATCH
Py_INCREF( self );
return (PyObject*)self;
}
static PyObject* PyInterval_intersection ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_intersection ()" << endl;
METHOD_HEAD( "Interval.intersection()" )
PyObject* arg0;
PyObject* arg1;
HTRY
__cs.init( "Interval.intersection" );
if (not PyArg_ParseTuple(args,"|O&O&:Interval.intersection",Converter,&arg0,Converter,&arg1))
return NULL;
if (__cs.getObjectIds() == INTV_ARG ) { interval->intersection( *PYINTERVAL_O(arg0) ); }
else if (__cs.getObjectIds() == INTS2_ARG) { interval->intersection( PyInt_AsLong(arg0), PyInt_AsLong(arg1) ); }
else {
PyErr_SetString ( ConstructorError, "invalid number of parameters for Interval.intersection()" );
return NULL;
}
HCATCH
Py_INCREF( self );
return (PyObject*)self;
}
static PyObject* PyInterval_translate ( PyInterval *self, PyObject* args ) {
trace << "PyInterval_translate ()" << endl;
HTRY
METHOD_HEAD( "Interval.translate()" )
DbU::Unit delta = 0;
if (PyArg_ParseTuple(args,"l:Interval.translate", &delta)) {
interval->translate(delta);
} else {
PyErr_SetString( ConstructorError, "invalid number of parameters for Interval.translate()" );
return NULL;
}
HCATCH
Py_INCREF( self );
return (PyObject*)self;
}
// ---------------------------------------------------------------
// PyInterval Attribute Method table.
PyMethodDef PyInterval_Methods[] =
{ { "getVMin" , (PyCFunction)PyInterval_getVMin , METH_NOARGS , "Return the VMin value." }
, { "getVMax" , (PyCFunction)PyInterval_getVMax , METH_NOARGS , "Return the VMax value." }
, { "getCenter" , (PyCFunction)PyInterval_getCenter , METH_NOARGS , "Return the interval center value." }
, { "getSize" , (PyCFunction)PyInterval_getSize , METH_NOARGS , "Return the interval length." }
, { "getHalfSize" , (PyCFunction)PyInterval_getHalfSize , METH_NOARGS , "Return the interval half length." }
, { "getUnion" , (PyCFunction)PyInterval_getUnion , METH_VARARGS, "Return the smallest enclosing interval." }
, { "getIntersection", (PyCFunction)PyInterval_getIntersection, METH_VARARGS, "Return the overlapping interval." }
, { "isEmpty" , (PyCFunction)PyInterval_isEmpty , METH_NOARGS , "Return true if the interval is empty." }
, { "isPonctual" , (PyCFunction)PyInterval_isPonctual , METH_NOARGS , "Return true if the interval reduced to a point." }
, { "contains" , (PyCFunction)PyInterval_contains , METH_VARARGS, "Return true if the interval contains the argument." }
, { "intersect" , (PyCFunction)PyInterval_intersect , METH_VARARGS, "Return true if two intervales overlap." }
, { "makeEmpty" , (PyCFunction)PyInterval_makeEmpty , METH_NOARGS , "Transform the interval in an empty one." }
, { "inflate" , (PyCFunction)PyInterval_inflate , METH_VARARGS, "Expand the interval of the given values." }
, { "merge" , (PyCFunction)PyInterval_merge , METH_VARARGS, "Expand or contract the interval to contains the arguments." }
, { "intersection" , (PyCFunction)PyInterval_intersection , METH_VARARGS, "Expand the interval to contains the arguments.." }
, { "translate" , (PyCFunction)PyInterval_translate , METH_VARARGS, "translate the interval." }
, { "destroy" , (PyCFunction)PyInterval_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
// x-------------------------------------------------------------x
// | "PyInterval" Object Methods |
// x-------------------------------------------------------------x
DirectDeleteMethod(PyInterval_DeAlloc,PyInterval)
PyTypeObjectLinkPyTypeNewInit(Interval)
//PyTypeObjectLinkPyType(Interval)
#else // End of Python Module Code Part.
// x=================================================================x
// | "PyInterval" Shared Library Code Part |
// x=================================================================x
// ---------------------------------------------------------------
// PyInterval Object Definitions.
LinkCreateMethod(Interval)
PyTypeObjectDefinitions(Interval)
# endif // End of Shared Library Code Part.
} // End of extern "C".
} // End of Isobar namespace.

View File

@ -1,36 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2006-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -47,6 +18,11 @@
#include "hurricane/isobar/PyLayer.h"
#include "hurricane/isobar/PyLayerMask.h"
#include "hurricane/isobar/PyBasicLayer.h"
#include "hurricane/isobar/PyRegularLayer.h"
#include "hurricane/isobar/PyContactLayer.h"
#include "hurricane/isobar/PyViaLayer.h"
#include "hurricane/isobar/PyDiffusionLayer.h"
#include "hurricane/isobar/PyTransistorLayer.h"
#include "hurricane/isobar/PyBasicLayerCollection.h"
@ -133,24 +109,7 @@ extern "C" {
} \
HCATCH \
\
return PyLayer_Link(rlayer); \
}
# define accessorLayerFromVoid(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self ) \
{ \
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
\
Layer* rlayer = NULL; \
\
HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
rlayer = const_cast<SELF_TYPE*>(cobject->FUNC_NAME()); \
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_Link(rlayer); \
return PyLayer_LinkDerived(rlayer); \
}
@ -196,7 +155,7 @@ extern "C" {
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_Link(rlayer); \
return PyLayer_LinkDerived(rlayer); \
}
@ -409,6 +368,32 @@ extern "C" {
}
extern PyObject* PyLayer_LinkDerived ( Layer* object )
{
if (object == NULL) Py_RETURN_NONE;
BasicLayer* basicLayer = dynamic_cast<BasicLayer*>(object);
if (basicLayer) return PyBasicLayer_Link(basicLayer);
ContactLayer* contactLayer = dynamic_cast<ContactLayer*>(object);
if (contactLayer) return PyContactLayer_Link(contactLayer);
ViaLayer* viaLayer = dynamic_cast<ViaLayer*>(object);
if (viaLayer) return PyViaLayer_Link(viaLayer);
DiffusionLayer* diffusionLayer = dynamic_cast<DiffusionLayer*>(object);
if (diffusionLayer) return PyDiffusionLayer_Link(diffusionLayer);
RegularLayer* regularLayer = dynamic_cast<RegularLayer*>(object);
if (regularLayer) return PyRegularLayer_Link(regularLayer);
TransistorLayer* transistorLayer = dynamic_cast<TransistorLayer*>(object);
if (transistorLayer) return PyTransistorLayer_Link(transistorLayer);
Py_RETURN_NONE;
}
#endif // End of Shared Library Code Part.
} // extern "C".

View File

@ -298,11 +298,11 @@ extern "C" {
, { "getMasterCell" , (PyCFunction)PyPath_getMasterCell , METH_NOARGS , "Returns the master cell referenced by the last instance of the path." }
, { "getName" , (PyCFunction)PyPath_getName , METH_NOARGS , "Returns the concatenation of instances names." }
, { "getTransformation" , (PyCFunction)PyPath_getTransformation , METH_VARARGS, "Return the resulting transformation." }
, { "getInstances", (PyCFunction)PyPath_getInstances, METH_NOARGS , "Returns the collection of instances defining the path." }
, { "getInstances" , (PyCFunction)PyPath_getInstances , METH_NOARGS , "Returns the collection of instances defining the path." }
, { "isEmpty" , (PyCFunction)PyPath_isEmpty , METH_NOARGS , "Return true if the path is empty." }
, { "destroy" , (PyCFunction)PyPath_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -130,9 +130,9 @@ extern "C" {
PyMethodDef PyPoint_Methods[] =
{ { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS , "Return the Point X value." }
, { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS , "Return the Point Y value." }
, { "SetX" , (PyCFunction)PyPoint_SetX , METH_VARARGS, "Modify the Point X value." }
, { "SetY" , (PyCFunction)PyPoint_SetY , METH_VARARGS, "Modify the Point Y value." }
, { "Translate", (PyCFunction)PyPoint_Translate, METH_VARARGS, "Translate the point of dx and dy." }
, { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS, "Modify the Point X value." }
, { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS, "Modify the Point Y value." }
, { "translate", (PyCFunction)PyPoint_Translate, METH_VARARGS, "Translate the point of dx and dy." }
, { "destroy" , (PyCFunction)PyPoint_destroy , METH_NOARGS
, "Destroy associated hurricane object The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */

View File

@ -1,36 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2010-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -44,9 +15,11 @@
#include "hurricane/isobar/PyBox.h"
#include "hurricane/isobar/PyPath.h"
#include "hurricane/isobar/PyTransformation.h"
#include "hurricane/isobar/PyBasicLayer.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/isobar/PyInstance.h"
#include "hurricane/isobar/PyEntity.h"
#include "hurricane/isobar/PyQuery.h"
#include "hurricane/isobar/PyQueryMask.h"
@ -88,6 +61,12 @@ extern "C" {
};
inline void BaseQuery::setGoCallback ( PyObject* cb ) { _goCallback = cb; }
inline void BaseQuery::setMarkerCallback ( PyObject* cb ) { _markerCallback = cb; }
inline void BaseQuery::setRubberCallback ( PyObject* cb ) { _rubberCallback = cb; }
inline void BaseQuery::setExtensionGoCallback ( PyObject* cb ) { _extensionGoCallback = cb; }
inline void BaseQuery::setMasterCellCallback ( PyObject* cb ) { _masterCellCallback = cb; }
BaseQuery::BaseQuery ( PyQuery* self )
: Query()
, _self (self)
@ -98,13 +77,7 @@ extern "C" {
, _masterCellCallback (NULL)
{ }
inline void BaseQuery::setGoCallback ( PyObject* cb ) { _goCallback = cb; cerr << "BaseQuery::setGoCallback()" << endl; }
inline void BaseQuery::setMarkerCallback ( PyObject* cb ) { _markerCallback = cb; }
inline void BaseQuery::setRubberCallback ( PyObject* cb ) { _rubberCallback = cb; }
inline void BaseQuery::setExtensionGoCallback ( PyObject* cb ) { _extensionGoCallback = cb; }
inline void BaseQuery::setMasterCellCallback ( PyObject* cb ) { _masterCellCallback = cb; }
bool BaseQuery::hasGoCallback () const { cerr << "BaseQuery::hasGoCallback():" << _goCallback << endl; return _goCallback != NULL; }
bool BaseQuery::hasGoCallback () const { return _goCallback != NULL; }
bool BaseQuery::hasMarkerCallback () const { return _markerCallback != NULL; }
bool BaseQuery::hasRubberCallback () const { return _rubberCallback != NULL; }
bool BaseQuery::hasExtensionGoCallback () const { return _extensionGoCallback != NULL; }
@ -112,7 +85,6 @@ extern "C" {
void BaseQuery::goCallback ( Go* go )
{
cerr << "BaseQuery::goCallback():" << go << endl;
if (PyCallable_Check(_goCallback)) {
PyObject_CallFunctionObjArgs( _goCallback, _self, PyEntity_NEW(go), NULL );
}
@ -143,7 +115,7 @@ extern "C" {
}
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Query,query,function)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(BaseQuery,query,function)
// +=================================================================+
@ -153,74 +125,11 @@ extern "C" {
#if defined(__PYTHON_MODULE__)
#if 0
template< typename PySelf, typename Self, typename RType, typename... Args >
class PySetFunctor {
public:
typedef PyObject* (PySet_fp) ( PySelf*, PyObject* );
typedef RType (Self::* CppSet_fp) ( Args... );
public:
inline PySet_fp wrapper() const;
private:
static PyObject* _wrapper ( PySelf* self, PyObject* args )
{
}
private:
CppSet_fp _fp;
string _name;
};
template< typename PySelf, typename Self, typename RType, typename... Args >
inline PySetFunctor<PySelf,Self,RType,Args>::PySet_fp PySetFunctor<PySelf,Self,RType,Args>::wrapper() const
{ return _wrapper; }
#endif
// +-------------------------------------------------------------+
// | "PyQuery" Attribute Methods |
// +-------------------------------------------------------------+
#if WORK_IN_PROGRESS
static MethodDefTable<PyQuery,64> pyObjectMethods;
template< typename CppType, typename PySelf >
inline CppType* getCppObject ( PySelf* self, const string& methodName )
{
if (self._object == NULL) {
string message = "Attempt to call "+methodName+"on an unbound hurricane object.";
PyErr_SetString( ProxyError, message.c_str() );
return NULL;
}
CppType* cppObject = dynamic_cast<CppType*>(self._object);
if (cppObject == NULL) {
string message = "Invalid dynamic_cast<>() in "+methodName+" (internal error).";
PyErr_SetString( ProxyError, message.c_str() );
return NULL;
}
return cppObject;
}
template< typename CppType, typename PySelf, typename ReturnType, typename PyReturnType, int fdefindex >
PyType* accessor ( PySelf* self ) {
string methodName = pyObjectMethods.getFullMethodName(fdefindex);
trace << methodName << endl;
ReturnType* value = NULL;
try {
CppType* cppThis = getCppObject<CppType,PySelf>( self );
if (cppThis == NULL) return NULL;
}
}
#endif
static PyObject* PyQuery_getMasterCell ( PyQuery *self ) {
trace << "PyQuery.getMasterCell()" << endl;
@ -235,6 +144,54 @@ extern "C" {
}
static PyObject* PyQuery_getInstance ( PyQuery *self ) {
trace << "PyQuery.getInstance()" << endl;
Instance* instance = NULL;
HTRY
METHOD_HEAD("PyQuery.getInstance()")
instance = query->getInstance();
HCATCH
return PyInstance_Link(instance);
}
static PyObject* PyQuery_getPath ( PyQuery *self )
{
trace << "PyQuery_getPath ()" << endl;
METHOD_HEAD( "PyQuery.getPath()" )
PyPath* pyPath = PyObject_NEW( PyPath, &PyTypePath );
if (pyPath == NULL) return NULL;
HTRY
pyPath->_object = new Path ( query->getPath() );
HCATCH
return (PyObject*)pyPath;
}
static PyObject* PyQuery_getTransformation ( PyQuery *self )
{
trace << "PyQuery_getTransformation ()" << endl;
METHOD_HEAD( "PyQuery.getTransformation()" )
PyTransformation* pyTransformation = PyObject_NEW( PyTransformation, &PyTypeTransformation );
if (pyTransformation == NULL) return NULL;
HTRY
pyTransformation->_object = new Transformation ( query->getTransformation() );
HCATCH
return (PyObject*)pyTransformation;
}
static PyObject* PyQuery_setCell ( PyQuery* self, PyObject* args )
{
trace << "PyQuery.setCell()" << endl;
@ -258,6 +215,24 @@ extern "C" {
}
static PyObject* PyQuery_setFilter ( PyQuery* self, PyObject* args )
{
trace << "PyQuery.setFilter()" << endl;
METHOD_HEAD("PyQuery.setFilter()")
HTRY
int mask = 0;
if (PyArg_ParseTuple(args,"i:Query.setFilter()",&mask) ) {
query->setFilter( mask );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to Query.setFilter()." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyQuery_setArea ( PyQuery* self, PyObject* args )
{
trace << "PyQuery.setArea()" << endl;
@ -446,16 +421,14 @@ extern "C" {
{
trace << "PyQuery.new()" << endl;
Query* query = NULL;
PyQuery* pyQuery = NULL;
BaseQuery* query = NULL;
PyQuery* pyQuery = NULL;
HTRY
pyQuery = PyObject_NEW( PyQuery, &PyTypeQuery );
if (pyQuery == NULL) return NULL;
query = new BaseQuery( pyQuery );
pyQuery->_object = query;
cerr << "PyQuery_NEW(): " << (void*)pyQuery << endl;
HCATCH
return (PyObject*)pyQuery;
@ -464,7 +437,6 @@ extern "C" {
int PyQuery_Init ( PyQuery* self, PyObject* args, PyObject* kwargs )
{
cerr << "PyQuery_Init(): " << (void*)self << endl;
return 0;
}
@ -478,8 +450,16 @@ extern "C" {
PyMethodDef PyQuery_Methods[] =
{ { "getMasterCell" , (PyCFunction)PyQuery_getMasterCell , METH_NOARGS
, "Returns the master Cell currently under exploration." }
, { "getInstance" , (PyCFunction)PyQuery_getInstance , METH_NOARGS
, "Returns the Instance currently under exploration." }
, { "getPath" , (PyCFunction)PyQuery_getPath , METH_NOARGS
, "Returns the Path to the Instance (inclusive) under exploration." }
, { "getTransformation" , (PyCFunction)PyQuery_getTransformation , METH_NOARGS
, "Returns the Transformation to the master Cell under exploration." }
, { "setCell" , (PyCFunction)PyQuery_setCell , METH_VARARGS
, "Set the cell upon which perform the query." }
, { "setFilter" , (PyCFunction)PyQuery_setFilter , METH_VARARGS
, "Set what classes of objects will be took into account." }
, { "setArea" , (PyCFunction)PyQuery_setArea , METH_VARARGS
, "Set the area into which perform the query." }
, { "setTransformation" , (PyCFunction)PyQuery_setTransformation , METH_VARARGS
@ -494,9 +474,9 @@ extern "C" {
, "Set the callback function for the Rubbers." }
, { "setExtensionGoCallback", (PyCFunction)PyQuery_setExtensionGoCallback, METH_VARARGS
, "Set the callback function for the ExtensionGos." }
, { "setMasterCellCallback" , (PyCFunction)PyQuery_setMasterCellCallback, METH_VARARGS
, { "setMasterCellCallback" , (PyCFunction)PyQuery_setMasterCellCallback , METH_VARARGS
, "Set the callback function for the MasterCell." }
, { "doQuery" , (PyCFunction)PyQuery_doQuery , METH_NOARGS
, { "doQuery" , (PyCFunction)PyQuery_doQuery , METH_NOARGS
, "Perform the actual Query walk." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
@ -509,56 +489,6 @@ extern "C" {
DirectDeleteMethod(PyQuery_DeAlloc,PyQuery)
PyTypeObjectLinkPyTypeNewInit(Query)
#if WORK_IN_PROGRESS
DirectReprMethod(PyQuery_Repr, PyQuery, Query)
DirectStrMethod (PyQuery_Str, PyQuery, Query)
DirectCmpMethod (PyQuery_Cmp, IsPyQuery, PyQuery)
DirectHashMethod(PyQuery_Hash, PyQuery)
extern void PyQuery_LinkPyType ()
{
trace << "PyQuery_LinkType()" << endl;
PyTypeQuery.tp_dealloc = (destructor) PyQuery_DeAlloc;
PyTypeQuery.tp_compare = (cmpfunc) PyQuery_Cmp;
PyTypeQuery.tp_repr = (reprfunc) PyQuery_Repr;
PyTypeQuery.tp_str = (reprfunc) PyQuery_Str;
PyTypeQuery.tp_hash = (hashfunc) PyQuery_Hash;
PyTypeQuery.tp_new = (newfunc) PyQuery_NEW;
PyTypeQuery.tp_init = (initproc) PyQuery_Init;
//PyTypeQuery.tp_methods = PyQuery_Methods;
if (not pyObjectMethods.size()) {
pyObjectMethods
( "getMasterCell" , (PyCFunction)PyQuery_getMasterCell, METH_NOARGS
, "Returns the master Cell currently under exploration." )
( "setCell" , (PyCFunction)PyQuery_setCell, METH_VARARGS
, "Set the cell upon which perform the query." )
( "setArea" , (PyCFunction)PyQuery_setArea, METH_VARARGS
, "Set the area into which perform the query." )
( "setTransformation" , (PyCFunction)PyQuery_setTransformation, METH_VARARGS
, "Set the initial transformation applied to the query area." )
( "setBasicLayer" , (PyCFunction)PyQuery_setBasicLayer, METH_VARARGS
, "Set the BasicLayer on which perform the query." )
( "setGoCallback" , (PyCFunction)PyQuery_setGoCallback, METH_VARARGS
, "Set the callback function for the Gos." )
( "setMarkerCallback" , (PyCFunction)PyQuery_setMarkerCallback, METH_VARARGS
, "Set the callback function for the Markers." )
( "setRubberCallback" , (PyCFunction)PyQuery_setRubberCallback, METH_VARARGS
, "Set the callback function for the Rubbers." )
( "setExtensionGoCallback", (PyCFunction)PyQuery_setExtensionGoCallback, METH_VARARGS
, "Set the callback function for the ExtensionGos." )
( "setMasterCellCallback" , (PyCFunction)PyQuery_setMasterCellCallback, METH_VARARGS
, "Set the callback function for the MasterCell." )
( "doQuery" , (PyCFunction)PyQuery_doQuery, METH_NOARGS
, "Perform the actual Query walk." );
}
PyTypeQuery.tp_methods = pyObjectMethods.getMethods();
}
#endif
#else // End of Python Module Code Part.

View File

@ -107,6 +107,7 @@ extern "C" {
// Standart Attribute.
accessorLayerFromVoid(getBasicLayer ,PyRegularLayer,RegularLayer)
updatorFromBasicLayer(setBasicLayer ,PyRegularLayer,RegularLayer)
DBoDestroyAttribute (PyRegularLayer_destroy, PyRegularLayer)
@ -117,6 +118,8 @@ extern "C" {
PyMethodDef PyRegularLayer_Methods[] =
{ { "create" , (PyCFunction)PyRegularLayer_create , METH_VARARGS|METH_STATIC
, "Create a new RegularLayer." }
, { "getBasicLayer", (PyCFunction)PyRegularLayer_getBasicLayer, METH_NOARGS
, "Get the BasicLayer associated to this RegularLayer." }
, { "setBasicLayer", (PyCFunction)PyRegularLayer_setBasicLayer, METH_VARARGS
, "Associate a BasicLayer with this RegularLayer." }
, { "destroy" , (PyCFunction)PyRegularLayer_destroy , METH_NOARGS

View File

@ -146,7 +146,7 @@ extern "C" {
}
HCATCH
return PyLayer_Link(layer);
return PyLayer_LinkDerived(layer);
}

View File

@ -43,8 +43,8 @@ namespace Isobar {
#define IsPyDebugSession(v) ( (v)->ob_type == &PyTypeDebugSession )
#define PYUPDATESESSION(v) ( (PyDebugSession*)(v) )
#define PYUPDATESESSION_O(v) ( PY_UPDATE_SESSION(v)->_object )
#define PYDEBUGSESSION(v) ( (PyDebugSession*)(v) )
#define PYDEBUGSESSION_O(v) ( PY_UPDATE_SESSION(v)->_object )
} // extern "C".

View File

@ -120,6 +120,7 @@ extern "C" {
#define NO_ARG ""
#define BOX_ARG ":box"
#define INTV_ARG ":intv"
#define CELL_ARG ":ent"
#define POINT_ARG ":point"
#define POINTS2_ARG ":point:point"
@ -324,6 +325,23 @@ extern "C" {
}
# define accessorLayerFromVoid(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self ) \
{ \
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
\
Layer* rlayer = NULL; \
\
HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
rlayer = const_cast<Layer*>( dynamic_cast<const Layer*>(cobject->FUNC_NAME()) ); \
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_LinkDerived(rlayer); \
}
# define accessorAnyLayerFromName(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE,LAYER_TYPE) \
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
{ \
@ -382,7 +400,7 @@ extern "C" {
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_Link(rlayer); \
return PyLayer_LinkDerived(rlayer); \
}
@ -414,7 +432,7 @@ extern "C" {
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_Link(rlayer); \
return PyLayer_LinkDerived(rlayer); \
}
@ -439,7 +457,7 @@ extern "C" {
HCATCH \
\
if (rlayer == NULL) Py_RETURN_NONE; \
return PyLayer_Link(rlayer); \
return PyLayer_LinkDerived(rlayer); \
}

View File

@ -0,0 +1,56 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2014-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/isobar/PyInterval.h" |
// +-----------------------------------------------------------------+
#ifndef ISOBAR_PY_INTERVAL_H
#define ISOBAR_PY_INTERVAL_H
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/Interval.h"
namespace Isobar {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyInterval".
typedef struct {
PyObject_HEAD
Hurricane::Interval* _object;
} PyInterval;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.cpp".
extern PyTypeObject PyTypeInterval;
extern PyMethodDef PyInterval_Methods[];
extern PyObject* PyInterval_Link ( Hurricane::Interval* object );
extern void PyInterval_LinkPyType ();
#define IsPyInterval(v) ( (v)->ob_type == &PyTypeInterval )
#define PYINTERVAL(v) ( (PyInterval*)(v) )
#define PYINTERVAL_O(v) ( PYINTERVAL(v)->_object )
} // extern "C".
} // Isobar namespace.
#endif // PY_INTERVAL_H

View File

@ -1,36 +1,8 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2006-2014, All Rights Reserved
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -43,8 +15,8 @@
// +-----------------------------------------------------------------+
# ifndef __PYLAYER__
# define __PYLAYER__
# ifndef ISOBAR_PYLAYER_H
# define ISOBAR_PYLAYER_H
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/Layer.h"
@ -71,6 +43,7 @@ extern "C" {
extern PyMethodDef PyLayer_Methods[];
extern PyObject* PyLayer_Link ( Hurricane::Layer* object );
extern PyObject* PyLayer_LinkDerived ( Hurricane::Layer* object );
extern void PyLayer_LinkPyType ();
extern void PyLayer_postModuleInit ();
@ -83,4 +56,4 @@ extern "C" {
} // Isobar namespace.
# endif
#endif // ISOBAR_PYLAYER_H

View File

@ -1,36 +1,8 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2010-2014, All Rights Reserved
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -54,128 +26,33 @@ namespace Isobar {
using namespace Hurricane;
#if WORK_IN_PROGRESS
template< typename CppObject, int TableSize >
class MethodDefTable {
public:
MethodDefTable ();
PyMethodDef* getMethods ();
const PyMethodDef& operator[] ( size_t );
MethodDefTable& addMethod ( const char* fname, PyCFunction, int flags, const char* fdoc );
MethodDefTable& operator() ( const char* fname, PyCFunction, int flags, const char* fdoc );
template< typename R, typename... Ps >
MethodDefTable& addMethod ( const char* fname, PyCFunction, int flags, const char* fdoc, R(CppObject::* mfp)(Ps...) );
template< typename R, typename... Ps >
MethodDefTable& operator() ( const char* fname, PyCFunction, int flags, const char* fdoc, R(CppObject::* mfp)(Ps...) );
inline size_t size () const;
private:
size_t _size;
PyMethodDef _pyMethods [TableSize];
void* _cppMethods[TableSize];
};
template< typename CppObject, int TableSize >
size_t MethodDefTable<CppObject,TableSize>::size () const
{ return _size; }
template< typename CppObject, int TableSize >
MethodDefTable<CppObject,TableSize>::MethodDefTable ()
: _size (0)
//, _pyMethods(new PyMethodDef[TableSize+1])
{
for ( size_t i=0 ; i<TableSize+1 ; ++i ) {
_pyMethods [i].ml_name = NULL;
_pyMethods [i].ml_meth = NULL;
_pyMethods [i].ml_flags = 0;
_pyMethods [i].ml_doc = NULL;
_cppMethods[i] = NULL;
}
}
template< typename CppObject, int TableSize >
PyMethodDef* MethodDefTable<CppObject,TableSize>::getMethods ()
{ return _pyMethods; }
template< typename CppObject, int TableSize >
const PyMethodDef& MethodDefTable<CppObject,TableSize>::operator[] ( size_t i )
{ return _pyMethods[i]; }
template< typename CppObject, int TableSize >
MethodDefTable<CppObject,TableSize>& MethodDefTable<CppObject,TableSize>::addMethod ( const char* fname, PyCFunction fp, int flags, const char* fdoc )
{
_pyMethods [_size].ml_name = fname;
_pyMethods [_size].ml_meth = fp;
_pyMethods [_size].ml_flags = flags;
_pyMethods [_size].ml_doc = fdoc;
_cppMethods[_size] = NULL;
++_size;
return *this;
}
template< typename CppObject, int TableSize >
template< typename R, typename... Ps >
MethodDefTable<CppObject,TableSize>& MethodDefTable<CppObject,TableSize>::addMethod
( const char* fname, PyCFunction fp, int flags, const char* fdoc, R(CppObject::* mfp)(Ps...) )
{
_pyMethods[_size].ml_name = fname;
_pyMethods[_size].ml_meth = fp;
_pyMethods[_size].ml_flags = flags;
_pyMethods[_size].ml_doc = fdoc;
_cppMethods[_size] = (void*)mfp;
++_size;
return *this;
}
template< typename CppObject, int TableSize >
MethodDefTable<CppObject,TableSize>& MethodDefTable<CppObject,TableSize>::operator() ( const char* fname, PyCFunction fp, int flags, const char* fdoc )
{ return addMethod( fname, fp, flags, fdoc ); }
template< typename CppObject, int TableSize >
template< typename R, typename... Ps >
MethodDefTable<CppObject,TableSize>& MethodDefTable<CppObject,TableSize>::operator()
( const char* fname, PyCFunction fp, int flags, const char* fdoc, R(CppObject::* mfp)(Ps...) )
{ return addMethod( fname, fp, flags, fdoc, mfp ); }
#endif
extern "C" {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyQuery".
typedef struct {
PyObject_HEAD
Query* _object;
} PyQuery;
typedef struct {
PyObject_HEAD
Query* _object;
} PyQuery;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.ccp".
extern PyTypeObject PyTypeQuery;
extern PyMethodDef PyQuery_Methods[];
extern PyTypeObject PyTypeQuery;
extern PyMethodDef PyQuery_Methods[];
extern PyObject* PyQuery_Link ( Hurricane::Query* object );
extern void PyQuery_LinkPyType ();
extern void PyQuery_postModuleInit ();
extern PyObject* PyQuery_Link ( Query* object );
extern void PyQuery_LinkPyType ();
extern void PyQuery_postModuleInit ();
#define IsPyQuery(v) ( (v)->ob_type == &PyTypeQuery )
#define PYQUERY(v) ( (PyQuery*)(v) )
#define PYQUERY_O(v) ( PYQUERY(v)->_object )
} // extern "C".
} // extern "C".
} // Isobar namespace.

View File

@ -1,30 +1,21 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2010-2014, All Rights Reserved
//
// x-----------------------------------------------------------------x
// | |
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./PyUpdateSession.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// | C++ Header : "./hurrican/isobar/PyUpdateSession.h" |
// +-----------------------------------------------------------------+
# ifndef __PY_UPDATE_SESSION__
# define __PY_UPDATE_SESSION__
#ifndef ISOBAR_PY_UPDATE_SESSION
#define ISOBAR_PY_UPDATE_SESSION
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/UpdateSession.h"
@ -32,26 +23,23 @@
namespace Isobar {
extern "C" {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyUpdateSession".
typedef struct {
PyObject_HEAD
} PyUpdateSession;
typedef struct {
PyObject_HEAD
} PyUpdateSession;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.cpp".
extern PyTypeObject PyTypeUpdateSession;
extern PyMethodDef PyUpdateSession_Methods[];
extern PyTypeObject PyTypeUpdateSession;
extern PyMethodDef PyUpdateSession_Methods[];
extern void PyUpdateSession_LinkPyType ();
extern void PyUpdateSession_LinkPyType ();
#define IsPyUpdateSession(v) ( (v)->ob_type == &PyTypeUpdateSession )
@ -59,13 +47,8 @@ extern "C" {
#define PYUPDATESESSION_O(v) ( PY_UPDATE_SESSION(v)->_object )
} // End of extern "C".
} // extern "C".
} // Isobar namespace.
} // End of Isobar namespace.
# endif
#endif

View File

@ -1,6 +1,21 @@
#!/usr/bin/env python
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2014-2014, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | U n i c o r n - M a i n G U I |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./init/unicornInit.py" |
# +-----------------------------------------------------------------+
try:
import traceback
import sys
import os.path
from helpers import ErrorMessage
@ -49,16 +64,24 @@ def unicornConfigure ( **kw ):
editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu )
for pluginFile in os.listdir( pluginsDir ):
if pluginFile == "__init__.py": continue
if not pluginFile.endswith('.py'): continue
moduleName = os.path.basename(pluginFile)[:-3]
module = __import__( moduleName, globals(), locals(), moduleName )
if not module.__dict__.has_key('unicornHook'):
print WarningMessage( 'Module <%s> do not provides the unicornHook() method, skipped.' \
% moduleName )
continue
try:
module = __import__( moduleName, globals(), locals(), moduleName )
module.__dict__['unicornHook']( editor )
if not module.__dict__.has_key('unicornHook'):
print WarningMessage( 'Plugin <%s> do not provides the unicornHook() method, skipped.' \
% moduleName )
continue
module.__dict__['unicornHook']( **kw )
except ErrorMessage, e:
print e
except Exception, e:
print ErrorMessage( 3, 'Plugin <%s> cannot be loaded, see message below:' % moduleName )
print e
traceback.print_tb(sys.exc_info()[2])
return