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:
Jean-Paul Chaput 2017-12-27 13:13:29 +01:00
parent 24d5e9f172
commit 24d8fe5957
27 changed files with 414 additions and 345 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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'

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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().'

View File

@ -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()

View File

@ -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

View File

@ -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 );
}
}

View File

@ -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" );
}

View File

@ -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."

View File

@ -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;
}

View File

@ -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 );

View File

@ -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() ) {

View File

@ -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 );

View File

@ -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 );

View File

@ -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) );
}

View File

@ -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 );

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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; }

View File

@ -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 ();

View File

@ -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

View File

@ -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 */

View File

@ -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 ) \
{ \