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:
parent
d0d045b55b
commit
25e82fc701
|
@ -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 )
|
||||
)
|
|
@ -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) ]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 ) )
|
|
@ -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
|
|
@ -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
|
|
@ -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 (" ")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -103,7 +103,7 @@ extern "C" {
|
|||
layer = const_cast<Layer*>(component->getLayer ());
|
||||
HCATCH
|
||||
|
||||
return PyLayer_Link ( layer );
|
||||
return PyLayer_LinkDerived ( layer );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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".
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -146,7 +146,7 @@ extern "C" {
|
|||
}
|
||||
HCATCH
|
||||
|
||||
return PyLayer_Link(layer);
|
||||
return PyLayer_LinkDerived(layer);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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); \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue