Cleaner support for real technologies (Hurricane, CRL Core configuration).
* Change: In Hurricane::Technology, in all the layer connexity methods (getLayers(), getMetalAbove(), getCutAbove(), getViaBetween(), ...) the "useWorking" parameter is replaced by a more accurate "useSymbolic". BEHAVIOR CHANGE: formerly, if a symbolic layer was requested, and none was found, NULL was returned. Now, if the symbolic layer is not found, we try to return the associated real one (same layer mask, but not flagged as symbolic, and usually with a lowercase name). All thoses changes have been propagated to Python bindings. * Change: In Hurricane::BasicLayer and derived classes, rename the "isWorking" attribute into "isSymbolic" (to match the technology renaming). * Change: In Hurricane::Cell::flattenNets(), ignore power, ground and blockage nets for the flatten. * Change: In CRL Core, in coriolisInit.py and Technology.py helpers, rename the tables describing the technology as follow: - symbolicLayersTable --> compositeLayersTable - workingLayersTable --> symbolicLayersTable - symbolicRulesTable --> layersExtensionsTable This is to give the table names a more clearer semantic after merging real technologies configurations (testbench AMS c35b4). In particular, we need to define a composite layer for the real VIAs, and not only the symbolic ones. And with correct enclosures expressed in real dimensions (microns).
This commit is contained in:
parent
24d5e9f172
commit
24d8fe5957
|
@ -9,8 +9,8 @@ from Hurricane import DbU
|
|||
# Provides standard settings for:
|
||||
# - <viewerConfig>
|
||||
# - <realLayersTable>
|
||||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
# - <workingLayersTable>
|
||||
|
||||
execfile( helpers.sysConfDir+'/common/technology.conf' )
|
||||
|
||||
|
@ -29,14 +29,16 @@ technoConfig = { 'name' : 'scn6m_deep'
|
|||
}
|
||||
|
||||
|
||||
# Format of <symbolicRulesTable>:
|
||||
# Format of <layersExtensionsTable>:
|
||||
# Each entry is a pair of (string, value).
|
||||
# * string: a synthetic way to designate the symbolic layer on which
|
||||
# it applies, an optional real layer in case where there is
|
||||
# more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value expressed in lambda.
|
||||
# * string: a synthetic way to designate the real or symbolic layer on
|
||||
# which it applies, an optional sub layer (BasicLayer) in case
|
||||
# where there is more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value. If the main layer is symbolic it
|
||||
# must be expressed in lambda, if it is for a real layers it
|
||||
# must be expressed in microns.
|
||||
|
||||
symbolicRulesTable = \
|
||||
layersExtensionsTable = \
|
||||
( ('NWELL.nWell.extention.cap' , 4.0)
|
||||
, ('PWELL.pWell.extention.cap' , 4.0)
|
||||
|
||||
|
@ -94,7 +96,7 @@ symbolicRulesTable = \
|
|||
, ('POLY2.minimum.width' , 2.0)
|
||||
, ('POLY2.poly2.extention.cap' , 2.0)
|
||||
|
||||
# Routing Layers.
|
||||
# Routing Layers (symbolic).
|
||||
, ('METAL1.minimum.width' , 2.0)
|
||||
, ('METAL1.metal1.extention.cap' , 2.0)
|
||||
, ('METAL1.metal1.extention.width' , 0.5)
|
||||
|
@ -113,7 +115,7 @@ symbolicRulesTable = \
|
|||
#, ('METAL8.minimum.width' , 2.0)
|
||||
#, ('METAL8.metal8.extention.cap' , 2.5)
|
||||
|
||||
# Blockages.
|
||||
# Blockages (symbolic).
|
||||
, ('BLOCKAGE1.minimum.width' , 3.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.cap' , 2.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.width', 0.5)
|
||||
|
@ -132,7 +134,7 @@ symbolicRulesTable = \
|
|||
#, ('BLOCKAGE8.minimum.width' , 2.0)
|
||||
#, ('BLOCKAGE8.blockage6.extention.cap' , 4.0)
|
||||
|
||||
# Contacts (i.e. Active <--> Metal).
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
, ('CONT_BODY_N.minimum.side' , 2.0)
|
||||
, ('CONT_BODY_N.nWell.enclosure' , 4.0)
|
||||
, ('CONT_BODY_N.nImplant.enclosure' , 3.5)
|
||||
|
@ -159,7 +161,7 @@ symbolicRulesTable = \
|
|||
, ('CONT_POLY.poly.enclosure' , 2.0)
|
||||
, ('CONT_POLY.metal1.enclosure' , 1.0)
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal).
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
, ('VIA12.minimum.side' , 3.0)
|
||||
, ('VIA12.metal1.enclosure' , 1.0)
|
||||
, ('VIA12.metal2.enclosure' , 1.0)
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
# Provides standard settings for:
|
||||
# - <viewerConfig>
|
||||
# - <realLayersTable>
|
||||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
# - <workingLayersTable>
|
||||
|
||||
from Hurricane import DbU
|
||||
|
||||
|
@ -22,13 +22,16 @@ technoConfig = { 'name' : 'freepdk_45'
|
|||
}
|
||||
|
||||
|
||||
# Format of <symbolicRulesTable>:
|
||||
# Format of <layersExtensionsTable>:
|
||||
# Each entry is a pair of (string, value).
|
||||
# * string: a synthetic way to designate the symbolic layer on which
|
||||
# it applies, an optional real layer in case where there is
|
||||
# more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value expressed in lambda.
|
||||
symbolicRulesTable = \
|
||||
# * string: a synthetic way to designate the real or symbolic layer on
|
||||
# which it applies, an optional sub layer (BasicLayer) in case
|
||||
# where there is more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value. If the main layer is symbolic it
|
||||
# must be expressed in lambda, if it is for a real layers it
|
||||
# must be expressed in microns.
|
||||
|
||||
layersExtensionsTable = \
|
||||
( ('NWELL.nWell.extention.cap' , 0.0)
|
||||
, ('PWELL.pWell.extention.cap' , 0.0)
|
||||
|
||||
|
@ -82,7 +85,7 @@ symbolicRulesTable = \
|
|||
, ('POLY2.minimum.width' , 1.0)
|
||||
, ('POLY2.poly.extention.cap' , 0.5)
|
||||
|
||||
# Routing Layers.
|
||||
# Routing Layers (symbolic).
|
||||
, ('METAL1.minimum.width' , 1.0)
|
||||
, ('METAL1.metal1.extention.cap' , 0.5)
|
||||
, ('METAL2.minimum.width' , 1.0)
|
||||
|
@ -104,7 +107,7 @@ symbolicRulesTable = \
|
|||
, ('METAL10.minimum.width' , 2.0)
|
||||
, ('METAL10.metal10.extention.cap' , 1.0)
|
||||
|
||||
# Contacts (i.e. Active <--> Metal).
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
, ('CONT_BODY_N.minimum.side' , 1.0)
|
||||
, ('CONT_BODY_N.nWell.enclosure' , 1.5)
|
||||
, ('CONT_BODY_N.nImplant.enclosure' , 1.5)
|
||||
|
@ -131,7 +134,7 @@ symbolicRulesTable = \
|
|||
, ('CONT_POLY.poly.enclosure' , 0.5)
|
||||
, ('CONT_POLY.metal1.enclosure' , 0.5)
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal).
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
, ('VIA12.minimum.side' , 1.0)
|
||||
, ('VIA12.metal1.enclosure' , 0.5)
|
||||
, ('VIA12.metal2.enclosure' , 0.5)
|
||||
|
@ -160,7 +163,7 @@ symbolicRulesTable = \
|
|||
, ('VIA910.metal9.enclosure' , 0.5)
|
||||
, ('VIA910.metal10.enclosure' , 0.5)
|
||||
|
||||
# Blockages.
|
||||
# Blockages (symbolic).
|
||||
, ('BLOCKAGE1.minimum.width' , 1.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
|
||||
, ('BLOCKAGE2.minimum.width' , 2.0)
|
||||
|
|
|
@ -82,14 +82,14 @@ realLayersTable = \
|
|||
)
|
||||
|
||||
|
||||
# Format of <symbolicLayersTable>:
|
||||
# Format of <compositeLayersTable>:
|
||||
# The length of the list of real layers depends on the type.
|
||||
# In some case, the last of the list may be optional, it must be
|
||||
# sets to None and not left empty.
|
||||
#
|
||||
# ('SYMB_LAYER' , Type , (LIST_OF_REAL_LAYERS) )
|
||||
|
||||
symbolicLayersTable = \
|
||||
compositeLayersTable = \
|
||||
( ('NWELL' , TypeRegular , ('nWell' ,))
|
||||
, ('PWELL' , TypeRegular , ('pWell' ,))
|
||||
, ('NTIE' , TypeDiffusion , ('nImplant' , 'active', 'nWell'))
|
||||
|
@ -118,6 +118,17 @@ symbolicLayersTable = \
|
|||
, ('CONT_DIF_N' , TypeContact , ('nImplant' , 'active', 'cut0', 'metal1', None ))
|
||||
, ('CONT_DIF_P' , TypeContact , ('pImplant' , 'active', 'cut0', 'metal1', None ))
|
||||
, ('CONT_POLY' , TypeVia , ( 'poly' , 'cut0', 'metal1' ))
|
||||
# VIAs for real technologies.
|
||||
, ('via12' , TypeVia , ( 'metal1', 'cut1', 'metal2' ))
|
||||
, ('via23' , TypeVia , ( 'metal2', 'cut2', 'metal3' ))
|
||||
, ('via34' , TypeVia , ( 'metal3', 'cut3', 'metal4' ))
|
||||
, ('via45' , TypeVia , ( 'metal4', 'cut4', 'metal5' ))
|
||||
, ('via56' , TypeVia , ( 'metal5', 'cut5', 'metal6' ))
|
||||
, ('via67' , TypeVia , ( 'metal6', 'cut6', 'metal7' ))
|
||||
, ('via78' , TypeVia , ( 'metal7', 'cut7', 'metal8' ))
|
||||
, ('via89' , TypeVia , ( 'metal8', 'cut8', 'metal9' ))
|
||||
, ('via910' , TypeVia , ( 'metal9', 'cut9', 'metal10'))
|
||||
# VIAs for symbolic technologies.
|
||||
, ('VIA12' , TypeVia , ( 'metal1', 'cut1', 'metal2' ))
|
||||
, ('VIA23' , TypeVia , ( 'metal2', 'cut2', 'metal3' ))
|
||||
, ('VIA23cap' , TypeVia , ( 'metcap', 'cut2', 'metal3' ))
|
||||
|
@ -142,12 +153,11 @@ symbolicLayersTable = \
|
|||
)
|
||||
|
||||
|
||||
# Format of <workingLayersTable>:
|
||||
# This is a simple list of Real & Symbolic layers.
|
||||
# Format of <symbolicLayersTable>:
|
||||
# This is a simple list of Symbolic layers.
|
||||
|
||||
workingLayersTable = \
|
||||
[ 'cut0', 'cut1' , 'cut2' , 'cut3' , 'cut4' , 'cut5' , 'cut6' , 'cut7' , 'cut8' , 'cut9'
|
||||
, 'POLY', 'POLY2'
|
||||
symbolicLayersTable = \
|
||||
[ 'POLY', 'POLY2'
|
||||
, 'METAL1' , 'METAL2' , 'METAL3' , 'METAL4' , 'METAL5' , 'METAL6' , 'METAL7' , 'METAL8' , 'METAL9' , 'METAL10'
|
||||
, 'BLOCKAGE1', 'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4', 'BLOCKAGE5', 'BLOCKAGE6', 'BLOCKAGE7', 'BLOCKAGE8', 'BLOCKAGE9', 'BLOCKAGE10'
|
||||
, 'VIA12' , 'VIA23' , 'VIA34' , 'VIA45' , 'VIA56' , 'VIA67' , 'VIA78' , 'VIA89' , 'VIA910'
|
||||
|
|
|
@ -9,8 +9,8 @@ from Hurricane import DbU
|
|||
# Provides standard settings for:
|
||||
# - <viewerConfig>
|
||||
# - <realLayersTable>
|
||||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
# - <workingLayersTable>
|
||||
|
||||
execfile( helpers.sysConfDir+'/common/technology.conf' )
|
||||
|
||||
|
@ -22,13 +22,16 @@ technoConfig = { 'name' : 'hcmos9gp'
|
|||
}
|
||||
|
||||
|
||||
# Format of <symbolicRulesTable>:
|
||||
# Format of <layersExtensionsTable>:
|
||||
# Each entry is a pair of (string, value).
|
||||
# * string: a synthetic way to designate the symbolic layer on which
|
||||
# it applies, an optional real layer in case where there is
|
||||
# more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value expressed in lambda.
|
||||
symbolicRulesTable = \
|
||||
# * string: a synthetic way to designate the real or symbolic layer on
|
||||
# which it applies, an optional sub layer (BasicLayer) in case
|
||||
# where there is more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value. If the main layer is symbolic it
|
||||
# must be expressed in lambda, if it is for a real layers it
|
||||
# must be expressed in microns.
|
||||
|
||||
layersExtensionsTable = \
|
||||
( ('NWELL.nWell.extention.cap' , 0.0)
|
||||
, ('PWELL.pWell.extention.cap' , 0.0)
|
||||
|
||||
|
@ -100,7 +103,7 @@ symbolicRulesTable = \
|
|||
, ('METAL8.minimum.width' , 2.0)
|
||||
, ('METAL8.metal6.extention.cap' , 1.0)
|
||||
|
||||
# Contacts (i.e. Active <--> Metal).
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
, ('CONT_BODY_N.minimum.side' , 1.0)
|
||||
, ('CONT_BODY_N.nWell.enclosure' , 1.5)
|
||||
, ('CONT_BODY_N.nImplant.enclosure' , 1.5)
|
||||
|
@ -127,7 +130,7 @@ symbolicRulesTable = \
|
|||
, ('CONT_POLY.poly.enclosure' , 0.5)
|
||||
, ('CONT_POLY.metal1.enclosure' , 0.5)
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal).
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
, ('VIA12.minimum.side' , 1.0)
|
||||
, ('VIA12.metal1.enclosure' , 0.5)
|
||||
, ('VIA12.metal2.enclosure' , 0.5)
|
||||
|
@ -150,7 +153,7 @@ symbolicRulesTable = \
|
|||
, ('VIA78.metal7.enclosure' , 0.5)
|
||||
, ('VIA78.metal8.enclosure' , 0.5)
|
||||
|
||||
# Blockages.
|
||||
# Blockages (symbolic).
|
||||
, ('BLOCKAGE1.minimum.width' , 1.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
|
||||
, ('BLOCKAGE2.minimum.width' , 2.0)
|
||||
|
|
|
@ -6,8 +6,8 @@ from Hurricane import DbU
|
|||
# Provides standard settings for:
|
||||
# - <viewerConfig>
|
||||
# - <realLayersTable>
|
||||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
# - <workingLayersTable>
|
||||
|
||||
execfile( helpers.sysConfDir+'/common/technology.conf' )
|
||||
|
||||
|
@ -19,13 +19,16 @@ technoConfig = { 'name' : 'hcmos9gp'
|
|||
}
|
||||
|
||||
|
||||
# Format of <symbolicRulesTable>:
|
||||
# Format of <layersExtensionsTable>:
|
||||
# Each entry is a pair of (string, value).
|
||||
# * string: a synthetic way to designate the symbolic layer on which
|
||||
# it applies, an optional real layer in case where there is
|
||||
# more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value expressed in lambda.
|
||||
symbolicRulesTable = \
|
||||
# * string: a synthetic way to designate the real or symbolic layer on
|
||||
# which it applies, an optional sub layer (BasicLayer) in case
|
||||
# where there is more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value. If the main layer is symbolic it
|
||||
# must be expressed in lambda, if it is for a real layers it
|
||||
# must be expressed in microns.
|
||||
|
||||
layersExtensionsTable = \
|
||||
( ('NWELL.nWell.extention.cap' , 0.0)
|
||||
, ('PWELL.pWell.extention.cap' , 0.0)
|
||||
|
||||
|
@ -79,7 +82,7 @@ symbolicRulesTable = \
|
|||
, ('POLY2.minimum.width' , 1.0)
|
||||
, ('POLY2.poly.extention.cap' , 0.5)
|
||||
|
||||
# Routing Layers.
|
||||
# Routing Layers (symbolic).
|
||||
, ('METAL1.minimum.width' , 1.0)
|
||||
, ('METAL1.metal1.extention.cap' , 0.5)
|
||||
, ('METAL2.minimum.width' , 1.0)
|
||||
|
@ -97,7 +100,7 @@ symbolicRulesTable = \
|
|||
, ('METAL8.minimum.width' , 2.0)
|
||||
, ('METAL8.metal6.extention.cap' , 1.0)
|
||||
|
||||
# Contacts (i.e. Active <--> Metal).
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
, ('CONT_BODY_N.minimum.side' , 1.0)
|
||||
, ('CONT_BODY_N.nWell.enclosure' , 1.5)
|
||||
, ('CONT_BODY_N.nImplant.enclosure' , 1.5)
|
||||
|
@ -124,7 +127,7 @@ symbolicRulesTable = \
|
|||
, ('CONT_POLY.poly.enclosure' , 0.5)
|
||||
, ('CONT_POLY.metal1.enclosure' , 0.5)
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal).
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
, ('VIA12.minimum.side' , 1.0)
|
||||
, ('VIA12.metal1.enclosure' , 0.5)
|
||||
, ('VIA12.metal2.enclosure' , 0.5)
|
||||
|
@ -147,7 +150,7 @@ symbolicRulesTable = \
|
|||
, ('VIA78.metal7.enclosure' , 0.5)
|
||||
, ('VIA78.metal8.enclosure' , 0.5)
|
||||
|
||||
# Blockages.
|
||||
# Blockages (symbolic).
|
||||
, ('BLOCKAGE1.minimum.width' , 1.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
|
||||
, ('BLOCKAGE2.minimum.width' , 2.0)
|
||||
|
|
|
@ -8,20 +8,22 @@ import helpers
|
|||
# Provides standard settings for:
|
||||
# - <viewerConfig>
|
||||
# - <realLayersTable>
|
||||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
# - <workingLayersTable>
|
||||
|
||||
execfile( helpers.sysConfDir+'/common/technology.conf' )
|
||||
|
||||
|
||||
# Format of <symbolicRulesTable>:
|
||||
# Format of <layersExtensionsTable>:
|
||||
# Each entry is a pair of (string, value).
|
||||
# * string: a synthetic way to designate the symbolic layer on which
|
||||
# it applies, an optional real layer in case where there is
|
||||
# more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value expressed in lambda.
|
||||
# * string: a synthetic way to designate the real or symbolic layer on
|
||||
# which it applies, an optional sub layer (BasicLayer) in case
|
||||
# where there is more than one, and the dimension name.
|
||||
# * value : the rule (dimension) value. If the main layer is symbolic it
|
||||
# must be expressed in lambda, if it is for a real layers it
|
||||
# must be expressed in microns.
|
||||
|
||||
symbolicRulesTable = \
|
||||
layersExtensionsTable = \
|
||||
( ('NWELL.nWell.extention.cap' , 4.0)
|
||||
, ('PWELL.pWell.extention.cap' , 4.0)
|
||||
|
||||
|
@ -79,7 +81,7 @@ symbolicRulesTable = \
|
|||
, ('POLY2.minimum.width' , 2.0)
|
||||
, ('POLY2.poly2.extention.cap' , 2.0)
|
||||
|
||||
# Routing Layers.
|
||||
# Routing Layers (symbolic).
|
||||
, ('METAL1.minimum.width' , 1.0)
|
||||
, ('METAL1.metal1.extention.cap' , 2.0)
|
||||
, ('METAL2.minimum.width' , 1.0)
|
||||
|
@ -97,7 +99,7 @@ symbolicRulesTable = \
|
|||
, ('METAL8.minimum.width' , 2.0)
|
||||
, ('METAL8.metal6.extention.cap' , 4.0)
|
||||
|
||||
# Contacts (i.e. Active <--> Metal).
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
, ('CONT_BODY_N.minimum.side' , 2.0)
|
||||
, ('CONT_BODY_N.nWell.enclosure' , 3.0)
|
||||
, ('CONT_BODY_N.nImplant.enclosure' , 3.0)
|
||||
|
@ -124,7 +126,7 @@ symbolicRulesTable = \
|
|||
, ('CONT_POLY.poly.enclosure' , 2.0)
|
||||
, ('CONT_POLY.metal1.enclosure' , 1.0)
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal).
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
, ('VIA12.minimum.side' , 2.0)
|
||||
, ('VIA12.metal1.enclosure' , 1.0)
|
||||
, ('VIA12.metal2.enclosure' , 1.0)
|
||||
|
@ -147,7 +149,7 @@ symbolicRulesTable = \
|
|||
, ('VIA78.metal7.enclosure' , 3.0)
|
||||
, ('VIA78.metal8.enclosure' , 3.0)
|
||||
|
||||
# Blockages.
|
||||
# Blockages (symbolic).
|
||||
, ('BLOCKAGE1.minimum.width' , 1.0)
|
||||
, ('BLOCKAGE1.blockage1.extention.cap' , 2.0)
|
||||
, ('BLOCKAGE2.minimum.width' , 2.0)
|
||||
|
|
|
@ -75,21 +75,21 @@ SystemMandatory = 0x0100
|
|||
|
||||
|
||||
def coriolisConfigure():
|
||||
confHelpers = ( ('allianceConfig' , Alliance.loadAllianceConfig , SystemMandatory|AllianceHelper)
|
||||
, ('routingGaugesTable' , Alliance.loadRoutingGaugesTable, SystemMandatory|KiteHelper)
|
||||
, ('cellGaugesTable' , Alliance.loadCellGaugesTable , SystemMandatory|KiteHelper)
|
||||
, ('viewerConfig' , Technology.loadViewerConfig , SystemMandatory|TechnologyHelper)
|
||||
, ('realLayersTable' , Technology.loadRealLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('symbolicLayersTable', Technology.loadSymbolicLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('symbolicRulesTable' , Technology.loadSymbolicRules , SystemMandatory|TechnologyHelper)
|
||||
, ('workingLayersTable' , Technology.loadWorkingLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('technoConfig' , Technology.loadTechnoConfig , SystemMandatory|TechnologyHelper)
|
||||
, ('gdsLayersTable' , Technology.loadGdsLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('patternsTable' , Patterns.loadPatterns , SystemMandatory|PatternsHelper)
|
||||
, ('stylesTable' , Display.loadStyles , SystemMandatory|DisplayHelper)
|
||||
, ('defaultStyle' , Display.loadDefaultStyle , SystemMandatory|DisplayHelper)
|
||||
, ('parametersTable' , Configuration.loadParameters , ConfigurationHelper)
|
||||
, ('layoutTable' , Configuration.loadLayout , ConfigurationHelper)
|
||||
confHelpers = ( ('technoConfig' , Technology.loadTechnoConfig , SystemMandatory|TechnologyHelper)
|
||||
, ('allianceConfig' , Alliance.loadAllianceConfig , SystemMandatory|AllianceHelper)
|
||||
, ('routingGaugesTable' , Alliance.loadRoutingGaugesTable, SystemMandatory|KiteHelper)
|
||||
, ('cellGaugesTable' , Alliance.loadCellGaugesTable , SystemMandatory|KiteHelper)
|
||||
, ('viewerConfig' , Technology.loadViewerConfig , SystemMandatory|TechnologyHelper)
|
||||
, ('realLayersTable' , Technology.loadRealLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('compositeLayersTable' , Technology.loadCompositeLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('symbolicLayersTable' , Technology.tagSymbolicLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('layersExtensionsTable', Technology.loadLayersExtensions, SystemMandatory|TechnologyHelper)
|
||||
, ('gdsLayersTable' , Technology.loadGdsLayers , SystemMandatory|TechnologyHelper)
|
||||
, ('patternsTable' , Patterns.loadPatterns , SystemMandatory|PatternsHelper)
|
||||
, ('stylesTable' , Display.loadStyles , SystemMandatory|DisplayHelper)
|
||||
, ('defaultStyle' , Display.loadDefaultStyle , SystemMandatory|DisplayHelper)
|
||||
, ('parametersTable' , Configuration.loadParameters , ConfigurationHelper)
|
||||
, ('layoutTable' , Configuration.loadLayout , ConfigurationHelper)
|
||||
)
|
||||
|
||||
print ' o Running configuration hook: coriolisConfigure().'
|
||||
|
|
|
@ -51,7 +51,7 @@ def Alliance ( db ):
|
|||
print " Minimal spacing :", DbU.toLambda(rlayer.getMinimalSpacing())
|
||||
print " Pitch :", DbU.toLambda(rlayer.getPitch())
|
||||
print " Cut above :", rlayer.getCutAbove()
|
||||
print " isWorking :", rlayer.isWorking()
|
||||
print " isSymbolic :", rlayer.isSymbolic()
|
||||
|
||||
dlayer = technology.getLayer('NDIF')
|
||||
print 'NDIF', dlayer.getMask()
|
||||
|
|
|
@ -16,12 +16,13 @@ from Hurricane import ContactLayer
|
|||
from Hurricane import ViaLayer
|
||||
from CRL import AllianceFramework
|
||||
from helpers import ErrorMessage
|
||||
from helpers import toDbU
|
||||
|
||||
|
||||
technologyFile = '<No technology file specified>'
|
||||
|
||||
|
||||
class SymbolicLayerType ( object ):
|
||||
class CompositeLayerType ( object ):
|
||||
|
||||
Regular = 1
|
||||
Diffusion = 2
|
||||
|
@ -37,54 +38,54 @@ class SymbolicLayerType ( object ):
|
|||
return self._code
|
||||
|
||||
def __str__ ( self ):
|
||||
if self._code == SymbolicLayerType.Regular: return 'TypeRegular'
|
||||
if self._code == SymbolicLayerType.Diffusion: return 'TypeDiffusion'
|
||||
if self._code == SymbolicLayerType.Transistor: return 'TypeTransistor'
|
||||
if self._code == SymbolicLayerType.Contact: return 'TypeContact'
|
||||
if self._code == SymbolicLayerType.Via: return 'TypeVia'
|
||||
if self._code == CompositeLayerType.Regular: return 'TypeRegular'
|
||||
if self._code == CompositeLayerType.Diffusion: return 'TypeDiffusion'
|
||||
if self._code == CompositeLayerType.Transistor: return 'TypeTransistor'
|
||||
if self._code == CompositeLayerType.Contact: return 'TypeContact'
|
||||
if self._code == CompositeLayerType.Via: return 'TypeVia'
|
||||
return 'TypeUnknown (%d)', self._code
|
||||
|
||||
def __repr__ ( self ):
|
||||
return str(self)
|
||||
|
||||
def realLayerLength ( self ):
|
||||
if self._code == SymbolicLayerType.Regular: return 1
|
||||
if self._code == SymbolicLayerType.Diffusion: return 3
|
||||
if self._code == SymbolicLayerType.Transistor: return 4
|
||||
if self._code == SymbolicLayerType.Contact: return 5
|
||||
if self._code == SymbolicLayerType.Via: return 3
|
||||
if self._code == CompositeLayerType.Regular: return 1
|
||||
if self._code == CompositeLayerType.Diffusion: return 3
|
||||
if self._code == CompositeLayerType.Transistor: return 4
|
||||
if self._code == CompositeLayerType.Contact: return 5
|
||||
if self._code == CompositeLayerType.Via: return 3
|
||||
return 0
|
||||
|
||||
|
||||
TypeRegular = SymbolicLayerType(SymbolicLayerType.Regular)
|
||||
TypeDiffusion = SymbolicLayerType(SymbolicLayerType.Diffusion)
|
||||
TypeTransistor = SymbolicLayerType(SymbolicLayerType.Transistor)
|
||||
TypeContact = SymbolicLayerType(SymbolicLayerType.Contact)
|
||||
TypeVia = SymbolicLayerType(SymbolicLayerType.Via)
|
||||
TypeRegular = CompositeLayerType(CompositeLayerType.Regular)
|
||||
TypeDiffusion = CompositeLayerType(CompositeLayerType.Diffusion)
|
||||
TypeTransistor = CompositeLayerType(CompositeLayerType.Transistor)
|
||||
TypeContact = CompositeLayerType(CompositeLayerType.Contact)
|
||||
TypeVia = CompositeLayerType(CompositeLayerType.Via)
|
||||
|
||||
|
||||
class LayersLUT ( object ):
|
||||
|
||||
Real = 0x1
|
||||
Symbolic = 0x2
|
||||
Composite = 0x2
|
||||
MissingError = 0x8
|
||||
|
||||
def __init__ ( self ):
|
||||
self._realLayers = {}
|
||||
self._symbolicLayers = {}
|
||||
self._realLayers = {}
|
||||
self._compositeLayers = {}
|
||||
return
|
||||
|
||||
def add ( self, layer ):
|
||||
if isinstance(layer,BasicLayer): self._realLayers [ layer.getName() ] = layer
|
||||
else: self._symbolicLayers[ layer.getName() ] = layer
|
||||
if isinstance(layer,BasicLayer): self._realLayers [ layer.getName() ] = layer
|
||||
else: self._compositeLayers[ layer.getName() ] = layer
|
||||
return
|
||||
|
||||
def lookup ( self, name, flags=Real|Symbolic ):
|
||||
def lookup ( self, name, flags=Real|Composite ):
|
||||
layer = None
|
||||
if flags & LayersLUT.Real and self._realLayers.has_key(name):
|
||||
layer = self._realLayers[name]
|
||||
if flags & LayersLUT.Symbolic and self._symbolicLayers.has_key(name):
|
||||
layer = self._symbolicLayers[name]
|
||||
if flags & LayersLUT.Composite and self._compositeLayers.has_key(name):
|
||||
layer = self._compositeLayers[name]
|
||||
|
||||
if not layer and flags&LayersLUT.MissingError:
|
||||
raise ErrorMessage(1,['Layer <%s> is not defined (yet?).'%name])
|
||||
|
@ -135,25 +136,25 @@ def loadRealLayers ( realLayersTable, confFile ):
|
|||
return
|
||||
|
||||
|
||||
def loadSymbolicLayers ( symbolicLayersData, confFile ):
|
||||
def loadCompositeLayers ( compositeLayersData, confFile ):
|
||||
global technologyFile
|
||||
technologyFile = confFile
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
|
||||
entryNo = 0
|
||||
for entry in symbolicLayersData:
|
||||
for entry in compositeLayersData:
|
||||
entryNo += 1
|
||||
|
||||
try:
|
||||
if len(entry) != 3:
|
||||
raise ErrorMessage(1,['Malformed entry in <symbolicLayersTable>.'
|
||||
raise ErrorMessage(1,['Malformed entry in <compositeLayersTable>.'
|
||||
,'Must contains exactly three fields: ( name, type, (real_layers,) ).'
|
||||
,str(entry)
|
||||
])
|
||||
name, layerType, realLayers = entry
|
||||
|
||||
if not isinstance(layerType,SymbolicLayerType):
|
||||
raise ErrorMessage(1,['Invalid entry in <symbolicLayersTable>.'
|
||||
if not isinstance(layerType,CompositeLayerType):
|
||||
raise ErrorMessage(1,['Invalid entry in <compositeLayersTable>.'
|
||||
,'The layer type code is not valid, should be any of:'
|
||||
,' * TypeRegular'
|
||||
,' * TypeDiffusion'
|
||||
|
@ -163,7 +164,7 @@ def loadSymbolicLayers ( symbolicLayersData, confFile ):
|
|||
,str(entry)
|
||||
])
|
||||
if layerType.realLayerLength() != len(realLayers):
|
||||
raise ErrorMessage(1,['Invalid entry in <symbolicLayersTable>.'
|
||||
raise ErrorMessage(1,['Invalid entry in <compositeLayersTable>.'
|
||||
,'Layer of type <%s> contains %d real layers instead of %d.' \
|
||||
% (layerType,len(realLayers),layerType.realLayerLength())
|
||||
,str(entry)
|
||||
|
@ -174,64 +175,66 @@ def loadSymbolicLayers ( symbolicLayersData, confFile ):
|
|||
if layerName:
|
||||
realLayersArgs += [ layersLUT.lookup(layerName
|
||||
,LayersLUT.Real
|
||||
|LayersLUT.Symbolic
|
||||
|LayersLUT.Composite
|
||||
|LayersLUT.MissingError) ]
|
||||
else:
|
||||
realLayersArgs += [ None ]
|
||||
|
||||
symbolicLayer = None
|
||||
compositeLayer = None
|
||||
|
||||
if layerType == TypeRegular:
|
||||
symbolicLayer = RegularLayer.create(technology,entry[0])
|
||||
symbolicLayer.setBasicLayer( *realLayersArgs )
|
||||
compositeLayer = RegularLayer.create(technology,entry[0])
|
||||
compositeLayer.setBasicLayer( *realLayersArgs )
|
||||
elif layerType == TypeDiffusion:
|
||||
symbolicLayer = DiffusionLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
compositeLayer = DiffusionLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
elif layerType == TypeTransistor:
|
||||
symbolicLayer = TransistorLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
compositeLayer = TransistorLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
elif layerType == TypeContact:
|
||||
symbolicLayer = ContactLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
compositeLayer = ContactLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
elif layerType == TypeVia:
|
||||
symbolicLayer = ViaLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
compositeLayer = ViaLayer.create(technology ,entry[0], *realLayersArgs)
|
||||
|
||||
layersLUT.add( symbolicLayer )
|
||||
layersLUT.add( compositeLayer )
|
||||
|
||||
except Exception, e:
|
||||
ErrorMessage.wrapPrint(e,'In %s:<symbolicLayersTable> at entry %d.' % (technologyFile,entryNo))
|
||||
ErrorMessage.wrapPrint(e,'In %s:<compositeLayersTable> at entry %d.' % (technologyFile,entryNo))
|
||||
return
|
||||
|
||||
|
||||
def loadSymbolicRules ( symbolicRulesTable, confFile ):
|
||||
def loadLayersExtensions ( layersExtensionsTable, confFile ):
|
||||
global technologyFile
|
||||
technologyFile = confFile
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
|
||||
entryNo = 0
|
||||
for rule in symbolicRulesTable:
|
||||
for rule in layersExtensionsTable:
|
||||
entryNo += 1
|
||||
|
||||
try:
|
||||
if len(rule) != 2:
|
||||
raise ErrorMessage(1,['Malformed entry in <symbolicRulesTable>.'
|
||||
raise ErrorMessage(1,['Malformed entry in <layersExtensionsTable>.'
|
||||
,'Must contains exactly two fields: ( rule_path, value ).'
|
||||
,str(rule)
|
||||
])
|
||||
if not isinstance(rule[1],int) and not isinstance(rule[1],float):
|
||||
raise ErrorMessage(1,['Invalid entry in <symbolicRulesTable>.'
|
||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||
,'Rule value must be of integer or float type.'
|
||||
,str(rule)
|
||||
])
|
||||
|
||||
value = DbU.fromLambda(rule[1])
|
||||
elements = rule[0].split('.')
|
||||
if len(elements) < 3:
|
||||
raise ErrorMessage(1,['Invalid entry in <symbolicRulesTable>.'
|
||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||
,'Rule name must contains at least three components: \"LAYER.category.dimension\".'
|
||||
,str(rule)
|
||||
])
|
||||
|
||||
ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Symbolic|LayersLUT.MissingError )
|
||||
ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Composite|LayersLUT.MissingError )
|
||||
subLayer = layersLUT.lookup( elements[1], LayersLUT.Real )
|
||||
|
||||
if elements[0].startswith('via'): value = toDbU(rule[1])
|
||||
else: value = DbU.fromLambda(rule[1])
|
||||
|
||||
if subLayer: ruleTag = string.join(elements[2:],'.')
|
||||
else: ruleTag = string.join(elements[1:],'.')
|
||||
|
||||
|
@ -241,7 +244,7 @@ def loadSymbolicRules ( symbolicRulesTable, confFile ):
|
|||
elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value )
|
||||
elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value )
|
||||
else:
|
||||
raise ErrorMessage(1,['Invalid entry in <symbolicRulesTable>.'
|
||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||
,'Unknown rule kind: \".%s\", should be any of:' % ruleTag
|
||||
,' * "RULE_HEAD.extention.cap"'
|
||||
,' * "RULE_HEAD.extention.width"'
|
||||
|
@ -252,24 +255,24 @@ def loadSymbolicRules ( symbolicRulesTable, confFile ):
|
|||
])
|
||||
|
||||
except Exception, e:
|
||||
ErrorMessage.wrapPrint(e,'In %s:<symbolicRulesTable> at entry %d.' % (technologyFile,entryNo))
|
||||
ErrorMessage.wrapPrint(e,'In %s:<layersExtensionsTable> at entry %d.' % (technologyFile,entryNo))
|
||||
return
|
||||
|
||||
|
||||
def loadWorkingLayers ( workingLayersTable, confFile ):
|
||||
def tagSymbolicLayers ( symbolicLayersTable, confFile ):
|
||||
global technologyFile
|
||||
technologyFile = confFile
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
|
||||
entryNo = 0
|
||||
for layerName in workingLayersTable:
|
||||
for layerName in symbolicLayersTable:
|
||||
entryNo += 1
|
||||
try:
|
||||
# This call is just to generate an error if the layer is non-existent.
|
||||
layersLUT.lookup(layerName,LayersLUT.Real|LayersLUT.Symbolic|LayersLUT.MissingError)
|
||||
technology.setWorkingLayer(layerName)
|
||||
layersLUT.lookup(layerName,LayersLUT.Real|LayersLUT.Composite|LayersLUT.MissingError)
|
||||
technology.setSymbolicLayer(layerName)
|
||||
except Exception, e:
|
||||
ErrorMessage.wrapPrint(e,'In %s:<workingLayersTable> at entry %d.' % (technologyFile,entryNo))
|
||||
ErrorMessage.wrapPrint(e,'In %s:<symbolicLayersTable> at entry %d.' % (technologyFile,entryNo))
|
||||
return
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace CRL {
|
|||
using Hurricane::JsonTypes;
|
||||
using Hurricane::JsonArray;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::ViaLayer;
|
||||
using Hurricane::getCollection;
|
||||
|
||||
|
@ -219,22 +220,23 @@ namespace CRL {
|
|||
|
||||
void RoutingGauge::addLayerGauge ( RoutingLayerGauge* layerGauge )
|
||||
{
|
||||
if ( getLayerGauge(layerGauge->getLayer()) != NULL )
|
||||
throw Error ( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str()
|
||||
, getString(_name).c_str() );
|
||||
if (getLayerGauge(layerGauge->getLayer()) != NULL)
|
||||
throw Error( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str()
|
||||
, getString(_name).c_str() );
|
||||
|
||||
_layerGauges.push_back ( layerGauge );
|
||||
_layerGauges.push_back( layerGauge );
|
||||
|
||||
size_t gaugeSize = _layerGauges.size();
|
||||
if ( gaugeSize > 1 ) {
|
||||
Layer* viaLayer = _technology->getViaBetween(_layerGauges[gaugeSize-2]->getLayer()
|
||||
,_layerGauges[gaugeSize-1]->getLayer());
|
||||
if ( !viaLayer ) {
|
||||
cerr << Error("Can't find a VIA between Gauge layers %s and %s."
|
||||
,getString(_layerGauges[gaugeSize-2]).c_str()
|
||||
,getString(_layerGauges[gaugeSize-1]).c_str()) << endl;
|
||||
if (gaugeSize > 1) {
|
||||
Layer* viaLayer = _technology->getViaBetween( _layerGauges[gaugeSize-2]->getLayer()
|
||||
, _layerGauges[gaugeSize-1]->getLayer()
|
||||
, _layerGauges[gaugeSize-1]->getLayer()->isSymbolic() );
|
||||
if (not viaLayer) {
|
||||
cerr << Error( "Can't find a VIA between Gauge layers %s and %s."
|
||||
, getString(_layerGauges[gaugeSize-2]).c_str()
|
||||
, getString(_layerGauges[gaugeSize-1]).c_str() ) << endl;
|
||||
}
|
||||
_viaLayers.push_back ( viaLayer );
|
||||
_viaLayers.push_back( viaLayer );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -537,34 +537,27 @@ namespace CRL {
|
|||
void SymbolicTechnologyParser::_postLoad ()
|
||||
{
|
||||
// Fixme.
|
||||
_technology->setWorkingLayer ( "cut0" );
|
||||
_technology->setWorkingLayer ( "cut1" );
|
||||
_technology->setWorkingLayer ( "cut2" );
|
||||
_technology->setWorkingLayer ( "cut3" );
|
||||
_technology->setWorkingLayer ( "cut4" );
|
||||
_technology->setWorkingLayer ( "cut5" );
|
||||
_technology->setWorkingLayer ( "gcut" );
|
||||
_technology->setWorkingLayer ( "POLY" );
|
||||
_technology->setWorkingLayer ( "METAL1" );
|
||||
_technology->setWorkingLayer ( "METAL2" );
|
||||
_technology->setWorkingLayer ( "METAL3" );
|
||||
_technology->setWorkingLayer ( "METAL4" );
|
||||
_technology->setWorkingLayer ( "METAL5" );
|
||||
_technology->setWorkingLayer ( "METAL6" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE1" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE2" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE3" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE4" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE5" );
|
||||
_technology->setWorkingLayer ( "BLOCKAGE6" );
|
||||
_technology->setWorkingLayer ( "gmetalh" );
|
||||
_technology->setWorkingLayer ( "gmetalv" );
|
||||
_technology->setWorkingLayer ( "VIA12" );
|
||||
_technology->setWorkingLayer ( "VIA23" );
|
||||
_technology->setWorkingLayer ( "VIA34" );
|
||||
_technology->setWorkingLayer ( "VIA45" );
|
||||
_technology->setWorkingLayer ( "VIA56" );
|
||||
_technology->setWorkingLayer ( "gcontact" );
|
||||
_technology->setSymbolicLayer ( "POLY" );
|
||||
_technology->setSymbolicLayer ( "METAL1" );
|
||||
_technology->setSymbolicLayer ( "METAL2" );
|
||||
_technology->setSymbolicLayer ( "METAL3" );
|
||||
_technology->setSymbolicLayer ( "METAL4" );
|
||||
_technology->setSymbolicLayer ( "METAL5" );
|
||||
_technology->setSymbolicLayer ( "METAL6" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE1" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE2" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE3" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE4" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE5" );
|
||||
_technology->setSymbolicLayer ( "BLOCKAGE6" );
|
||||
_technology->setSymbolicLayer ( "gmetalh" );
|
||||
_technology->setSymbolicLayer ( "gmetalv" );
|
||||
_technology->setSymbolicLayer ( "VIA12" );
|
||||
_technology->setSymbolicLayer ( "VIA23" );
|
||||
_technology->setSymbolicLayer ( "VIA34" );
|
||||
_technology->setSymbolicLayer ( "VIA45" );
|
||||
_technology->setSymbolicLayer ( "VIA56" );
|
||||
_technology->setSymbolicLayer ( "gcontact" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -373,12 +373,12 @@ namespace {
|
|||
else {
|
||||
cmess2 << " " << tab++ << "+ " << cell->getName() << " [.model]" << endl;
|
||||
|
||||
Net* vss = Net::create ( _cell, "vss" );
|
||||
Net* vss = Net::create ( _cell, "gnd!" );
|
||||
vss->setExternal( true );
|
||||
vss->setGlobal ( true );
|
||||
vss->setType ( Net::Type::GROUND );
|
||||
|
||||
Net* vdd = Net::create ( _cell, "vdd" );
|
||||
Net* vdd = Net::create ( _cell, "vdd!" );
|
||||
vdd->setExternal( true );
|
||||
vdd->setGlobal ( true );
|
||||
vdd->setType ( Net::Type::POWER );
|
||||
|
@ -689,7 +689,7 @@ namespace CRL {
|
|||
, tokenize.lineno()
|
||||
) << endl;
|
||||
//blifModel->mergeAlias( blifLine[1], "vss" );
|
||||
blifModel->getCell()->getNet( "vss" )->addAlias( blifLine[1] );
|
||||
blifModel->getCell()->getNet( "gnd!" )->addAlias( blifLine[1] );
|
||||
} else if (tokenize.state() & Tokenize::CoverOne ) {
|
||||
cerr << Warning( "Blif::load() Definition of an alias <%s> of VDD in a \".names\". Maybe you should use tie cells?\n"
|
||||
" File \"%s.blif\" at line %u."
|
||||
|
@ -698,7 +698,7 @@ namespace CRL {
|
|||
, tokenize.lineno()
|
||||
) << endl;
|
||||
//blifModel->mergeAlias( blifLine[1], "vdd" );
|
||||
blifModel->getCell()->getNet( "vdd" )->addAlias( blifLine[1] );
|
||||
blifModel->getCell()->getNet( "vdd!" )->addAlias( blifLine[1] );
|
||||
} else {
|
||||
cerr << Error( "Blif::load() Unsupported \".names\" cover construct.\n"
|
||||
" File \"%s.blif\" at line %u."
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace {
|
|||
static void setCoreSite ( DbU::Unit x, DbU::Unit y );
|
||||
static DbU::Unit getCoreSiteX ();
|
||||
static DbU::Unit getCoreSiteY ();
|
||||
inline DbU::Unit getMinTerminalWidth () const;
|
||||
inline double getUnitsMicrons () const;
|
||||
inline DbU::Unit fromUnitsMicrons ( double ) const;
|
||||
inline void setUnitsMicrons ( double );
|
||||
|
@ -122,11 +123,13 @@ namespace {
|
|||
int _nthCut;
|
||||
RoutingGauge* _routingGauge;
|
||||
CellGauge* _cellGauge;
|
||||
DbU::Unit _minTerminalWidth;
|
||||
static DbU::Unit _coreSiteX;
|
||||
static DbU::Unit _coreSiteY;
|
||||
};
|
||||
|
||||
|
||||
inline DbU::Unit LefParser::getMinTerminalWidth () const { return _minTerminalWidth; }
|
||||
inline string LefParser::getLibraryName () const { return _libraryName; }
|
||||
inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; }
|
||||
inline Cell* LefParser::getCell () const { return _cell; }
|
||||
|
@ -184,18 +187,19 @@ namespace {
|
|||
|
||||
|
||||
LefParser::LefParser ( string file, string libraryName )
|
||||
: _file (file)
|
||||
, _libraryName (libraryName)
|
||||
, _library (NULL)
|
||||
, _cell (NULL)
|
||||
, _net (NULL)
|
||||
, _busBits ("()")
|
||||
, _unitsMicrons(0.01)
|
||||
, _errors ()
|
||||
, _nthMetal (0)
|
||||
, _nthCut (0)
|
||||
, _routingGauge(NULL)
|
||||
, _cellGauge (NULL)
|
||||
: _file (file)
|
||||
, _libraryName (libraryName)
|
||||
, _library (NULL)
|
||||
, _cell (NULL)
|
||||
, _net (NULL)
|
||||
, _busBits ("()")
|
||||
, _unitsMicrons (0.01)
|
||||
, _errors ()
|
||||
, _nthMetal (0)
|
||||
, _nthCut (0)
|
||||
, _routingGauge (NULL)
|
||||
, _cellGauge (NULL)
|
||||
, _minTerminalWidth(DbU::fromPhysical(0.9,DbU::UnitPower::Micro))
|
||||
{
|
||||
_routingGauge = AllianceFramework::get()->getRoutingGauge();
|
||||
_cellGauge = AllianceFramework::get()->getCellGauge();
|
||||
|
@ -364,8 +368,10 @@ namespace {
|
|||
Cell* cell = parser->getCell();
|
||||
Net* blockageNet = cell->getNet( "blockage" );
|
||||
|
||||
if (not blockageNet)
|
||||
if (not blockageNet) {
|
||||
blockageNet = Net::create( cell, "blockage" );
|
||||
blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
|
||||
lefiGeometries* geoms = obstruction->geometries();
|
||||
for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) {
|
||||
|
@ -472,26 +478,29 @@ namespace {
|
|||
continue;
|
||||
}
|
||||
if (geoms->itemType(igeom) == lefiGeomRectE) {
|
||||
lefiGeomRect* r = geoms->getRect(igeom);
|
||||
double w = r->xh - r->xl;
|
||||
double h = r->yh - r->yl;
|
||||
Component* component = NULL;
|
||||
lefiGeomRect* r = geoms->getRect(igeom);
|
||||
DbU::Unit w = parser->fromUnitsMicrons(r->xh - r->xl);
|
||||
DbU::Unit h = parser->fromUnitsMicrons(r->yh - r->yl);
|
||||
Component* component = NULL;
|
||||
bool isExternal = false;
|
||||
if (w >= h) {
|
||||
isExternal = (h >= parser->getMinTerminalWidth());
|
||||
component = Horizontal::create( net, layer
|
||||
, parser->fromUnitsMicrons( (r->yl + r->yh)/2 )
|
||||
, parser->fromUnitsMicrons( h )
|
||||
, h
|
||||
, parser->fromUnitsMicrons( r->xl )
|
||||
, parser->fromUnitsMicrons( r->xh )
|
||||
);
|
||||
} else {
|
||||
isExternal = (w >= parser->getMinTerminalWidth());
|
||||
component = Vertical::create( net, layer
|
||||
, parser->fromUnitsMicrons( (r->xl + r->xh)/2 )
|
||||
, parser->fromUnitsMicrons( w )
|
||||
, w
|
||||
, parser->fromUnitsMicrons( r->yl )
|
||||
, parser->fromUnitsMicrons( r->yh )
|
||||
);
|
||||
}
|
||||
NetExternalComponents::setExternal( component );
|
||||
if (isExternal) NetExternalComponents::setExternal( component );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
string materialName = get<string> ( stack, "_material" );
|
||||
unsigned int extractNumber = get<int64_t>( stack, "_extractNumber" );
|
||||
string blockageLayer = get<string> ( stack, "_blockageLayer" );
|
||||
|
@ -405,7 +405,7 @@ namespace Hurricane {
|
|||
, minimalSize
|
||||
, minimalSpacing
|
||||
);
|
||||
basicLayer->setWorking( isWorking );
|
||||
basicLayer->setSymbolic( isSymbolic );
|
||||
|
||||
if (blockageLayer != "no_blockage_layer") {
|
||||
JsonTechnology* jtechno = jget<JsonTechnology>( stack );
|
||||
|
|
|
@ -837,6 +837,7 @@ void Cell::flattenNets ( const Instance* instance, uint64_t flags )
|
|||
Net* net = static_cast<Net*>(occurrence.getEntity());
|
||||
|
||||
if (net->isClock() and (flags & Flags::NoClockFlatten)) continue;
|
||||
if (net->isPower() or net->isGround() or net->isBlockage()) continue;
|
||||
|
||||
HyperNet hyperNet ( occurrence );
|
||||
if ( not occurrence.getPath().isEmpty() ) {
|
||||
|
|
|
@ -266,7 +266,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
|
||||
BasicLayer* metal = techno->getBasicLayer( get<string>(stack,"_metal" ) );
|
||||
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
|
||||
|
@ -291,7 +291,7 @@ namespace Hurricane {
|
|||
, diffusion
|
||||
, well
|
||||
);
|
||||
layer->setWorking ( isWorking );
|
||||
layer->setSymbolic ( isSymbolic );
|
||||
layer->setEnclosure( metal , metalEncl );
|
||||
layer->setEnclosure( cut , cutEncl );
|
||||
layer->setEnclosure( active , activeEncl );
|
||||
|
|
|
@ -293,7 +293,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
|
||||
BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
|
||||
BasicLayer* diffusion = techno->getBasicLayer( get<string>(stack,"_diffusion" ) );
|
||||
|
@ -315,7 +315,7 @@ namespace Hurricane {
|
|||
, diffusion
|
||||
, well
|
||||
);
|
||||
layer->setWorking ( isWorking );
|
||||
layer->setSymbolic ( isSymbolic );
|
||||
layer->setExtentionCap ( active , eCapActive );
|
||||
layer->setExtentionCap ( diffusion, eCapDiffusion );
|
||||
layer->setExtentionWidth( active , eWidthActive );
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Hurricane {
|
|||
, _minimalSize(minimalSize)
|
||||
, _minimalSpacing(minimalSpacing)
|
||||
, _nextOfTechnologyLayerMap(NULL)
|
||||
, _working(false)
|
||||
, _symbolic(false)
|
||||
{
|
||||
if ( !_technology )
|
||||
throw Error ( "Can't create " + _TName("Layer") + " : null technology" );
|
||||
|
@ -84,20 +84,20 @@ namespace Hurricane {
|
|||
{ return NULL; }
|
||||
|
||||
|
||||
Layer* Layer::getMetalAbove ( bool useWorking ) const
|
||||
{ return _technology->getMetalAbove(this,useWorking); }
|
||||
Layer* Layer::getMetalAbove ( bool useSymbolic ) const
|
||||
{ return _technology->getMetalAbove(this,useSymbolic); }
|
||||
|
||||
|
||||
Layer* Layer::getMetalBelow ( bool useWorking ) const
|
||||
{ return _technology->getMetalBelow(this,useWorking); }
|
||||
Layer* Layer::getMetalBelow ( bool useSymbolic ) const
|
||||
{ return _technology->getMetalBelow(this,useSymbolic); }
|
||||
|
||||
|
||||
Layer* Layer::getCutAbove ( bool useWorking ) const
|
||||
{ return _technology->getCutAbove(this,useWorking); }
|
||||
Layer* Layer::getCutAbove ( bool useSymbolic ) const
|
||||
{ return _technology->getCutAbove(this,useSymbolic); }
|
||||
|
||||
|
||||
Layer* Layer::getCutBelow ( bool useWorking ) const
|
||||
{ return _technology->getCutBelow(this,useWorking); }
|
||||
Layer* Layer::getCutBelow ( bool useSymbolic ) const
|
||||
{ return _technology->getCutBelow(this,useSymbolic); }
|
||||
|
||||
|
||||
DbU::Unit Layer::getEnclosure () const
|
||||
|
@ -246,7 +246,7 @@ namespace Hurricane {
|
|||
jsonWrite( writer, "_extractMask" , getString(_extractMask) );
|
||||
jsonWrite( writer, "_minimalSize" , _minimalSize );
|
||||
jsonWrite( writer, "_minimalSpacing", _minimalSpacing );
|
||||
jsonWrite( writer, "_working" , _working );
|
||||
jsonWrite( writer, "_symbolic" , _symbolic );
|
||||
}
|
||||
|
||||
|
||||
|
@ -261,7 +261,7 @@ namespace Hurricane {
|
|||
add( "_extractMask" , typeid(string) );
|
||||
add( "_minimalSize" , typeid(uint64_t) );
|
||||
add( "_minimalSpacing", typeid(uint64_t) );
|
||||
add( "_working" , typeid(uint64_t) );
|
||||
add( "_symbolic" , typeid(uint64_t) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
|
||||
BasicLayer* basicLayer = techno->getBasicLayer( get<string>(stack,"_basicLayer" ) );
|
||||
DbU::Unit enclosure = get<int64_t>( stack, "_enclosure" );
|
||||
|
@ -398,7 +398,7 @@ namespace Hurricane {
|
|||
// Actual creation.
|
||||
layer = RegularLayer::create( techno, name );
|
||||
layer->setBasicLayer ( basicLayer );
|
||||
layer->setWorking ( isWorking );
|
||||
layer->setSymbolic ( isSymbolic );
|
||||
layer->setMinimalSize ( minimalSize );
|
||||
layer->setMinimalSpacing( minimalSpacing );
|
||||
layer->setEnclosure ( basicLayer, enclosure );
|
||||
|
|
|
@ -150,16 +150,6 @@ Technology* Technology::create(DataBase* dataBase, const Name& name)
|
|||
return technology;
|
||||
}
|
||||
|
||||
// Layer* Technology::getLayer ( Layer::Mask mask ) const
|
||||
// // ***************************************************
|
||||
// {
|
||||
// LayerMaskMap::const_iterator ilayer = _layerMaskMap.find(mask);
|
||||
// if ( ilayer == _layerMaskMap.end() )
|
||||
// return NULL;
|
||||
|
||||
// return ilayer->second;
|
||||
// }
|
||||
|
||||
BasicLayer* Technology::getBasicLayer(const Name& name) const
|
||||
// **********************************************************
|
||||
{
|
||||
|
@ -195,97 +185,107 @@ BasicLayers Technology::getBasicLayers(const Layer::Mask& mask) const
|
|||
}
|
||||
|
||||
RegularLayers Technology::getRegularLayers() const
|
||||
// ***************************************************
|
||||
// ***********************************************
|
||||
{
|
||||
return SubTypeCollection<Layer*, RegularLayer*>(getLayers());
|
||||
}
|
||||
|
||||
ViaLayers Technology::getViaLayers() const
|
||||
// ***************************************************
|
||||
// ***************************************
|
||||
{
|
||||
return SubTypeCollection<Layer*, ViaLayer*>(getLayers());
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getLayer ( const Layer::Mask& mask, bool useWorking ) const
|
||||
Layer* Technology::getLayer ( const Layer::Mask& mask, bool useSymbolic ) const
|
||||
{
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( mask );
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( mask );
|
||||
Layer* layer = NULL;
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( mask );
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound( mask );
|
||||
for ( ; lb != ub ; lb++ ) {
|
||||
if ( !useWorking || lb->second->isWorking() ) return lb->second;
|
||||
layer = lb->second;
|
||||
if (not useSymbolic or layer->isSymbolic()) return layer;
|
||||
}
|
||||
return NULL;
|
||||
return layer;
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getMetalAbove ( const Layer* layer, bool useWorking ) const
|
||||
Layer* Technology::getMetalAbove ( const Layer* layer, bool useSymbolic ) const
|
||||
{
|
||||
if ( !layer ) return NULL;
|
||||
if (not layer) return NULL;
|
||||
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
||||
Layer* above = NULL;
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound( layer->getMask() );
|
||||
for ( ; ub != _layerMaskMap.end() ; ub++ ) {
|
||||
if ( _metalMask.contains(ub->second->getMask())
|
||||
&& ( !useWorking || ub->second->isWorking() ) )
|
||||
return ub->second;
|
||||
if (_metalMask.contains(ub->second->getMask())) {
|
||||
above = ub->second;
|
||||
if (not useSymbolic or above->isSymbolic()) return above;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return above;
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getMetalBelow ( const Layer* layer, bool useWorking ) const
|
||||
Layer* Technology::getMetalBelow ( const Layer* layer, bool useSymbolic ) const
|
||||
{
|
||||
if ( !layer ) return NULL;
|
||||
if (not layer) return NULL;
|
||||
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
||||
if ( lb->second == layer ) lb--;
|
||||
Layer* below = NULL;
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
|
||||
if (lb->second->getMask() == layer->getMask()) lb--;
|
||||
for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
|
||||
if ( _metalMask.contains(lb->second->getMask())
|
||||
&& ( !useWorking || lb->second->isWorking() ) )
|
||||
return lb->second;
|
||||
if (_metalMask.contains(lb->second->getMask())) {
|
||||
below = lb->second;
|
||||
if (not useSymbolic or below->isSymbolic()) return below;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return below;
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getCutAbove ( const Layer* layer, bool useWorking ) const
|
||||
Layer* Technology::getCutAbove ( const Layer* layer, bool useSymbolic ) const
|
||||
{
|
||||
if ( !layer ) return NULL;
|
||||
if (not layer) return NULL;
|
||||
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
||||
Layer* cut = NULL;
|
||||
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound( layer->getMask() );
|
||||
for ( ; ub != _layerMaskMap.end() ; ub++ ) {
|
||||
if ( _cutMask.contains(ub->second->getMask())
|
||||
&& ( !useWorking || ub->second->isWorking() ) )
|
||||
return ub->second;
|
||||
if (_cutMask.contains(ub->second->getMask())) {
|
||||
cut = ub->second;
|
||||
if (not useSymbolic or cut->isSymbolic()) return cut;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return cut;
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getCutBelow ( const Layer* layer, bool useWorking ) const
|
||||
Layer* Technology::getCutBelow ( const Layer* layer, bool useSymbolic ) const
|
||||
{
|
||||
if ( !layer ) return NULL;
|
||||
if (not layer) return NULL;
|
||||
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
||||
if ( lb->second == layer ) lb--;
|
||||
Layer* cut = NULL;
|
||||
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
|
||||
if (lb->second->getMask() == layer->getMask()) lb--;
|
||||
for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
|
||||
if ( _cutMask.contains(lb->second->getMask())
|
||||
&& ( !useWorking || lb->second->isWorking() ) )
|
||||
return lb->second;
|
||||
if (_cutMask.contains(lb->second->getMask())) {
|
||||
cut = lb->second;
|
||||
if (not useSymbolic or cut->isSymbolic()) return cut;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return cut;
|
||||
}
|
||||
|
||||
|
||||
Layer* Technology::getViaBetween ( const Layer* metal1, const Layer* metal2 ) const
|
||||
Layer* Technology::getViaBetween ( const Layer* metal1, const Layer* metal2, bool useSymbolic ) const
|
||||
{
|
||||
if ( !metal1 || !metal2 ) return NULL;
|
||||
if ( metal1 == metal2 ) return const_cast<Layer*>(metal1);
|
||||
if ( metal1->above(metal2) ) swap ( metal1, metal2 );
|
||||
if (not metal1 or not metal2) return NULL;
|
||||
if (metal1 == metal2) return const_cast<Layer*>(metal1);
|
||||
if (metal1->above(metal2)) swap( metal1, metal2 );
|
||||
|
||||
Layer* cutLayer = getCutBelow ( metal2 );
|
||||
if ( !cutLayer ) return NULL;
|
||||
Layer* cutLayer = getCutBelow( metal2, false );
|
||||
if (not cutLayer) return NULL;
|
||||
|
||||
return getLayer ( metal1->getMask() | metal2->getMask() | cutLayer->getMask() );
|
||||
return getLayer( metal1->getMask() | metal2->getMask() | cutLayer->getMask(), useSymbolic );
|
||||
}
|
||||
|
||||
|
||||
|
@ -316,26 +316,26 @@ void Technology::setName(const Name& name)
|
|||
}
|
||||
|
||||
|
||||
bool Technology::setWorkingLayer ( const Name& name )
|
||||
bool Technology::setSymbolicLayer ( const Name& name )
|
||||
{
|
||||
Layer* layer = getLayer ( name );
|
||||
if ( !layer ) return false;
|
||||
Layer* layer = getLayer( name );
|
||||
if (not layer) return false;
|
||||
|
||||
return setWorkingLayer ( layer );
|
||||
return setSymbolicLayer( layer );
|
||||
}
|
||||
|
||||
|
||||
bool Technology::setWorkingLayer ( const Layer* layer )
|
||||
bool Technology::setSymbolicLayer ( const Layer* layer )
|
||||
{
|
||||
bool found = false;
|
||||
LayerMaskMap::iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
||||
LayerMaskMap::iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
||||
LayerMaskMap::iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
|
||||
LayerMaskMap::iterator ub = _layerMaskMap.upper_bound( layer->getMask() );
|
||||
for ( ; lb != ub ; lb++ ) {
|
||||
if ( lb->second == layer ) {
|
||||
lb->second->setWorking ( true );
|
||||
if (lb->second == layer) {
|
||||
lb->second->setSymbolic( true );
|
||||
found = true;
|
||||
} else
|
||||
lb->second->setWorking ( false );
|
||||
lb->second->setSymbolic( false );
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -301,7 +301,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
|
||||
BasicLayer* gate = techno->getBasicLayer( get<string>(stack,"_gate" ) );
|
||||
BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
|
||||
|
@ -327,7 +327,7 @@ namespace Hurricane {
|
|||
, diffusion
|
||||
, well
|
||||
);
|
||||
layer->setWorking ( isWorking );
|
||||
layer->setSymbolic ( isSymbolic );
|
||||
layer->setExtentionCap ( gate , eCapGate );
|
||||
layer->setExtentionCap ( active , eCapActive );
|
||||
layer->setExtentionCap ( diffusion, eCapDiffusion );
|
||||
|
|
|
@ -267,7 +267,7 @@ namespace Hurricane {
|
|||
string smask = get<string> ( stack, "_mask" );
|
||||
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
|
||||
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
|
||||
bool isWorking = get<bool> ( stack, "_working" );
|
||||
bool isSymbolic = get<bool> ( stack, "_symbolic" );
|
||||
|
||||
BasicLayer* bottom = techno->getBasicLayer( get<string>(stack,"_bottom" ) );
|
||||
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
|
||||
|
@ -286,7 +286,7 @@ namespace Hurricane {
|
|||
, cut
|
||||
, top
|
||||
);
|
||||
layer->setWorking ( isWorking );
|
||||
layer->setSymbolic ( isSymbolic );
|
||||
layer->setEnclosure( bottom, bottomEncl );
|
||||
layer->setEnclosure( cut , cutEncl );
|
||||
layer->setEnclosure( top , topEncl );
|
||||
|
|
|
@ -68,10 +68,10 @@ namespace Hurricane {
|
|||
virtual const Layer* getTop () const;
|
||||
virtual const Layer* getBottom () const;
|
||||
virtual const Layer* getOpposite ( const Layer* ) const;
|
||||
Layer* getMetalAbove ( bool useWorking=true ) const;
|
||||
Layer* getMetalBelow ( bool useWorking=true ) const;
|
||||
Layer* getCutAbove ( bool useWorking=true ) const;
|
||||
Layer* getCutBelow ( bool useWorking=true ) const;
|
||||
Layer* getMetalAbove ( bool useSymbolic=true ) const;
|
||||
Layer* getMetalBelow ( bool useSymbolic=true ) const;
|
||||
Layer* getCutAbove ( bool useSymbolic=true ) const;
|
||||
Layer* getCutBelow ( bool useSymbolic=true ) const;
|
||||
virtual DbU::Unit getEnclosure () const;
|
||||
virtual DbU::Unit getExtentionCap () const;
|
||||
virtual DbU::Unit getExtentionWidth () const;
|
||||
|
@ -83,10 +83,10 @@ namespace Hurricane {
|
|||
inline bool below ( const Layer* layer ) const;
|
||||
bool contains ( const Layer* layer ) const;
|
||||
bool intersect ( const Layer* layer ) const;
|
||||
inline bool isWorking () const;
|
||||
inline bool isSymbolic () const;
|
||||
// Updators
|
||||
void setName ( const Name& name );
|
||||
inline void setWorking ( bool );
|
||||
inline void setSymbolic ( bool );
|
||||
void setMinimalSize ( const DbU::Unit& minimalSize );
|
||||
void setMinimalSpacing ( const DbU::Unit& minimalSpacing );
|
||||
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit );
|
||||
|
@ -112,7 +112,7 @@ namespace Hurricane {
|
|||
DbU::Unit _minimalSize;
|
||||
DbU::Unit _minimalSpacing;
|
||||
Layer* _nextOfTechnologyLayerMap;
|
||||
bool _working;
|
||||
bool _symbolic;
|
||||
|
||||
protected:
|
||||
// Internal: Constructors & Destructors.
|
||||
|
@ -133,7 +133,7 @@ namespace Hurricane {
|
|||
|
||||
|
||||
// Inline Functions.
|
||||
inline bool Layer::isWorking () const { return _working; }
|
||||
inline bool Layer::isSymbolic () const { return _symbolic; }
|
||||
inline bool Layer::above ( const Layer* layer ) const { return _mask > layer->getMask(); }
|
||||
inline bool Layer::below ( const Layer* layer ) const { return _mask < layer->getMask(); }
|
||||
inline Technology* Layer::getTechnology () const { return _technology; }
|
||||
|
@ -142,7 +142,7 @@ namespace Hurricane {
|
|||
inline const Layer::Mask& Layer::getExtractMask () const { return _extractMask; }
|
||||
inline const DbU::Unit& Layer::getMinimalSize () const { return _minimalSize; }
|
||||
inline const DbU::Unit& Layer::getMinimalSpacing () const { return _minimalSpacing; }
|
||||
inline void Layer::setWorking ( bool state ) { _working = state; }
|
||||
inline void Layer::setSymbolic ( bool state ) { _symbolic = state; }
|
||||
inline Layer* Layer::_getNextOfTechnologyLayerMap () const { return _nextOfTechnologyLayerMap; }
|
||||
inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; }
|
||||
inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; }
|
||||
|
|
|
@ -90,18 +90,18 @@ namespace Hurricane {
|
|||
BasicLayers getBasicLayers ( const Layer::Mask& ) const;
|
||||
RegularLayers getRegularLayers () const;
|
||||
ViaLayers getViaLayers () const;
|
||||
Layer* getLayer ( const Layer::Mask&, bool useWorking=true ) const;
|
||||
Layer* getMetalAbove ( const Layer*, bool useWorking=true ) const;
|
||||
Layer* getMetalBelow ( const Layer*, bool useWorking=true ) const;
|
||||
Layer* getCutAbove ( const Layer*, bool useWorking=true ) const;
|
||||
Layer* getCutBelow ( const Layer*, bool useWorking=true ) const;
|
||||
Layer* getViaBetween ( const Layer*, const Layer* ) const;
|
||||
Layer* getLayer ( const Layer::Mask&, bool useSymbolic=true ) const;
|
||||
Layer* getMetalAbove ( const Layer*, bool useSymbolic=true ) const;
|
||||
Layer* getMetalBelow ( const Layer*, bool useSymbolic=true ) const;
|
||||
Layer* getCutAbove ( const Layer*, bool useSymbolic=true ) const;
|
||||
Layer* getCutBelow ( const Layer*, bool useSymbolic=true ) const;
|
||||
Layer* getViaBetween ( const Layer*, const Layer*, bool useSymbolic=true ) const;
|
||||
Layer* getNthMetal ( int ) const;
|
||||
Layer* getNthCut ( int ) const;
|
||||
// Updators.
|
||||
void setName ( const Name& );
|
||||
bool setWorkingLayer ( const Name& );
|
||||
bool setWorkingLayer ( const Layer* );
|
||||
bool setSymbolicLayer ( const Name& );
|
||||
bool setSymbolicLayer ( const Layer* );
|
||||
// Others.
|
||||
inline LayerMap& _getLayerMap ();
|
||||
inline LayerMaskMap& _getLayerMaskMap ();
|
||||
|
|
|
@ -129,29 +129,29 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
# define accessorLayerFromOptBool(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
# define accessorLayerFromOptBool(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
||||
{ \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
cdebug_log(20,0) << #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; \
|
||||
PyObject* arg0 = NULL; \
|
||||
bool useSymbolic = true; \
|
||||
\
|
||||
if (PyArg_ParseTuple( args, "|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0)) { \
|
||||
if (arg0 != NULL) { \
|
||||
useWorking = PyObject_IsTrue(arg0); \
|
||||
useSymbolic = 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)); \
|
||||
rlayer = const_cast<SELF_TYPE*>(cobject->FUNC_NAME(useSymbolic)); \
|
||||
HCATCH \
|
||||
\
|
||||
if (rlayer == NULL) Py_RETURN_NONE; \
|
||||
|
@ -159,10 +159,10 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
# define predicateFromVoid(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
# define predicateFromVoid(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self ) \
|
||||
{ \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
\
|
||||
HTRY \
|
||||
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
||||
|
@ -199,7 +199,7 @@ extern "C" {
|
|||
# define updatorFromBasicLayerDbu(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
||||
{ \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
\
|
||||
HTRY \
|
||||
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
||||
|
@ -245,7 +245,7 @@ extern "C" {
|
|||
predicateFromLayer ( below ,PyLayer,Layer)
|
||||
predicateFromLayer ( contains ,PyLayer,Layer)
|
||||
predicateFromLayer ( intersect ,PyLayer,Layer)
|
||||
predicateFromVoid ( isWorking ,PyLayer,Layer)
|
||||
predicateFromVoid ( isSymbolic ,PyLayer,Layer)
|
||||
accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer)
|
||||
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
|
||||
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
|
||||
|
@ -269,6 +269,7 @@ extern "C" {
|
|||
updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer)
|
||||
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
|
||||
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
|
||||
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer)
|
||||
|
||||
// Standart destroy (Attribute).
|
||||
DBoDestroyAttribute(PyLayer_destroy, PyLayer)
|
||||
|
@ -319,12 +320,12 @@ extern "C" {
|
|||
, "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." }
|
||||
, { "isSymbolic" , (PyCFunction)PyLayer_isSymbolic , METH_NOARGS
|
||||
, "Tells if the layer is the symbolic 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." }
|
||||
, { "setSymbolic" , (PyCFunction)PyLayer_setSymbolic , METH_VARARGS
|
||||
, "Sets the layer as the symbolic one." }
|
||||
, { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS
|
||||
, "Sets the layer minimal size (width)." }
|
||||
, { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS
|
||||
|
|
|
@ -134,8 +134,8 @@ extern "C" {
|
|||
if (PyString_Check(arg0)) {
|
||||
layer = techno->getLayer(Name(PyString_AsString(arg0)));
|
||||
} else if (IsPyLayerMask(arg0)) {
|
||||
bool useWorking = (arg1 != NULL) ? PyObject_IsTrue(arg1) : true;
|
||||
layer = techno->getLayer(PYLAYERMASK_O(arg0), useWorking);
|
||||
bool useSymbolic = (arg1 != NULL) ? PyObject_IsTrue(arg1) : true;
|
||||
layer = techno->getLayer(PYLAYERMASK_O(arg0), useSymbolic);
|
||||
} else {
|
||||
PyErr_SetString(ConstructorError, "invalid number of parameters for getLayer.");
|
||||
return NULL;
|
||||
|
@ -188,26 +188,26 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PyTechnology_setWorkingLayer ( PyTechnology *self, PyObject* args ) {
|
||||
cdebug_log(20,0) << "Technology.setWorkingLayer()" << endl;
|
||||
static PyObject* PyTechnology_setSymbolicLayer ( PyTechnology *self, PyObject* args ) {
|
||||
cdebug_log(20,0) << "Technology.setSymbolicLayer()" << endl;
|
||||
|
||||
METHOD_HEAD("Technology.setWorkingLayer()")
|
||||
METHOD_HEAD("Technology.setSymbolicLayer()")
|
||||
|
||||
bool rvalue = false;
|
||||
|
||||
HTRY
|
||||
PyObject* arg0 = NULL;
|
||||
if (PyArg_ParseTuple(args,"O:Technology.setWorkingLayer", &arg0)) {
|
||||
if (PyArg_ParseTuple(args,"O:Technology.setSymbolicLayer", &arg0)) {
|
||||
if (PyString_Check(arg0)) {
|
||||
rvalue = techno->setWorkingLayer(Name(PyString_AsString(arg0)));
|
||||
rvalue = techno->setSymbolicLayer(Name(PyString_AsString(arg0)));
|
||||
} else if (IsPyLayer(arg0)) {
|
||||
rvalue = techno->setWorkingLayer(PYLAYER_O(arg0));
|
||||
rvalue = techno->setSymbolicLayer(PYLAYER_O(arg0));
|
||||
} else {
|
||||
PyErr_SetString(ConstructorError, "Hurricane.setWorkingLayer(): Invalid number of parameters.");
|
||||
PyErr_SetString(ConstructorError, "Hurricane.setSymbolicLayer(): Invalid number of parameters.");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(ConstructorError, "Hurricane.setWorkingLayer(): Bad parameter type.");
|
||||
PyErr_SetString(ConstructorError, "Hurricane.setSymbolicLayer(): Bad parameter type.");
|
||||
return NULL;
|
||||
}
|
||||
HCATCH
|
||||
|
@ -218,21 +218,21 @@ extern "C" {
|
|||
|
||||
|
||||
// Standart Accessors (Attributes).
|
||||
GetNameMethod (Technology,techno)
|
||||
SetNameMethod (Technology,techno)
|
||||
predicateFromLayer (isMetal ,PyTechnology,Technology)
|
||||
accessorAnyLayerFromName (getBasicLayer ,PyTechnology,Technology,BasicLayer )
|
||||
accessorAnyLayerFromName (getRegularLayer ,PyTechnology,Technology,RegularLayer)
|
||||
accessorAnyLayerFromName (getViaLayer ,PyTechnology,Technology,ViaLayer )
|
||||
accessorCollectionFromVoid (getLayers ,PyTechnology,Technology,Layer )
|
||||
accessorCollectionFromVoid (getRegularLayers,PyTechnology,Technology,RegularLayer)
|
||||
accessorCollectionFromVoid (getViaLayers ,PyTechnology,Technology,ViaLayer )
|
||||
accessorLayerFromLayerOptBool(getMetalAbove ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool(getMetalBelow ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool(getCutAbove ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool(getCutBelow ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerLayer (getViaBetween ,PyTechnology,Technology)
|
||||
accessorLayerFromInt (getNthMetal ,PyTechnology,Technology)
|
||||
GetNameMethod (Technology,techno)
|
||||
SetNameMethod (Technology,techno)
|
||||
predicateFromLayer (isMetal ,PyTechnology,Technology)
|
||||
accessorAnyLayerFromName (getBasicLayer ,PyTechnology,Technology,BasicLayer )
|
||||
accessorAnyLayerFromName (getRegularLayer ,PyTechnology,Technology,RegularLayer)
|
||||
accessorAnyLayerFromName (getViaLayer ,PyTechnology,Technology,ViaLayer )
|
||||
accessorCollectionFromVoid (getLayers ,PyTechnology,Technology,Layer )
|
||||
accessorCollectionFromVoid (getRegularLayers,PyTechnology,Technology,RegularLayer)
|
||||
accessorCollectionFromVoid (getViaLayers ,PyTechnology,Technology,ViaLayer )
|
||||
accessorLayerFromLayerOptBool (getMetalAbove ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool (getMetalBelow ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool (getCutAbove ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerOptBool (getCutBelow ,PyTechnology,Technology)
|
||||
accessorLayerFromLayerLayerOptBool(getViaBetween ,PyTechnology,Technology)
|
||||
accessorLayerFromInt (getNthMetal ,PyTechnology,Technology)
|
||||
|
||||
// Standard destroy (Attribute).
|
||||
DBoDestroyAttribute(PyTechnology_destroy, PyTechnology)
|
||||
|
@ -280,8 +280,8 @@ extern "C" {
|
|||
, "Returns Nth metal (zero is nearest substrate)." }
|
||||
, { "setName" , (PyCFunction)PyTechnology_setName , METH_VARARGS
|
||||
, "Allows to change the technology name." }
|
||||
, { "setWorkingLayer" , (PyCFunction)PyTechnology_setWorkingLayer , METH_VARARGS
|
||||
, "Mark a Layer as the working one (by name or by Layer)." }
|
||||
, { "setSymbolicLayer" , (PyCFunction)PyTechnology_setSymbolicLayer, METH_VARARGS
|
||||
, "Mark a Layer as the symbolic one (by name or by Layer)." }
|
||||
, { "destroy" , (PyCFunction)PyTechnology_destroy , METH_NOARGS
|
||||
, "Destroy associated hurricane object The python object remains." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
|
|
|
@ -457,9 +457,9 @@ extern "C" {
|
|||
HTRY \
|
||||
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
||||
\
|
||||
PyObject* arg0 = NULL; \
|
||||
PyObject* arg1 = NULL; \
|
||||
bool useWorking = true; \
|
||||
PyObject* arg0 = NULL; \
|
||||
PyObject* arg1 = NULL; \
|
||||
bool useSymbolic = true; \
|
||||
\
|
||||
if (PyArg_ParseTuple( args, "O|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0, &arg1)) { \
|
||||
if (not IsPyLayer(arg0)) { \
|
||||
|
@ -468,14 +468,14 @@ extern "C" {
|
|||
return NULL; \
|
||||
} \
|
||||
if (arg1 != NULL) { \
|
||||
useWorking = PyObject_IsTrue(arg1); \
|
||||
useSymbolic = PyObject_IsTrue(arg1); \
|
||||
} \
|
||||
} else { \
|
||||
PyErr_SetString ( ConstructorError \
|
||||
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
|
||||
return NULL; \
|
||||
} \
|
||||
rlayer = const_cast<Layer*>(cobject->FUNC_NAME( PYLAYER_O(arg0), useWorking) ); \
|
||||
rlayer = const_cast<Layer*>(cobject->FUNC_NAME( PYLAYER_O(arg0), useSymbolic) ); \
|
||||
HCATCH \
|
||||
\
|
||||
if (rlayer == NULL) Py_RETURN_NONE; \
|
||||
|
@ -515,6 +515,43 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
# define accessorLayerFromLayerLayerOptBool(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
||||
{ \
|
||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
\
|
||||
Layer* rlayer = NULL; \
|
||||
\
|
||||
HTRY \
|
||||
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
|
||||
\
|
||||
PyObject* arg0 = NULL; \
|
||||
PyObject* arg1 = NULL; \
|
||||
PyObject* arg2 = NULL; \
|
||||
bool useSymbolic = true; \
|
||||
\
|
||||
if (PyArg_ParseTuple( args, "OO|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0, &arg1, &arg2)) { \
|
||||
if (not IsPyLayer(arg0) or not IsPyLayer(arg1)) { \
|
||||
PyErr_SetString ( ConstructorError \
|
||||
, #SELF_TYPE"."#FUNC_NAME"(): First or second argument is not of Layer type." ); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (arg2 != NULL) { \
|
||||
useSymbolic = PyObject_IsTrue(arg2); \
|
||||
} \
|
||||
} else { \
|
||||
PyErr_SetString ( ConstructorError \
|
||||
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
|
||||
return NULL; \
|
||||
} \
|
||||
rlayer = const_cast<Layer*>(cobject->FUNC_NAME( PYLAYER_O(arg0), PYLAYER_O(arg1), useSymbolic ) ); \
|
||||
HCATCH \
|
||||
\
|
||||
if (rlayer == NULL) Py_RETURN_NONE; \
|
||||
return PyLayer_LinkDerived(rlayer); \
|
||||
}
|
||||
|
||||
|
||||
# define accessorLayerFromInt(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
||||
{ \
|
||||
|
|
Loading…
Reference in New Issue