402 lines
25 KiB
C++
402 lines
25 KiB
C++
// -*- C++ -*-
|
|
//
|
|
// This file is part of the Coriolis Software.
|
|
// Copyright (c) UPMC 2006-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++ Module : "./PyLayer.cpp" |
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
#include "hurricane/isobar/PyTechnology.h"
|
|
#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"
|
|
|
|
|
|
namespace Isobar {
|
|
|
|
using namespace Hurricane;
|
|
|
|
extern "C" {
|
|
|
|
|
|
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Layer,layer,function)
|
|
|
|
|
|
// +=================================================================+
|
|
// | "PyLayer" Python Module Code Part |
|
|
// +=================================================================+
|
|
|
|
#if defined(__PYTHON_MODULE__)
|
|
|
|
|
|
// +-------------------------------------------------------------+
|
|
// | "PyLayer" Attribute Methods |
|
|
// +-------------------------------------------------------------+
|
|
|
|
|
|
# define accessorDbuFromOptBasicLayer(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
|
{ \
|
|
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
|
\
|
|
DbU::Unit rvalue = 0; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
\
|
|
PyObject* arg0 = NULL; \
|
|
\
|
|
__cs.init (#SELF_TYPE"."#FUNC_NAME"()"); \
|
|
if (PyArg_ParseTuple( args, "|O&:"#SELF_TYPE"."#FUNC_NAME"()", Converter, &arg0)) { \
|
|
if ( __cs.getObjectIds() == ":basiclayer" ) \
|
|
rvalue = cobject->FUNC_NAME( PYBASICLAYER_O(arg0) ); \
|
|
else if ( __cs.getObjectIds() == "" ) \
|
|
rvalue = cobject->FUNC_NAME(); \
|
|
else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, "invalid parameter type for "#SELF_TYPE"."#FUNC_NAME"()." ); \
|
|
return NULL; \
|
|
} \
|
|
} else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
|
|
return NULL; \
|
|
} \
|
|
HCATCH \
|
|
\
|
|
return Py_BuildValue("l",rvalue); \
|
|
}
|
|
|
|
|
|
# define accessorLayerFromLayer(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
|
{ \
|
|
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
|
\
|
|
Layer* rlayer = 0; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
\
|
|
PyObject* arg0 = NULL; \
|
|
\
|
|
if (PyArg_ParseTuple( args, "O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0)) { \
|
|
Layer* argLayer = PYLAYER_O(arg0); \
|
|
if (argLayer == NULL) { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, #SELF_TYPE"."#FUNC_NAME"(): Parameter is not of Layer type" ); \
|
|
return NULL; \
|
|
} \
|
|
rlayer = const_cast<Layer*>(cobject->FUNC_NAME( argLayer )); \
|
|
} else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, #SELF_TYPE"."#FUNC_NAME"(): Parameter is not of Layer type" ); \
|
|
return NULL; \
|
|
} \
|
|
HCATCH \
|
|
\
|
|
return PyLayer_LinkDerived(rlayer); \
|
|
}
|
|
|
|
|
|
# define accessorMaskFromVoid(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::Mask mask = 0; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
mask = cobject->FUNC_NAME(); \
|
|
HCATCH \
|
|
\
|
|
return PyLayerMask_Link(mask); \
|
|
}
|
|
|
|
|
|
# define accessorLayerFromOptBool(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
|
{ \
|
|
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
|
\
|
|
Layer* rlayer = NULL; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
\
|
|
PyObject* arg0 = NULL; \
|
|
bool useWorking = true; \
|
|
\
|
|
if (PyArg_ParseTuple( args, "|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0)) { \
|
|
if (arg0 != NULL) { \
|
|
useWorking = PyObject_IsTrue(arg0); \
|
|
} \
|
|
} else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
|
|
return NULL; \
|
|
} \
|
|
rlayer = const_cast<SELF_TYPE*>(cobject->FUNC_NAME(useWorking)); \
|
|
HCATCH \
|
|
\
|
|
if (rlayer == NULL) Py_RETURN_NONE; \
|
|
return PyLayer_LinkDerived(rlayer); \
|
|
}
|
|
|
|
|
|
# define predicateFromVoid(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; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
if (cobject->FUNC_NAME()) Py_RETURN_TRUE; \
|
|
HCATCH \
|
|
\
|
|
Py_RETURN_FALSE; \
|
|
}
|
|
|
|
|
|
# define updatorFromDbu(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
|
{ \
|
|
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
\
|
|
long dimension = 0; \
|
|
\
|
|
if (PyArg_ParseTuple( args, "l:"#SELF_TYPE"."#FUNC_NAME"()", &dimension)) { \
|
|
cobject->FUNC_NAME( dimension ); \
|
|
} else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, #SELF_TYPE"."#FUNC_NAME"(): Parameter is not of long (DbU) type" ); \
|
|
return NULL; \
|
|
} \
|
|
HCATCH \
|
|
\
|
|
Py_RETURN_NONE; \
|
|
}
|
|
|
|
|
|
# define updatorFromBasicLayerDbu(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
|
{ \
|
|
trace << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
|
\
|
|
HTRY \
|
|
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
|
\
|
|
PyObject* pyBasicLayer = NULL; \
|
|
long dimension = 0; \
|
|
\
|
|
if (PyArg_ParseTuple( args, "Ol:"#SELF_TYPE"."#FUNC_NAME"()", &pyBasicLayer, &dimension)) { \
|
|
BasicLayer* layer = PYBASICLAYER_O(pyBasicLayer); \
|
|
if (layer == NULL) { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, #SELF_TYPE"."#FUNC_NAME"(): First parameter is not of BasicLayer type" ); \
|
|
return NULL; \
|
|
} \
|
|
cobject->FUNC_NAME( layer, dimension ); \
|
|
} else { \
|
|
PyErr_SetString ( ConstructorError \
|
|
, #SELF_TYPE"."#FUNC_NAME"(): Bad parameters types or numbers." ); \
|
|
return NULL; \
|
|
} \
|
|
HCATCH \
|
|
\
|
|
Py_RETURN_NONE; \
|
|
}
|
|
|
|
|
|
static PyObject* PyLayer_getTechnology ( PyLayer *self ) {
|
|
trace << "PyLayer_getTechnology ()" << endl;
|
|
|
|
Technology* techno = NULL;
|
|
|
|
HTRY
|
|
METHOD_HEAD ( "Layer.getTechnology()" )
|
|
techno = layer->getTechnology ();
|
|
HCATCH
|
|
|
|
return PyTechnology_Link(techno);
|
|
}
|
|
|
|
|
|
GetNameMethod (Layer, layer)
|
|
predicateFromLayer ( above ,PyLayer,Layer)
|
|
predicateFromLayer ( below ,PyLayer,Layer)
|
|
predicateFromLayer ( contains ,PyLayer,Layer)
|
|
predicateFromLayer ( intersect ,PyLayer,Layer)
|
|
predicateFromVoid ( isWorking ,PyLayer,Layer)
|
|
accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer)
|
|
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
|
|
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
|
|
accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer)
|
|
accessorMaskFromVoid ( getMask ,PyLayer,Layer)
|
|
accessorMaskFromVoid ( getExtractMask ,PyLayer,Layer)
|
|
accessorLayerFromVoid ( getBlockageLayer ,PyLayer,Layer)
|
|
accessorLayerFromVoid ( getTop ,PyLayer,Layer)
|
|
accessorLayerFromVoid ( getBottom ,PyLayer,Layer)
|
|
accessorLayerFromLayer ( getOpposite ,PyLayer,Layer)
|
|
accessorLayerFromOptBool ( getMetalAbove ,PyLayer,Layer)
|
|
accessorLayerFromOptBool ( getMetalBelow ,PyLayer,Layer)
|
|
accessorLayerFromOptBool ( getCutAbove ,PyLayer,Layer)
|
|
accessorLayerFromOptBool ( getCutBelow ,PyLayer,Layer)
|
|
DirectGetLongAttribute (PyLayer_getMinimalSize ,getMinimalSize ,PyLayer,Layer)
|
|
DirectGetLongAttribute (PyLayer_getMinimalSpacing,getMinimalSpacing,PyLayer,Layer)
|
|
|
|
SetNameMethod(Layer, layer)
|
|
updatorFromDbu (setMinimalSize ,PyLayer,Layer)
|
|
updatorFromDbu (setMinimalSpacing,PyLayer,Layer)
|
|
updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer)
|
|
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
|
|
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
|
|
|
|
// Standart destroy (Attribute).
|
|
DBoDestroyAttribute(PyLayer_destroy, PyLayer)
|
|
|
|
|
|
PyMethodDef PyLayer_Methods[] =
|
|
{ { "getTechnology" , (PyCFunction)PyLayer_getTechnology , METH_NOARGS
|
|
, "Returns the technology owning the layer." }
|
|
, { "getName" , (PyCFunction)PyLayer_getName , METH_NOARGS
|
|
, "Returns the name of the layer." }
|
|
, { "getMask" , (PyCFunction)PyLayer_getMask , METH_NOARGS
|
|
, "Returns the mask (bits) of the layer." }
|
|
, { "getExtractMask" , (PyCFunction)PyLayer_getExtractMask , METH_NOARGS
|
|
, "Returns the extract mask of the layer (for GDSII)." }
|
|
, { "getMinimalSize" , (PyCFunction)PyLayer_getMinimalSize , METH_NOARGS
|
|
, "Returns the minimum width allowed for the layer." }
|
|
, { "getMinimalSpacing" , (PyCFunction)PyLayer_getMinimalSpacing , METH_NOARGS
|
|
, "Returns the spacing allowed for the layer (edge to edge)." }
|
|
, { "getBasicLayers" , (PyCFunction)PyLayer_getBasicLayers , METH_NOARGS
|
|
, "Returns the collection of BasicLayer the Layer is built upon." }
|
|
, { "getBlockageLayer" , (PyCFunction)PyLayer_getBlockageLayer , METH_NOARGS
|
|
, "Returns the associated connector layer." }
|
|
, { "getTop" , (PyCFunction)PyLayer_getTop , METH_NOARGS
|
|
, "Returns the top layer (in case of a muti-layer)." }
|
|
, { "getBottom" , (PyCFunction)PyLayer_getBottom , METH_NOARGS
|
|
, "Returns the bottom layer (in case of a muti-layer)." }
|
|
, { "getOpposite" , (PyCFunction)PyLayer_getOpposite , METH_VARARGS
|
|
, "Returns the layer opposite the one given." }
|
|
, { "getMetalAbove" , (PyCFunction)PyLayer_getMetalAbove , METH_VARARGS
|
|
, "Returns the metal layer above this one." }
|
|
, { "getMetalBelow" , (PyCFunction)PyLayer_getMetalBelow , METH_VARARGS
|
|
, "Returns the metal layer below this one." }
|
|
, { "getCutAbove" , (PyCFunction)PyLayer_getCutAbove , METH_VARARGS
|
|
, "Returns the cut layer above this one." }
|
|
, { "getCutBelow" , (PyCFunction)PyLayer_getCutBelow , METH_VARARGS
|
|
, "Returns the cut layer below this one." }
|
|
, { "getEnclosure" , (PyCFunction)PyLayer_getEnclosure , METH_VARARGS
|
|
, "Returns the enclosure (global or for one BasicLayer)." }
|
|
, { "getExtentionCap" , (PyCFunction)PyLayer_getExtentionCap , METH_VARARGS
|
|
, "Returns the extention cap (global or for one BasicLayer)." }
|
|
, { "getExtentionWidth" , (PyCFunction)PyLayer_getExtentionWidth , METH_VARARGS
|
|
, "Returns the extention width (global or for one BasicLayer)." }
|
|
, { "above" , (PyCFunction)PyLayer_above , METH_VARARGS
|
|
, "Tells if the layer is above the one passed as argument." }
|
|
, { "below" , (PyCFunction)PyLayer_below , METH_VARARGS
|
|
, "Tells if the layer is below the one passed as argument." }
|
|
, { "contains" , (PyCFunction)PyLayer_contains , METH_VARARGS
|
|
, "Tells if the layer fully contains the one passed as argument." }
|
|
, { "intersect" , (PyCFunction)PyLayer_intersect , METH_VARARGS
|
|
, "Tells if the layer share some BasicLayer with the one passed as argument." }
|
|
, { "isWorking" , (PyCFunction)PyLayer_isWorking , METH_NOARGS
|
|
, "Tells if the layer is the working one for this BasicLayer." }
|
|
, { "setName" , (PyCFunction)PyLayer_setName , METH_VARARGS
|
|
, "Allows to change the layer name." }
|
|
, { "setWorking" , (PyCFunction)PyLayer_setName , METH_VARARGS
|
|
, "Sets the layer as the working one." }
|
|
, { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS
|
|
, "Sets the layer minimal size (width)." }
|
|
, { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS
|
|
, "Sets the layer minimal spacing (edge to edge)." }
|
|
, { "setEnclosure" , (PyCFunction)PyLayer_setEnclosure , METH_VARARGS
|
|
, "Sets the enclosure for the given BasicLayer sub-component." }
|
|
, { "setExtentionCap" , (PyCFunction)PyLayer_setExtentionCap , METH_VARARGS
|
|
, "Sets the extention cap for the given BasiLayer sub-component." }
|
|
, { "setExtentionWidth" , (PyCFunction)PyLayer_setExtentionWidth , METH_VARARGS
|
|
, "Sets the extention width for the given BasiLayer sub-component." }
|
|
, { "destroy" , (PyCFunction)PyLayer_destroy , METH_NOARGS
|
|
, "Destroy associated hurricane object The python object remains." }
|
|
, {NULL, NULL, 0, NULL} /* sentinel */
|
|
};
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// PyLayer Type Methods.
|
|
|
|
|
|
DBoDeleteMethod(Layer)
|
|
PyTypeObjectLinkPyType(Layer)
|
|
|
|
|
|
#else // End of Python Module Code Part.
|
|
|
|
|
|
// +=================================================================+
|
|
// | "PyLayer" Shared Library Code Part |
|
|
// +=================================================================+
|
|
|
|
// Link/Creation Method.
|
|
DBoLinkCreateMethod(Layer)
|
|
|
|
PyTypeRootObjectDefinitions(Layer)
|
|
|
|
|
|
extern void PyLayer_postModuleInit ()
|
|
{
|
|
PyDict_SetItemString ( PyTypeLayer.tp_dict, "Mask", (PyObject*)&PyTypeLayerMask );
|
|
}
|
|
|
|
|
|
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".
|
|
|
|
} // Isobar namespace.
|