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: # Provides standard settings for:
# - <viewerConfig> # - <viewerConfig>
# - <realLayersTable> # - <realLayersTable>
# - <compositeLayersTable>
# - <symbolicLayersTable> # - <symbolicLayersTable>
# - <workingLayersTable>
execfile( helpers.sysConfDir+'/common/technology.conf' ) 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). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which # * string: a synthetic way to designate the real or symbolic layer on
# it applies, an optional real layer in case where there is # which it applies, an optional sub layer (BasicLayer) in case
# more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda. # * 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) ( ('NWELL.nWell.extention.cap' , 4.0)
, ('PWELL.pWell.extention.cap' , 4.0) , ('PWELL.pWell.extention.cap' , 4.0)
@ -94,7 +96,7 @@ symbolicRulesTable = \
, ('POLY2.minimum.width' , 2.0) , ('POLY2.minimum.width' , 2.0)
, ('POLY2.poly2.extention.cap' , 2.0) , ('POLY2.poly2.extention.cap' , 2.0)
# Routing Layers. # Routing Layers (symbolic).
, ('METAL1.minimum.width' , 2.0) , ('METAL1.minimum.width' , 2.0)
, ('METAL1.metal1.extention.cap' , 2.0) , ('METAL1.metal1.extention.cap' , 2.0)
, ('METAL1.metal1.extention.width' , 0.5) , ('METAL1.metal1.extention.width' , 0.5)
@ -113,7 +115,7 @@ symbolicRulesTable = \
#, ('METAL8.minimum.width' , 2.0) #, ('METAL8.minimum.width' , 2.0)
#, ('METAL8.metal8.extention.cap' , 2.5) #, ('METAL8.metal8.extention.cap' , 2.5)
# Blockages. # Blockages (symbolic).
, ('BLOCKAGE1.minimum.width' , 3.0) , ('BLOCKAGE1.minimum.width' , 3.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 2.0) , ('BLOCKAGE1.blockage1.extention.cap' , 2.0)
, ('BLOCKAGE1.blockage1.extention.width', 0.5) , ('BLOCKAGE1.blockage1.extention.width', 0.5)
@ -132,7 +134,7 @@ symbolicRulesTable = \
#, ('BLOCKAGE8.minimum.width' , 2.0) #, ('BLOCKAGE8.minimum.width' , 2.0)
#, ('BLOCKAGE8.blockage6.extention.cap' , 4.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.minimum.side' , 2.0)
, ('CONT_BODY_N.nWell.enclosure' , 4.0) , ('CONT_BODY_N.nWell.enclosure' , 4.0)
, ('CONT_BODY_N.nImplant.enclosure' , 3.5) , ('CONT_BODY_N.nImplant.enclosure' , 3.5)
@ -159,7 +161,7 @@ symbolicRulesTable = \
, ('CONT_POLY.poly.enclosure' , 2.0) , ('CONT_POLY.poly.enclosure' , 2.0)
, ('CONT_POLY.metal1.enclosure' , 1.0) , ('CONT_POLY.metal1.enclosure' , 1.0)
# VIAs (i.e. Metal <--> Metal). # VIAs (i.e. Metal <--> Metal) (symbolic).
, ('VIA12.minimum.side' , 3.0) , ('VIA12.minimum.side' , 3.0)
, ('VIA12.metal1.enclosure' , 1.0) , ('VIA12.metal1.enclosure' , 1.0)
, ('VIA12.metal2.enclosure' , 1.0) , ('VIA12.metal2.enclosure' , 1.0)

View File

@ -5,8 +5,8 @@
# Provides standard settings for: # Provides standard settings for:
# - <viewerConfig> # - <viewerConfig>
# - <realLayersTable> # - <realLayersTable>
# - <compositeLayersTable>
# - <symbolicLayersTable> # - <symbolicLayersTable>
# - <workingLayersTable>
from Hurricane import DbU 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). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which # * string: a synthetic way to designate the real or symbolic layer on
# it applies, an optional real layer in case where there is # which it applies, an optional sub layer (BasicLayer) in case
# more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda. # * value : the rule (dimension) value. If the main layer is symbolic it
symbolicRulesTable = \ # 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) ( ('NWELL.nWell.extention.cap' , 0.0)
, ('PWELL.pWell.extention.cap' , 0.0) , ('PWELL.pWell.extention.cap' , 0.0)
@ -82,7 +85,7 @@ symbolicRulesTable = \
, ('POLY2.minimum.width' , 1.0) , ('POLY2.minimum.width' , 1.0)
, ('POLY2.poly.extention.cap' , 0.5) , ('POLY2.poly.extention.cap' , 0.5)
# Routing Layers. # Routing Layers (symbolic).
, ('METAL1.minimum.width' , 1.0) , ('METAL1.minimum.width' , 1.0)
, ('METAL1.metal1.extention.cap' , 0.5) , ('METAL1.metal1.extention.cap' , 0.5)
, ('METAL2.minimum.width' , 1.0) , ('METAL2.minimum.width' , 1.0)
@ -104,7 +107,7 @@ symbolicRulesTable = \
, ('METAL10.minimum.width' , 2.0) , ('METAL10.minimum.width' , 2.0)
, ('METAL10.metal10.extention.cap' , 1.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.minimum.side' , 1.0)
, ('CONT_BODY_N.nWell.enclosure' , 1.5) , ('CONT_BODY_N.nWell.enclosure' , 1.5)
, ('CONT_BODY_N.nImplant.enclosure' , 1.5) , ('CONT_BODY_N.nImplant.enclosure' , 1.5)
@ -131,7 +134,7 @@ symbolicRulesTable = \
, ('CONT_POLY.poly.enclosure' , 0.5) , ('CONT_POLY.poly.enclosure' , 0.5)
, ('CONT_POLY.metal1.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.minimum.side' , 1.0)
, ('VIA12.metal1.enclosure' , 0.5) , ('VIA12.metal1.enclosure' , 0.5)
, ('VIA12.metal2.enclosure' , 0.5) , ('VIA12.metal2.enclosure' , 0.5)
@ -160,7 +163,7 @@ symbolicRulesTable = \
, ('VIA910.metal9.enclosure' , 0.5) , ('VIA910.metal9.enclosure' , 0.5)
, ('VIA910.metal10.enclosure' , 0.5) , ('VIA910.metal10.enclosure' , 0.5)
# Blockages. # Blockages (symbolic).
, ('BLOCKAGE1.minimum.width' , 1.0) , ('BLOCKAGE1.minimum.width' , 1.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5) , ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
, ('BLOCKAGE2.minimum.width' , 2.0) , ('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. # 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 # In some case, the last of the list may be optional, it must be
# sets to None and not left empty. # sets to None and not left empty.
# #
# ('SYMB_LAYER' , Type , (LIST_OF_REAL_LAYERS) ) # ('SYMB_LAYER' , Type , (LIST_OF_REAL_LAYERS) )
symbolicLayersTable = \ compositeLayersTable = \
( ('NWELL' , TypeRegular , ('nWell' ,)) ( ('NWELL' , TypeRegular , ('nWell' ,))
, ('PWELL' , TypeRegular , ('pWell' ,)) , ('PWELL' , TypeRegular , ('pWell' ,))
, ('NTIE' , TypeDiffusion , ('nImplant' , 'active', 'nWell')) , ('NTIE' , TypeDiffusion , ('nImplant' , 'active', 'nWell'))
@ -118,6 +118,17 @@ symbolicLayersTable = \
, ('CONT_DIF_N' , TypeContact , ('nImplant' , 'active', 'cut0', 'metal1', None )) , ('CONT_DIF_N' , TypeContact , ('nImplant' , 'active', 'cut0', 'metal1', None ))
, ('CONT_DIF_P' , TypeContact , ('pImplant' , 'active', 'cut0', 'metal1', None )) , ('CONT_DIF_P' , TypeContact , ('pImplant' , 'active', 'cut0', 'metal1', None ))
, ('CONT_POLY' , TypeVia , ( 'poly' , 'cut0', 'metal1' )) , ('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' )) , ('VIA12' , TypeVia , ( 'metal1', 'cut1', 'metal2' ))
, ('VIA23' , TypeVia , ( 'metal2', 'cut2', 'metal3' )) , ('VIA23' , TypeVia , ( 'metal2', 'cut2', 'metal3' ))
, ('VIA23cap' , TypeVia , ( 'metcap', 'cut2', 'metal3' )) , ('VIA23cap' , TypeVia , ( 'metcap', 'cut2', 'metal3' ))
@ -142,12 +153,11 @@ symbolicLayersTable = \
) )
# Format of <workingLayersTable>: # Format of <symbolicLayersTable>:
# This is a simple list of Real & Symbolic layers. # This is a simple list of Symbolic layers.
workingLayersTable = \ symbolicLayersTable = \
[ 'cut0', 'cut1' , 'cut2' , 'cut3' , 'cut4' , 'cut5' , 'cut6' , 'cut7' , 'cut8' , 'cut9' [ 'POLY', 'POLY2'
, 'POLY', 'POLY2'
, 'METAL1' , 'METAL2' , 'METAL3' , 'METAL4' , 'METAL5' , 'METAL6' , 'METAL7' , 'METAL8' , 'METAL9' , 'METAL10' , 'METAL1' , 'METAL2' , 'METAL3' , 'METAL4' , 'METAL5' , 'METAL6' , 'METAL7' , 'METAL8' , 'METAL9' , 'METAL10'
, 'BLOCKAGE1', 'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4', 'BLOCKAGE5', 'BLOCKAGE6', 'BLOCKAGE7', 'BLOCKAGE8', 'BLOCKAGE9', 'BLOCKAGE10' , 'BLOCKAGE1', 'BLOCKAGE2', 'BLOCKAGE3', 'BLOCKAGE4', 'BLOCKAGE5', 'BLOCKAGE6', 'BLOCKAGE7', 'BLOCKAGE8', 'BLOCKAGE9', 'BLOCKAGE10'
, 'VIA12' , 'VIA23' , 'VIA34' , 'VIA45' , 'VIA56' , 'VIA67' , 'VIA78' , 'VIA89' , 'VIA910' , 'VIA12' , 'VIA23' , 'VIA34' , 'VIA45' , 'VIA56' , 'VIA67' , 'VIA78' , 'VIA89' , 'VIA910'

View File

@ -9,8 +9,8 @@ from Hurricane import DbU
# Provides standard settings for: # Provides standard settings for:
# - <viewerConfig> # - <viewerConfig>
# - <realLayersTable> # - <realLayersTable>
# - <compositeLayersTable>
# - <symbolicLayersTable> # - <symbolicLayersTable>
# - <workingLayersTable>
execfile( helpers.sysConfDir+'/common/technology.conf' ) 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). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which # * string: a synthetic way to designate the real or symbolic layer on
# it applies, an optional real layer in case where there is # which it applies, an optional sub layer (BasicLayer) in case
# more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda. # * value : the rule (dimension) value. If the main layer is symbolic it
symbolicRulesTable = \ # 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) ( ('NWELL.nWell.extention.cap' , 0.0)
, ('PWELL.pWell.extention.cap' , 0.0) , ('PWELL.pWell.extention.cap' , 0.0)
@ -100,7 +103,7 @@ symbolicRulesTable = \
, ('METAL8.minimum.width' , 2.0) , ('METAL8.minimum.width' , 2.0)
, ('METAL8.metal6.extention.cap' , 1.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.minimum.side' , 1.0)
, ('CONT_BODY_N.nWell.enclosure' , 1.5) , ('CONT_BODY_N.nWell.enclosure' , 1.5)
, ('CONT_BODY_N.nImplant.enclosure' , 1.5) , ('CONT_BODY_N.nImplant.enclosure' , 1.5)
@ -127,7 +130,7 @@ symbolicRulesTable = \
, ('CONT_POLY.poly.enclosure' , 0.5) , ('CONT_POLY.poly.enclosure' , 0.5)
, ('CONT_POLY.metal1.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.minimum.side' , 1.0)
, ('VIA12.metal1.enclosure' , 0.5) , ('VIA12.metal1.enclosure' , 0.5)
, ('VIA12.metal2.enclosure' , 0.5) , ('VIA12.metal2.enclosure' , 0.5)
@ -150,7 +153,7 @@ symbolicRulesTable = \
, ('VIA78.metal7.enclosure' , 0.5) , ('VIA78.metal7.enclosure' , 0.5)
, ('VIA78.metal8.enclosure' , 0.5) , ('VIA78.metal8.enclosure' , 0.5)
# Blockages. # Blockages (symbolic).
, ('BLOCKAGE1.minimum.width' , 1.0) , ('BLOCKAGE1.minimum.width' , 1.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5) , ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
, ('BLOCKAGE2.minimum.width' , 2.0) , ('BLOCKAGE2.minimum.width' , 2.0)

View File

@ -6,8 +6,8 @@ from Hurricane import DbU
# Provides standard settings for: # Provides standard settings for:
# - <viewerConfig> # - <viewerConfig>
# - <realLayersTable> # - <realLayersTable>
# - <compositeLayersTable>
# - <symbolicLayersTable> # - <symbolicLayersTable>
# - <workingLayersTable>
execfile( helpers.sysConfDir+'/common/technology.conf' ) 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). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which # * string: a synthetic way to designate the real or symbolic layer on
# it applies, an optional real layer in case where there is # which it applies, an optional sub layer (BasicLayer) in case
# more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda. # * value : the rule (dimension) value. If the main layer is symbolic it
symbolicRulesTable = \ # 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) ( ('NWELL.nWell.extention.cap' , 0.0)
, ('PWELL.pWell.extention.cap' , 0.0) , ('PWELL.pWell.extention.cap' , 0.0)
@ -79,7 +82,7 @@ symbolicRulesTable = \
, ('POLY2.minimum.width' , 1.0) , ('POLY2.minimum.width' , 1.0)
, ('POLY2.poly.extention.cap' , 0.5) , ('POLY2.poly.extention.cap' , 0.5)
# Routing Layers. # Routing Layers (symbolic).
, ('METAL1.minimum.width' , 1.0) , ('METAL1.minimum.width' , 1.0)
, ('METAL1.metal1.extention.cap' , 0.5) , ('METAL1.metal1.extention.cap' , 0.5)
, ('METAL2.minimum.width' , 1.0) , ('METAL2.minimum.width' , 1.0)
@ -97,7 +100,7 @@ symbolicRulesTable = \
, ('METAL8.minimum.width' , 2.0) , ('METAL8.minimum.width' , 2.0)
, ('METAL8.metal6.extention.cap' , 1.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.minimum.side' , 1.0)
, ('CONT_BODY_N.nWell.enclosure' , 1.5) , ('CONT_BODY_N.nWell.enclosure' , 1.5)
, ('CONT_BODY_N.nImplant.enclosure' , 1.5) , ('CONT_BODY_N.nImplant.enclosure' , 1.5)
@ -124,7 +127,7 @@ symbolicRulesTable = \
, ('CONT_POLY.poly.enclosure' , 0.5) , ('CONT_POLY.poly.enclosure' , 0.5)
, ('CONT_POLY.metal1.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.minimum.side' , 1.0)
, ('VIA12.metal1.enclosure' , 0.5) , ('VIA12.metal1.enclosure' , 0.5)
, ('VIA12.metal2.enclosure' , 0.5) , ('VIA12.metal2.enclosure' , 0.5)
@ -147,7 +150,7 @@ symbolicRulesTable = \
, ('VIA78.metal7.enclosure' , 0.5) , ('VIA78.metal7.enclosure' , 0.5)
, ('VIA78.metal8.enclosure' , 0.5) , ('VIA78.metal8.enclosure' , 0.5)
# Blockages. # Blockages (symbolic).
, ('BLOCKAGE1.minimum.width' , 1.0) , ('BLOCKAGE1.minimum.width' , 1.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5) , ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
, ('BLOCKAGE2.minimum.width' , 2.0) , ('BLOCKAGE2.minimum.width' , 2.0)

View File

@ -8,20 +8,22 @@ import helpers
# Provides standard settings for: # Provides standard settings for:
# - <viewerConfig> # - <viewerConfig>
# - <realLayersTable> # - <realLayersTable>
# - <compositeLayersTable>
# - <symbolicLayersTable> # - <symbolicLayersTable>
# - <workingLayersTable>
execfile( helpers.sysConfDir+'/common/technology.conf' ) execfile( helpers.sysConfDir+'/common/technology.conf' )
# Format of <symbolicRulesTable>: # Format of <layersExtensionsTable>:
# Each entry is a pair of (string, value). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which # * string: a synthetic way to designate the real or symbolic layer on
# it applies, an optional real layer in case where there is # which it applies, an optional sub layer (BasicLayer) in case
# more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda. # * 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) ( ('NWELL.nWell.extention.cap' , 4.0)
, ('PWELL.pWell.extention.cap' , 4.0) , ('PWELL.pWell.extention.cap' , 4.0)
@ -79,7 +81,7 @@ symbolicRulesTable = \
, ('POLY2.minimum.width' , 2.0) , ('POLY2.minimum.width' , 2.0)
, ('POLY2.poly2.extention.cap' , 2.0) , ('POLY2.poly2.extention.cap' , 2.0)
# Routing Layers. # Routing Layers (symbolic).
, ('METAL1.minimum.width' , 1.0) , ('METAL1.minimum.width' , 1.0)
, ('METAL1.metal1.extention.cap' , 2.0) , ('METAL1.metal1.extention.cap' , 2.0)
, ('METAL2.minimum.width' , 1.0) , ('METAL2.minimum.width' , 1.0)
@ -97,7 +99,7 @@ symbolicRulesTable = \
, ('METAL8.minimum.width' , 2.0) , ('METAL8.minimum.width' , 2.0)
, ('METAL8.metal6.extention.cap' , 4.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.minimum.side' , 2.0)
, ('CONT_BODY_N.nWell.enclosure' , 3.0) , ('CONT_BODY_N.nWell.enclosure' , 3.0)
, ('CONT_BODY_N.nImplant.enclosure' , 3.0) , ('CONT_BODY_N.nImplant.enclosure' , 3.0)
@ -124,7 +126,7 @@ symbolicRulesTable = \
, ('CONT_POLY.poly.enclosure' , 2.0) , ('CONT_POLY.poly.enclosure' , 2.0)
, ('CONT_POLY.metal1.enclosure' , 1.0) , ('CONT_POLY.metal1.enclosure' , 1.0)
# VIAs (i.e. Metal <--> Metal). # VIAs (i.e. Metal <--> Metal) (symbolic).
, ('VIA12.minimum.side' , 2.0) , ('VIA12.minimum.side' , 2.0)
, ('VIA12.metal1.enclosure' , 1.0) , ('VIA12.metal1.enclosure' , 1.0)
, ('VIA12.metal2.enclosure' , 1.0) , ('VIA12.metal2.enclosure' , 1.0)
@ -147,7 +149,7 @@ symbolicRulesTable = \
, ('VIA78.metal7.enclosure' , 3.0) , ('VIA78.metal7.enclosure' , 3.0)
, ('VIA78.metal8.enclosure' , 3.0) , ('VIA78.metal8.enclosure' , 3.0)
# Blockages. # Blockages (symbolic).
, ('BLOCKAGE1.minimum.width' , 1.0) , ('BLOCKAGE1.minimum.width' , 1.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 2.0) , ('BLOCKAGE1.blockage1.extention.cap' , 2.0)
, ('BLOCKAGE2.minimum.width' , 2.0) , ('BLOCKAGE2.minimum.width' , 2.0)

View File

@ -75,21 +75,21 @@ SystemMandatory = 0x0100
def coriolisConfigure(): def coriolisConfigure():
confHelpers = ( ('allianceConfig' , Alliance.loadAllianceConfig , SystemMandatory|AllianceHelper) confHelpers = ( ('technoConfig' , Technology.loadTechnoConfig , SystemMandatory|TechnologyHelper)
, ('routingGaugesTable' , Alliance.loadRoutingGaugesTable, SystemMandatory|KiteHelper) , ('allianceConfig' , Alliance.loadAllianceConfig , SystemMandatory|AllianceHelper)
, ('cellGaugesTable' , Alliance.loadCellGaugesTable , SystemMandatory|KiteHelper) , ('routingGaugesTable' , Alliance.loadRoutingGaugesTable, SystemMandatory|KiteHelper)
, ('viewerConfig' , Technology.loadViewerConfig , SystemMandatory|TechnologyHelper) , ('cellGaugesTable' , Alliance.loadCellGaugesTable , SystemMandatory|KiteHelper)
, ('realLayersTable' , Technology.loadRealLayers , SystemMandatory|TechnologyHelper) , ('viewerConfig' , Technology.loadViewerConfig , SystemMandatory|TechnologyHelper)
, ('symbolicLayersTable', Technology.loadSymbolicLayers , SystemMandatory|TechnologyHelper) , ('realLayersTable' , Technology.loadRealLayers , SystemMandatory|TechnologyHelper)
, ('symbolicRulesTable' , Technology.loadSymbolicRules , SystemMandatory|TechnologyHelper) , ('compositeLayersTable' , Technology.loadCompositeLayers , SystemMandatory|TechnologyHelper)
, ('workingLayersTable' , Technology.loadWorkingLayers , SystemMandatory|TechnologyHelper) , ('symbolicLayersTable' , Technology.tagSymbolicLayers , SystemMandatory|TechnologyHelper)
, ('technoConfig' , Technology.loadTechnoConfig , SystemMandatory|TechnologyHelper) , ('layersExtensionsTable', Technology.loadLayersExtensions, SystemMandatory|TechnologyHelper)
, ('gdsLayersTable' , Technology.loadGdsLayers , SystemMandatory|TechnologyHelper) , ('gdsLayersTable' , Technology.loadGdsLayers , SystemMandatory|TechnologyHelper)
, ('patternsTable' , Patterns.loadPatterns , SystemMandatory|PatternsHelper) , ('patternsTable' , Patterns.loadPatterns , SystemMandatory|PatternsHelper)
, ('stylesTable' , Display.loadStyles , SystemMandatory|DisplayHelper) , ('stylesTable' , Display.loadStyles , SystemMandatory|DisplayHelper)
, ('defaultStyle' , Display.loadDefaultStyle , SystemMandatory|DisplayHelper) , ('defaultStyle' , Display.loadDefaultStyle , SystemMandatory|DisplayHelper)
, ('parametersTable' , Configuration.loadParameters , ConfigurationHelper) , ('parametersTable' , Configuration.loadParameters , ConfigurationHelper)
, ('layoutTable' , Configuration.loadLayout , ConfigurationHelper) , ('layoutTable' , Configuration.loadLayout , ConfigurationHelper)
) )
print ' o Running configuration hook: coriolisConfigure().' print ' o Running configuration hook: coriolisConfigure().'

View File

@ -51,7 +51,7 @@ def Alliance ( db ):
print " Minimal spacing :", DbU.toLambda(rlayer.getMinimalSpacing()) print " Minimal spacing :", DbU.toLambda(rlayer.getMinimalSpacing())
print " Pitch :", DbU.toLambda(rlayer.getPitch()) print " Pitch :", DbU.toLambda(rlayer.getPitch())
print " Cut above :", rlayer.getCutAbove() print " Cut above :", rlayer.getCutAbove()
print " isWorking :", rlayer.isWorking() print " isSymbolic :", rlayer.isSymbolic()
dlayer = technology.getLayer('NDIF') dlayer = technology.getLayer('NDIF')
print 'NDIF', dlayer.getMask() print 'NDIF', dlayer.getMask()

View File

@ -16,12 +16,13 @@ from Hurricane import ContactLayer
from Hurricane import ViaLayer from Hurricane import ViaLayer
from CRL import AllianceFramework from CRL import AllianceFramework
from helpers import ErrorMessage from helpers import ErrorMessage
from helpers import toDbU
technologyFile = '<No technology file specified>' technologyFile = '<No technology file specified>'
class SymbolicLayerType ( object ): class CompositeLayerType ( object ):
Regular = 1 Regular = 1
Diffusion = 2 Diffusion = 2
@ -37,54 +38,54 @@ class SymbolicLayerType ( object ):
return self._code return self._code
def __str__ ( self ): def __str__ ( self ):
if self._code == SymbolicLayerType.Regular: return 'TypeRegular' if self._code == CompositeLayerType.Regular: return 'TypeRegular'
if self._code == SymbolicLayerType.Diffusion: return 'TypeDiffusion' if self._code == CompositeLayerType.Diffusion: return 'TypeDiffusion'
if self._code == SymbolicLayerType.Transistor: return 'TypeTransistor' if self._code == CompositeLayerType.Transistor: return 'TypeTransistor'
if self._code == SymbolicLayerType.Contact: return 'TypeContact' if self._code == CompositeLayerType.Contact: return 'TypeContact'
if self._code == SymbolicLayerType.Via: return 'TypeVia' if self._code == CompositeLayerType.Via: return 'TypeVia'
return 'TypeUnknown (%d)', self._code return 'TypeUnknown (%d)', self._code
def __repr__ ( self ): def __repr__ ( self ):
return str(self) return str(self)
def realLayerLength ( self ): def realLayerLength ( self ):
if self._code == SymbolicLayerType.Regular: return 1 if self._code == CompositeLayerType.Regular: return 1
if self._code == SymbolicLayerType.Diffusion: return 3 if self._code == CompositeLayerType.Diffusion: return 3
if self._code == SymbolicLayerType.Transistor: return 4 if self._code == CompositeLayerType.Transistor: return 4
if self._code == SymbolicLayerType.Contact: return 5 if self._code == CompositeLayerType.Contact: return 5
if self._code == SymbolicLayerType.Via: return 3 if self._code == CompositeLayerType.Via: return 3
return 0 return 0
TypeRegular = SymbolicLayerType(SymbolicLayerType.Regular) TypeRegular = CompositeLayerType(CompositeLayerType.Regular)
TypeDiffusion = SymbolicLayerType(SymbolicLayerType.Diffusion) TypeDiffusion = CompositeLayerType(CompositeLayerType.Diffusion)
TypeTransistor = SymbolicLayerType(SymbolicLayerType.Transistor) TypeTransistor = CompositeLayerType(CompositeLayerType.Transistor)
TypeContact = SymbolicLayerType(SymbolicLayerType.Contact) TypeContact = CompositeLayerType(CompositeLayerType.Contact)
TypeVia = SymbolicLayerType(SymbolicLayerType.Via) TypeVia = CompositeLayerType(CompositeLayerType.Via)
class LayersLUT ( object ): class LayersLUT ( object ):
Real = 0x1 Real = 0x1
Symbolic = 0x2 Composite = 0x2
MissingError = 0x8 MissingError = 0x8
def __init__ ( self ): def __init__ ( self ):
self._realLayers = {} self._realLayers = {}
self._symbolicLayers = {} self._compositeLayers = {}
return return
def add ( self, layer ): def add ( self, layer ):
if isinstance(layer,BasicLayer): self._realLayers [ layer.getName() ] = layer if isinstance(layer,BasicLayer): self._realLayers [ layer.getName() ] = layer
else: self._symbolicLayers[ layer.getName() ] = layer else: self._compositeLayers[ layer.getName() ] = layer
return return
def lookup ( self, name, flags=Real|Symbolic ): def lookup ( self, name, flags=Real|Composite ):
layer = None layer = None
if flags & LayersLUT.Real and self._realLayers.has_key(name): if flags & LayersLUT.Real and self._realLayers.has_key(name):
layer = self._realLayers[name] layer = self._realLayers[name]
if flags & LayersLUT.Symbolic and self._symbolicLayers.has_key(name): if flags & LayersLUT.Composite and self._compositeLayers.has_key(name):
layer = self._symbolicLayers[name] layer = self._compositeLayers[name]
if not layer and flags&LayersLUT.MissingError: if not layer and flags&LayersLUT.MissingError:
raise ErrorMessage(1,['Layer <%s> is not defined (yet?).'%name]) raise ErrorMessage(1,['Layer <%s> is not defined (yet?).'%name])
@ -135,25 +136,25 @@ def loadRealLayers ( realLayersTable, confFile ):
return return
def loadSymbolicLayers ( symbolicLayersData, confFile ): def loadCompositeLayers ( compositeLayersData, confFile ):
global technologyFile global technologyFile
technologyFile = confFile technologyFile = confFile
technology = DataBase.getDB().getTechnology() technology = DataBase.getDB().getTechnology()
entryNo = 0 entryNo = 0
for entry in symbolicLayersData: for entry in compositeLayersData:
entryNo += 1 entryNo += 1
try: try:
if len(entry) != 3: 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,) ).' ,'Must contains exactly three fields: ( name, type, (real_layers,) ).'
,str(entry) ,str(entry)
]) ])
name, layerType, realLayers = entry name, layerType, realLayers = entry
if not isinstance(layerType,SymbolicLayerType): if not isinstance(layerType,CompositeLayerType):
raise ErrorMessage(1,['Invalid entry in <symbolicLayersTable>.' raise ErrorMessage(1,['Invalid entry in <compositeLayersTable>.'
,'The layer type code is not valid, should be any of:' ,'The layer type code is not valid, should be any of:'
,' * TypeRegular' ,' * TypeRegular'
,' * TypeDiffusion' ,' * TypeDiffusion'
@ -163,7 +164,7 @@ def loadSymbolicLayers ( symbolicLayersData, confFile ):
,str(entry) ,str(entry)
]) ])
if layerType.realLayerLength() != len(realLayers): 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.' \ ,'Layer of type <%s> contains %d real layers instead of %d.' \
% (layerType,len(realLayers),layerType.realLayerLength()) % (layerType,len(realLayers),layerType.realLayerLength())
,str(entry) ,str(entry)
@ -174,64 +175,66 @@ def loadSymbolicLayers ( symbolicLayersData, confFile ):
if layerName: if layerName:
realLayersArgs += [ layersLUT.lookup(layerName realLayersArgs += [ layersLUT.lookup(layerName
,LayersLUT.Real ,LayersLUT.Real
|LayersLUT.Symbolic |LayersLUT.Composite
|LayersLUT.MissingError) ] |LayersLUT.MissingError) ]
else: else:
realLayersArgs += [ None ] realLayersArgs += [ None ]
symbolicLayer = None compositeLayer = None
if layerType == TypeRegular: if layerType == TypeRegular:
symbolicLayer = RegularLayer.create(technology,entry[0]) compositeLayer = RegularLayer.create(technology,entry[0])
symbolicLayer.setBasicLayer( *realLayersArgs ) compositeLayer.setBasicLayer( *realLayersArgs )
elif layerType == TypeDiffusion: elif layerType == TypeDiffusion:
symbolicLayer = DiffusionLayer.create(technology ,entry[0], *realLayersArgs) compositeLayer = DiffusionLayer.create(technology ,entry[0], *realLayersArgs)
elif layerType == TypeTransistor: elif layerType == TypeTransistor:
symbolicLayer = TransistorLayer.create(technology ,entry[0], *realLayersArgs) compositeLayer = TransistorLayer.create(technology ,entry[0], *realLayersArgs)
elif layerType == TypeContact: elif layerType == TypeContact:
symbolicLayer = ContactLayer.create(technology ,entry[0], *realLayersArgs) compositeLayer = ContactLayer.create(technology ,entry[0], *realLayersArgs)
elif layerType == TypeVia: 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: 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 return
def loadSymbolicRules ( symbolicRulesTable, confFile ): def loadLayersExtensions ( layersExtensionsTable, confFile ):
global technologyFile global technologyFile
technologyFile = confFile technologyFile = confFile
technology = DataBase.getDB().getTechnology() technology = DataBase.getDB().getTechnology()
entryNo = 0 entryNo = 0
for rule in symbolicRulesTable: for rule in layersExtensionsTable:
entryNo += 1 entryNo += 1
try: try:
if len(rule) != 2: 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 ).' ,'Must contains exactly two fields: ( rule_path, value ).'
,str(rule) ,str(rule)
]) ])
if not isinstance(rule[1],int) and not isinstance(rule[1],float): 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.' ,'Rule value must be of integer or float type.'
,str(rule) ,str(rule)
]) ])
value = DbU.fromLambda(rule[1])
elements = rule[0].split('.') elements = rule[0].split('.')
if len(elements) < 3: 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\".' ,'Rule name must contains at least three components: \"LAYER.category.dimension\".'
,str(rule) ,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 ) 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:],'.') if subLayer: ruleTag = string.join(elements[2:],'.')
else: ruleTag = string.join(elements[1:],'.') else: ruleTag = string.join(elements[1:],'.')
@ -241,7 +244,7 @@ def loadSymbolicRules ( symbolicRulesTable, confFile ):
elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value ) elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value )
elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value ) elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value )
else: else:
raise ErrorMessage(1,['Invalid entry in <symbolicRulesTable>.' raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
,'Unknown rule kind: \".%s\", should be any of:' % ruleTag ,'Unknown rule kind: \".%s\", should be any of:' % ruleTag
,' * "RULE_HEAD.extention.cap"' ,' * "RULE_HEAD.extention.cap"'
,' * "RULE_HEAD.extention.width"' ,' * "RULE_HEAD.extention.width"'
@ -252,24 +255,24 @@ def loadSymbolicRules ( symbolicRulesTable, confFile ):
]) ])
except Exception, e: 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 return
def loadWorkingLayers ( workingLayersTable, confFile ): def tagSymbolicLayers ( symbolicLayersTable, confFile ):
global technologyFile global technologyFile
technologyFile = confFile technologyFile = confFile
technology = DataBase.getDB().getTechnology() technology = DataBase.getDB().getTechnology()
entryNo = 0 entryNo = 0
for layerName in workingLayersTable: for layerName in symbolicLayersTable:
entryNo += 1 entryNo += 1
try: try:
# This call is just to generate an error if the layer is non-existent. # This call is just to generate an error if the layer is non-existent.
layersLUT.lookup(layerName,LayersLUT.Real|LayersLUT.Symbolic|LayersLUT.MissingError) layersLUT.lookup(layerName,LayersLUT.Real|LayersLUT.Composite|LayersLUT.MissingError)
technology.setWorkingLayer(layerName) technology.setSymbolicLayer(layerName)
except Exception, e: 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 return

View File

@ -43,6 +43,7 @@ namespace CRL {
using Hurricane::JsonTypes; using Hurricane::JsonTypes;
using Hurricane::JsonArray; using Hurricane::JsonArray;
using Hurricane::DataBase; using Hurricane::DataBase;
using Hurricane::BasicLayer;
using Hurricane::ViaLayer; using Hurricane::ViaLayer;
using Hurricane::getCollection; using Hurricane::getCollection;
@ -219,22 +220,23 @@ namespace CRL {
void RoutingGauge::addLayerGauge ( RoutingLayerGauge* layerGauge ) void RoutingGauge::addLayerGauge ( RoutingLayerGauge* layerGauge )
{ {
if ( getLayerGauge(layerGauge->getLayer()) != NULL ) if (getLayerGauge(layerGauge->getLayer()) != NULL)
throw Error ( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str() throw Error( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str()
, getString(_name).c_str() ); , getString(_name).c_str() );
_layerGauges.push_back ( layerGauge ); _layerGauges.push_back( layerGauge );
size_t gaugeSize = _layerGauges.size(); size_t gaugeSize = _layerGauges.size();
if ( gaugeSize > 1 ) { if (gaugeSize > 1) {
Layer* viaLayer = _technology->getViaBetween(_layerGauges[gaugeSize-2]->getLayer() Layer* viaLayer = _technology->getViaBetween( _layerGauges[gaugeSize-2]->getLayer()
,_layerGauges[gaugeSize-1]->getLayer()); , _layerGauges[gaugeSize-1]->getLayer()
if ( !viaLayer ) { , _layerGauges[gaugeSize-1]->getLayer()->isSymbolic() );
cerr << Error("Can't find a VIA between Gauge layers %s and %s." if (not viaLayer) {
,getString(_layerGauges[gaugeSize-2]).c_str() cerr << Error( "Can't find a VIA between Gauge layers %s and %s."
,getString(_layerGauges[gaugeSize-1]).c_str()) << endl; , 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 () void SymbolicTechnologyParser::_postLoad ()
{ {
// Fixme. // Fixme.
_technology->setWorkingLayer ( "cut0" ); _technology->setSymbolicLayer ( "POLY" );
_technology->setWorkingLayer ( "cut1" ); _technology->setSymbolicLayer ( "METAL1" );
_technology->setWorkingLayer ( "cut2" ); _technology->setSymbolicLayer ( "METAL2" );
_technology->setWorkingLayer ( "cut3" ); _technology->setSymbolicLayer ( "METAL3" );
_technology->setWorkingLayer ( "cut4" ); _technology->setSymbolicLayer ( "METAL4" );
_technology->setWorkingLayer ( "cut5" ); _technology->setSymbolicLayer ( "METAL5" );
_technology->setWorkingLayer ( "gcut" ); _technology->setSymbolicLayer ( "METAL6" );
_technology->setWorkingLayer ( "POLY" ); _technology->setSymbolicLayer ( "BLOCKAGE1" );
_technology->setWorkingLayer ( "METAL1" ); _technology->setSymbolicLayer ( "BLOCKAGE2" );
_technology->setWorkingLayer ( "METAL2" ); _technology->setSymbolicLayer ( "BLOCKAGE3" );
_technology->setWorkingLayer ( "METAL3" ); _technology->setSymbolicLayer ( "BLOCKAGE4" );
_technology->setWorkingLayer ( "METAL4" ); _technology->setSymbolicLayer ( "BLOCKAGE5" );
_technology->setWorkingLayer ( "METAL5" ); _technology->setSymbolicLayer ( "BLOCKAGE6" );
_technology->setWorkingLayer ( "METAL6" ); _technology->setSymbolicLayer ( "gmetalh" );
_technology->setWorkingLayer ( "BLOCKAGE1" ); _technology->setSymbolicLayer ( "gmetalv" );
_technology->setWorkingLayer ( "BLOCKAGE2" ); _technology->setSymbolicLayer ( "VIA12" );
_technology->setWorkingLayer ( "BLOCKAGE3" ); _technology->setSymbolicLayer ( "VIA23" );
_technology->setWorkingLayer ( "BLOCKAGE4" ); _technology->setSymbolicLayer ( "VIA34" );
_technology->setWorkingLayer ( "BLOCKAGE5" ); _technology->setSymbolicLayer ( "VIA45" );
_technology->setWorkingLayer ( "BLOCKAGE6" ); _technology->setSymbolicLayer ( "VIA56" );
_technology->setWorkingLayer ( "gmetalh" ); _technology->setSymbolicLayer ( "gcontact" );
_technology->setWorkingLayer ( "gmetalv" );
_technology->setWorkingLayer ( "VIA12" );
_technology->setWorkingLayer ( "VIA23" );
_technology->setWorkingLayer ( "VIA34" );
_technology->setWorkingLayer ( "VIA45" );
_technology->setWorkingLayer ( "VIA56" );
_technology->setWorkingLayer ( "gcontact" );
} }

View File

@ -373,12 +373,12 @@ namespace {
else { else {
cmess2 << " " << tab++ << "+ " << cell->getName() << " [.model]" << endl; cmess2 << " " << tab++ << "+ " << cell->getName() << " [.model]" << endl;
Net* vss = Net::create ( _cell, "vss" ); Net* vss = Net::create ( _cell, "gnd!" );
vss->setExternal( true ); vss->setExternal( true );
vss->setGlobal ( true ); vss->setGlobal ( true );
vss->setType ( Net::Type::GROUND ); vss->setType ( Net::Type::GROUND );
Net* vdd = Net::create ( _cell, "vdd" ); Net* vdd = Net::create ( _cell, "vdd!" );
vdd->setExternal( true ); vdd->setExternal( true );
vdd->setGlobal ( true ); vdd->setGlobal ( true );
vdd->setType ( Net::Type::POWER ); vdd->setType ( Net::Type::POWER );
@ -689,7 +689,7 @@ namespace CRL {
, tokenize.lineno() , tokenize.lineno()
) << endl; ) << endl;
//blifModel->mergeAlias( blifLine[1], "vss" ); //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 ) { } 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" 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." " File \"%s.blif\" at line %u."
@ -698,7 +698,7 @@ namespace CRL {
, tokenize.lineno() , tokenize.lineno()
) << endl; ) << endl;
//blifModel->mergeAlias( blifLine[1], "vdd" ); //blifModel->mergeAlias( blifLine[1], "vdd" );
blifModel->getCell()->getNet( "vdd" )->addAlias( blifLine[1] ); blifModel->getCell()->getNet( "vdd!" )->addAlias( blifLine[1] );
} else { } else {
cerr << Error( "Blif::load() Unsupported \".names\" cover construct.\n" cerr << Error( "Blif::load() Unsupported \".names\" cover construct.\n"
" File \"%s.blif\" at line %u." " File \"%s.blif\" at line %u."

View File

@ -87,6 +87,7 @@ namespace {
static void setCoreSite ( DbU::Unit x, DbU::Unit y ); static void setCoreSite ( DbU::Unit x, DbU::Unit y );
static DbU::Unit getCoreSiteX (); static DbU::Unit getCoreSiteX ();
static DbU::Unit getCoreSiteY (); static DbU::Unit getCoreSiteY ();
inline DbU::Unit getMinTerminalWidth () const;
inline double getUnitsMicrons () const; inline double getUnitsMicrons () const;
inline DbU::Unit fromUnitsMicrons ( double ) const; inline DbU::Unit fromUnitsMicrons ( double ) const;
inline void setUnitsMicrons ( double ); inline void setUnitsMicrons ( double );
@ -122,11 +123,13 @@ namespace {
int _nthCut; int _nthCut;
RoutingGauge* _routingGauge; RoutingGauge* _routingGauge;
CellGauge* _cellGauge; CellGauge* _cellGauge;
DbU::Unit _minTerminalWidth;
static DbU::Unit _coreSiteX; static DbU::Unit _coreSiteX;
static DbU::Unit _coreSiteY; static DbU::Unit _coreSiteY;
}; };
inline DbU::Unit LefParser::getMinTerminalWidth () const { return _minTerminalWidth; }
inline string LefParser::getLibraryName () const { return _libraryName; } inline string LefParser::getLibraryName () const { return _libraryName; }
inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; } inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; }
inline Cell* LefParser::getCell () const { return _cell; } inline Cell* LefParser::getCell () const { return _cell; }
@ -184,18 +187,19 @@ namespace {
LefParser::LefParser ( string file, string libraryName ) LefParser::LefParser ( string file, string libraryName )
: _file (file) : _file (file)
, _libraryName (libraryName) , _libraryName (libraryName)
, _library (NULL) , _library (NULL)
, _cell (NULL) , _cell (NULL)
, _net (NULL) , _net (NULL)
, _busBits ("()") , _busBits ("()")
, _unitsMicrons(0.01) , _unitsMicrons (0.01)
, _errors () , _errors ()
, _nthMetal (0) , _nthMetal (0)
, _nthCut (0) , _nthCut (0)
, _routingGauge(NULL) , _routingGauge (NULL)
, _cellGauge (NULL) , _cellGauge (NULL)
, _minTerminalWidth(DbU::fromPhysical(0.9,DbU::UnitPower::Micro))
{ {
_routingGauge = AllianceFramework::get()->getRoutingGauge(); _routingGauge = AllianceFramework::get()->getRoutingGauge();
_cellGauge = AllianceFramework::get()->getCellGauge(); _cellGauge = AllianceFramework::get()->getCellGauge();
@ -364,8 +368,10 @@ namespace {
Cell* cell = parser->getCell(); Cell* cell = parser->getCell();
Net* blockageNet = cell->getNet( "blockage" ); Net* blockageNet = cell->getNet( "blockage" );
if (not blockageNet) if (not blockageNet) {
blockageNet = Net::create( cell, "blockage" ); blockageNet = Net::create( cell, "blockage" );
blockageNet->setType( Net::Type::BLOCKAGE );
}
lefiGeometries* geoms = obstruction->geometries(); lefiGeometries* geoms = obstruction->geometries();
for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) { for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) {
@ -472,26 +478,29 @@ namespace {
continue; continue;
} }
if (geoms->itemType(igeom) == lefiGeomRectE) { if (geoms->itemType(igeom) == lefiGeomRectE) {
lefiGeomRect* r = geoms->getRect(igeom); lefiGeomRect* r = geoms->getRect(igeom);
double w = r->xh - r->xl; DbU::Unit w = parser->fromUnitsMicrons(r->xh - r->xl);
double h = r->yh - r->yl; DbU::Unit h = parser->fromUnitsMicrons(r->yh - r->yl);
Component* component = NULL; Component* component = NULL;
bool isExternal = false;
if (w >= h) { if (w >= h) {
isExternal = (h >= parser->getMinTerminalWidth());
component = Horizontal::create( net, layer component = Horizontal::create( net, layer
, parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) , parser->fromUnitsMicrons( (r->yl + r->yh)/2 )
, parser->fromUnitsMicrons( h ) , h
, parser->fromUnitsMicrons( r->xl ) , parser->fromUnitsMicrons( r->xl )
, parser->fromUnitsMicrons( r->xh ) , parser->fromUnitsMicrons( r->xh )
); );
} else { } else {
isExternal = (w >= parser->getMinTerminalWidth());
component = Vertical::create( net, layer component = Vertical::create( net, layer
, parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) , parser->fromUnitsMicrons( (r->xl + r->xh)/2 )
, parser->fromUnitsMicrons( w ) , w
, parser->fromUnitsMicrons( r->yl ) , parser->fromUnitsMicrons( r->yl )
, parser->fromUnitsMicrons( r->yh ) , parser->fromUnitsMicrons( r->yh )
); );
} }
NetExternalComponents::setExternal( component ); if (isExternal) NetExternalComponents::setExternal( component );
continue; continue;
} }

View File

@ -387,7 +387,7 @@ namespace Hurricane {
string smask = get<string> ( stack, "_mask" ); string smask = get<string> ( stack, "_mask" );
DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); 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" ); string materialName = get<string> ( stack, "_material" );
unsigned int extractNumber = get<int64_t>( stack, "_extractNumber" ); unsigned int extractNumber = get<int64_t>( stack, "_extractNumber" );
string blockageLayer = get<string> ( stack, "_blockageLayer" ); string blockageLayer = get<string> ( stack, "_blockageLayer" );
@ -405,7 +405,7 @@ namespace Hurricane {
, minimalSize , minimalSize
, minimalSpacing , minimalSpacing
); );
basicLayer->setWorking( isWorking ); basicLayer->setSymbolic( isSymbolic );
if (blockageLayer != "no_blockage_layer") { if (blockageLayer != "no_blockage_layer") {
JsonTechnology* jtechno = jget<JsonTechnology>( stack ); 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()); Net* net = static_cast<Net*>(occurrence.getEntity());
if (net->isClock() and (flags & Flags::NoClockFlatten)) continue; if (net->isClock() and (flags & Flags::NoClockFlatten)) continue;
if (net->isPower() or net->isGround() or net->isBlockage()) continue;
HyperNet hyperNet ( occurrence ); HyperNet hyperNet ( occurrence );
if ( not occurrence.getPath().isEmpty() ) { if ( not occurrence.getPath().isEmpty() ) {

View File

@ -266,7 +266,7 @@ namespace Hurricane {
string smask = get<string> ( stack, "_mask" ); string smask = get<string> ( stack, "_mask" );
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); //DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); //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* metal = techno->getBasicLayer( get<string>(stack,"_metal" ) );
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) ); BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
@ -291,7 +291,7 @@ namespace Hurricane {
, diffusion , diffusion
, well , well
); );
layer->setWorking ( isWorking ); layer->setSymbolic ( isSymbolic );
layer->setEnclosure( metal , metalEncl ); layer->setEnclosure( metal , metalEncl );
layer->setEnclosure( cut , cutEncl ); layer->setEnclosure( cut , cutEncl );
layer->setEnclosure( active , activeEncl ); layer->setEnclosure( active , activeEncl );

View File

@ -293,7 +293,7 @@ namespace Hurricane {
string smask = get<string> ( stack, "_mask" ); string smask = get<string> ( stack, "_mask" );
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); //DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); //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* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
BasicLayer* diffusion = techno->getBasicLayer( get<string>(stack,"_diffusion" ) ); BasicLayer* diffusion = techno->getBasicLayer( get<string>(stack,"_diffusion" ) );
@ -315,7 +315,7 @@ namespace Hurricane {
, diffusion , diffusion
, well , well
); );
layer->setWorking ( isWorking ); layer->setSymbolic ( isSymbolic );
layer->setExtentionCap ( active , eCapActive ); layer->setExtentionCap ( active , eCapActive );
layer->setExtentionCap ( diffusion, eCapDiffusion ); layer->setExtentionCap ( diffusion, eCapDiffusion );
layer->setExtentionWidth( active , eWidthActive ); layer->setExtentionWidth( active , eWidthActive );

View File

@ -55,7 +55,7 @@ namespace Hurricane {
, _minimalSize(minimalSize) , _minimalSize(minimalSize)
, _minimalSpacing(minimalSpacing) , _minimalSpacing(minimalSpacing)
, _nextOfTechnologyLayerMap(NULL) , _nextOfTechnologyLayerMap(NULL)
, _working(false) , _symbolic(false)
{ {
if ( !_technology ) if ( !_technology )
throw Error ( "Can't create " + _TName("Layer") + " : null technology" ); throw Error ( "Can't create " + _TName("Layer") + " : null technology" );
@ -84,20 +84,20 @@ namespace Hurricane {
{ return NULL; } { return NULL; }
Layer* Layer::getMetalAbove ( bool useWorking ) const Layer* Layer::getMetalAbove ( bool useSymbolic ) const
{ return _technology->getMetalAbove(this,useWorking); } { return _technology->getMetalAbove(this,useSymbolic); }
Layer* Layer::getMetalBelow ( bool useWorking ) const Layer* Layer::getMetalBelow ( bool useSymbolic ) const
{ return _technology->getMetalBelow(this,useWorking); } { return _technology->getMetalBelow(this,useSymbolic); }
Layer* Layer::getCutAbove ( bool useWorking ) const Layer* Layer::getCutAbove ( bool useSymbolic ) const
{ return _technology->getCutAbove(this,useWorking); } { return _technology->getCutAbove(this,useSymbolic); }
Layer* Layer::getCutBelow ( bool useWorking ) const Layer* Layer::getCutBelow ( bool useSymbolic ) const
{ return _technology->getCutBelow(this,useWorking); } { return _technology->getCutBelow(this,useSymbolic); }
DbU::Unit Layer::getEnclosure () const DbU::Unit Layer::getEnclosure () const
@ -246,7 +246,7 @@ namespace Hurricane {
jsonWrite( writer, "_extractMask" , getString(_extractMask) ); jsonWrite( writer, "_extractMask" , getString(_extractMask) );
jsonWrite( writer, "_minimalSize" , _minimalSize ); jsonWrite( writer, "_minimalSize" , _minimalSize );
jsonWrite( writer, "_minimalSpacing", _minimalSpacing ); jsonWrite( writer, "_minimalSpacing", _minimalSpacing );
jsonWrite( writer, "_working" , _working ); jsonWrite( writer, "_symbolic" , _symbolic );
} }
@ -261,7 +261,7 @@ namespace Hurricane {
add( "_extractMask" , typeid(string) ); add( "_extractMask" , typeid(string) );
add( "_minimalSize" , typeid(uint64_t) ); add( "_minimalSize" , typeid(uint64_t) );
add( "_minimalSpacing", 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" ); string smask = get<string> ( stack, "_mask" );
DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); 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" ) ); BasicLayer* basicLayer = techno->getBasicLayer( get<string>(stack,"_basicLayer" ) );
DbU::Unit enclosure = get<int64_t>( stack, "_enclosure" ); DbU::Unit enclosure = get<int64_t>( stack, "_enclosure" );
@ -398,7 +398,7 @@ namespace Hurricane {
// Actual creation. // Actual creation.
layer = RegularLayer::create( techno, name ); layer = RegularLayer::create( techno, name );
layer->setBasicLayer ( basicLayer ); layer->setBasicLayer ( basicLayer );
layer->setWorking ( isWorking ); layer->setSymbolic ( isSymbolic );
layer->setMinimalSize ( minimalSize ); layer->setMinimalSize ( minimalSize );
layer->setMinimalSpacing( minimalSpacing ); layer->setMinimalSpacing( minimalSpacing );
layer->setEnclosure ( basicLayer, enclosure ); layer->setEnclosure ( basicLayer, enclosure );

View File

@ -150,16 +150,6 @@ Technology* Technology::create(DataBase* dataBase, const Name& name)
return technology; 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 BasicLayer* Technology::getBasicLayer(const Name& name) const
// ********************************************************** // **********************************************************
{ {
@ -195,97 +185,107 @@ BasicLayers Technology::getBasicLayers(const Layer::Mask& mask) const
} }
RegularLayers Technology::getRegularLayers() const RegularLayers Technology::getRegularLayers() const
// *************************************************** // ***********************************************
{ {
return SubTypeCollection<Layer*, RegularLayer*>(getLayers()); return SubTypeCollection<Layer*, RegularLayer*>(getLayers());
} }
ViaLayers Technology::getViaLayers() const ViaLayers Technology::getViaLayers() const
// *************************************************** // ***************************************
{ {
return SubTypeCollection<Layer*, ViaLayer*>(getLayers()); 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 ); Layer* layer = NULL;
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( mask ); LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( mask );
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound( mask );
for ( ; lb != ub ; lb++ ) { 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++ ) { for ( ; ub != _layerMaskMap.end() ; ub++ ) {
if ( _metalMask.contains(ub->second->getMask()) if (_metalMask.contains(ub->second->getMask())) {
&& ( !useWorking || ub->second->isWorking() ) ) above = ub->second;
return 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() ); Layer* below = NULL;
if ( lb->second == layer ) lb--; LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
if (lb->second->getMask() == layer->getMask()) lb--;
for ( ; lb != _layerMaskMap.begin() ; lb-- ) { for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
if ( _metalMask.contains(lb->second->getMask()) if (_metalMask.contains(lb->second->getMask())) {
&& ( !useWorking || lb->second->isWorking() ) ) below = lb->second;
return 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++ ) { for ( ; ub != _layerMaskMap.end() ; ub++ ) {
if ( _cutMask.contains(ub->second->getMask()) if (_cutMask.contains(ub->second->getMask())) {
&& ( !useWorking || ub->second->isWorking() ) ) cut = ub->second;
return 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() ); Layer* cut = NULL;
if ( lb->second == layer ) lb--; LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
if (lb->second->getMask() == layer->getMask()) lb--;
for ( ; lb != _layerMaskMap.begin() ; lb-- ) { for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
if ( _cutMask.contains(lb->second->getMask()) if (_cutMask.contains(lb->second->getMask())) {
&& ( !useWorking || lb->second->isWorking() ) ) cut = lb->second;
return 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 (not metal1 or not metal2) return NULL;
if ( metal1 == metal2 ) return const_cast<Layer*>(metal1); if (metal1 == metal2) return const_cast<Layer*>(metal1);
if ( metal1->above(metal2) ) swap ( metal1, metal2 ); if (metal1->above(metal2)) swap( metal1, metal2 );
Layer* cutLayer = getCutBelow ( metal2 ); Layer* cutLayer = getCutBelow( metal2, false );
if ( !cutLayer ) return NULL; 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 ); Layer* layer = getLayer( name );
if ( !layer ) return false; 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; bool found = false;
LayerMaskMap::iterator lb = _layerMaskMap.lower_bound ( layer->getMask() ); LayerMaskMap::iterator lb = _layerMaskMap.lower_bound( layer->getMask() );
LayerMaskMap::iterator ub = _layerMaskMap.upper_bound ( layer->getMask() ); LayerMaskMap::iterator ub = _layerMaskMap.upper_bound( layer->getMask() );
for ( ; lb != ub ; lb++ ) { for ( ; lb != ub ; lb++ ) {
if ( lb->second == layer ) { if (lb->second == layer) {
lb->second->setWorking ( true ); lb->second->setSymbolic( true );
found = true; found = true;
} else } else
lb->second->setWorking ( false ); lb->second->setSymbolic( false );
} }
return found; return found;
} }

View File

@ -301,7 +301,7 @@ namespace Hurricane {
string smask = get<string> ( stack, "_mask" ); string smask = get<string> ( stack, "_mask" );
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); //DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); //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* gate = techno->getBasicLayer( get<string>(stack,"_gate" ) );
BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) ); BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
@ -327,7 +327,7 @@ namespace Hurricane {
, diffusion , diffusion
, well , well
); );
layer->setWorking ( isWorking ); layer->setSymbolic ( isSymbolic );
layer->setExtentionCap ( gate , eCapGate ); layer->setExtentionCap ( gate , eCapGate );
layer->setExtentionCap ( active , eCapActive ); layer->setExtentionCap ( active , eCapActive );
layer->setExtentionCap ( diffusion, eCapDiffusion ); layer->setExtentionCap ( diffusion, eCapDiffusion );

View File

@ -267,7 +267,7 @@ namespace Hurricane {
string smask = get<string> ( stack, "_mask" ); string smask = get<string> ( stack, "_mask" );
//DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" ); //DbU::Unit minimalSize = get<int64_t>( stack, "_minimalSize" );
//DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" ); //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* bottom = techno->getBasicLayer( get<string>(stack,"_bottom" ) );
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) ); BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
@ -286,7 +286,7 @@ namespace Hurricane {
, cut , cut
, top , top
); );
layer->setWorking ( isWorking ); layer->setSymbolic ( isSymbolic );
layer->setEnclosure( bottom, bottomEncl ); layer->setEnclosure( bottom, bottomEncl );
layer->setEnclosure( cut , cutEncl ); layer->setEnclosure( cut , cutEncl );
layer->setEnclosure( top , topEncl ); layer->setEnclosure( top , topEncl );

View File

@ -68,10 +68,10 @@ namespace Hurricane {
virtual const Layer* getTop () const; virtual const Layer* getTop () const;
virtual const Layer* getBottom () const; virtual const Layer* getBottom () const;
virtual const Layer* getOpposite ( const Layer* ) const; virtual const Layer* getOpposite ( const Layer* ) const;
Layer* getMetalAbove ( bool useWorking=true ) const; Layer* getMetalAbove ( bool useSymbolic=true ) const;
Layer* getMetalBelow ( bool useWorking=true ) const; Layer* getMetalBelow ( bool useSymbolic=true ) const;
Layer* getCutAbove ( bool useWorking=true ) const; Layer* getCutAbove ( bool useSymbolic=true ) const;
Layer* getCutBelow ( bool useWorking=true ) const; Layer* getCutBelow ( bool useSymbolic=true ) const;
virtual DbU::Unit getEnclosure () const; virtual DbU::Unit getEnclosure () const;
virtual DbU::Unit getExtentionCap () const; virtual DbU::Unit getExtentionCap () const;
virtual DbU::Unit getExtentionWidth () const; virtual DbU::Unit getExtentionWidth () const;
@ -83,10 +83,10 @@ namespace Hurricane {
inline bool below ( const Layer* layer ) const; inline bool below ( const Layer* layer ) const;
bool contains ( const Layer* layer ) const; bool contains ( const Layer* layer ) const;
bool intersect ( const Layer* layer ) const; bool intersect ( const Layer* layer ) const;
inline bool isWorking () const; inline bool isSymbolic () const;
// Updators // Updators
void setName ( const Name& name ); void setName ( const Name& name );
inline void setWorking ( bool ); inline void setSymbolic ( bool );
void setMinimalSize ( const DbU::Unit& minimalSize ); void setMinimalSize ( const DbU::Unit& minimalSize );
void setMinimalSpacing ( const DbU::Unit& minimalSpacing ); void setMinimalSpacing ( const DbU::Unit& minimalSpacing );
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit ); virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit );
@ -112,7 +112,7 @@ namespace Hurricane {
DbU::Unit _minimalSize; DbU::Unit _minimalSize;
DbU::Unit _minimalSpacing; DbU::Unit _minimalSpacing;
Layer* _nextOfTechnologyLayerMap; Layer* _nextOfTechnologyLayerMap;
bool _working; bool _symbolic;
protected: protected:
// Internal: Constructors & Destructors. // Internal: Constructors & Destructors.
@ -133,7 +133,7 @@ namespace Hurricane {
// Inline Functions. // 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::above ( const Layer* layer ) const { return _mask > layer->getMask(); }
inline bool Layer::below ( 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; } inline Technology* Layer::getTechnology () const { return _technology; }
@ -142,7 +142,7 @@ namespace Hurricane {
inline const Layer::Mask& Layer::getExtractMask () const { return _extractMask; } inline const Layer::Mask& Layer::getExtractMask () const { return _extractMask; }
inline const DbU::Unit& Layer::getMinimalSize () const { return _minimalSize; } inline const DbU::Unit& Layer::getMinimalSize () const { return _minimalSize; }
inline const DbU::Unit& Layer::getMinimalSpacing () const { return _minimalSpacing; } 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 Layer* Layer::_getNextOfTechnologyLayerMap () const { return _nextOfTechnologyLayerMap; }
inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; } inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; }
inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; } inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; }

View File

@ -90,18 +90,18 @@ namespace Hurricane {
BasicLayers getBasicLayers ( const Layer::Mask& ) const; BasicLayers getBasicLayers ( const Layer::Mask& ) const;
RegularLayers getRegularLayers () const; RegularLayers getRegularLayers () const;
ViaLayers getViaLayers () const; ViaLayers getViaLayers () const;
Layer* getLayer ( const Layer::Mask&, bool useWorking=true ) const; Layer* getLayer ( const Layer::Mask&, bool useSymbolic=true ) const;
Layer* getMetalAbove ( const Layer*, bool useWorking=true ) const; Layer* getMetalAbove ( const Layer*, bool useSymbolic=true ) const;
Layer* getMetalBelow ( const Layer*, bool useWorking=true ) const; Layer* getMetalBelow ( const Layer*, bool useSymbolic=true ) const;
Layer* getCutAbove ( const Layer*, bool useWorking=true ) const; Layer* getCutAbove ( const Layer*, bool useSymbolic=true ) const;
Layer* getCutBelow ( const Layer*, bool useWorking=true ) const; Layer* getCutBelow ( const Layer*, bool useSymbolic=true ) const;
Layer* getViaBetween ( const Layer*, const Layer* ) const; Layer* getViaBetween ( const Layer*, const Layer*, bool useSymbolic=true ) const;
Layer* getNthMetal ( int ) const; Layer* getNthMetal ( int ) const;
Layer* getNthCut ( int ) const; Layer* getNthCut ( int ) const;
// Updators. // Updators.
void setName ( const Name& ); void setName ( const Name& );
bool setWorkingLayer ( const Name& ); bool setSymbolicLayer ( const Name& );
bool setWorkingLayer ( const Layer* ); bool setSymbolicLayer ( const Layer* );
// Others. // Others.
inline LayerMap& _getLayerMap (); inline LayerMap& _getLayerMap ();
inline LayerMaskMap& _getLayerMaskMap (); 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 ) \ 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; \ Layer* rlayer = NULL; \
\ \
HTRY \ HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \ GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
\ \
PyObject* arg0 = NULL; \ PyObject* arg0 = NULL; \
bool useWorking = true; \ bool useSymbolic = true; \
\ \
if (PyArg_ParseTuple( args, "|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0)) { \ if (PyArg_ParseTuple( args, "|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0)) { \
if (arg0 != NULL) { \ if (arg0 != NULL) { \
useWorking = PyObject_IsTrue(arg0); \ useSymbolic = PyObject_IsTrue(arg0); \
} \ } \
} else { \ } else { \
PyErr_SetString ( ConstructorError \ PyErr_SetString ( ConstructorError \
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \ , "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
return NULL; \ return NULL; \
} \ } \
rlayer = const_cast<SELF_TYPE*>(cobject->FUNC_NAME(useWorking)); \ rlayer = const_cast<SELF_TYPE*>(cobject->FUNC_NAME(useSymbolic)); \
HCATCH \ HCATCH \
\ \
if (rlayer == NULL) Py_RETURN_NONE; \ 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 ) \ 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 \ HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \ 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) \ # define updatorFromBasicLayerDbu(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \ 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 \ HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \ GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
@ -245,7 +245,7 @@ extern "C" {
predicateFromLayer ( below ,PyLayer,Layer) predicateFromLayer ( below ,PyLayer,Layer)
predicateFromLayer ( contains ,PyLayer,Layer) predicateFromLayer ( contains ,PyLayer,Layer)
predicateFromLayer ( intersect ,PyLayer,Layer) predicateFromLayer ( intersect ,PyLayer,Layer)
predicateFromVoid ( isWorking ,PyLayer,Layer) predicateFromVoid ( isSymbolic ,PyLayer,Layer)
accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer)
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
@ -269,6 +269,7 @@ extern "C" {
updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer) updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer)
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer)
// Standart destroy (Attribute). // Standart destroy (Attribute).
DBoDestroyAttribute(PyLayer_destroy, PyLayer) DBoDestroyAttribute(PyLayer_destroy, PyLayer)
@ -319,12 +320,12 @@ extern "C" {
, "Tells if the layer fully contains the one passed as argument." } , "Tells if the layer fully contains the one passed as argument." }
, { "intersect" , (PyCFunction)PyLayer_intersect , METH_VARARGS , { "intersect" , (PyCFunction)PyLayer_intersect , METH_VARARGS
, "Tells if the layer share some BasicLayer with the one passed as argument." } , "Tells if the layer share some BasicLayer with the one passed as argument." }
, { "isWorking" , (PyCFunction)PyLayer_isWorking , METH_NOARGS , { "isSymbolic" , (PyCFunction)PyLayer_isSymbolic , METH_NOARGS
, "Tells if the layer is the working one for this BasicLayer." } , "Tells if the layer is the symbolic one for this BasicLayer." }
, { "setName" , (PyCFunction)PyLayer_setName , METH_VARARGS , { "setName" , (PyCFunction)PyLayer_setName , METH_VARARGS
, "Allows to change the layer name." } , "Allows to change the layer name." }
, { "setWorking" , (PyCFunction)PyLayer_setName , METH_VARARGS , { "setSymbolic" , (PyCFunction)PyLayer_setSymbolic , METH_VARARGS
, "Sets the layer as the working one." } , "Sets the layer as the symbolic one." }
, { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS , { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS
, "Sets the layer minimal size (width)." } , "Sets the layer minimal size (width)." }
, { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS , { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS

View File

@ -134,8 +134,8 @@ extern "C" {
if (PyString_Check(arg0)) { if (PyString_Check(arg0)) {
layer = techno->getLayer(Name(PyString_AsString(arg0))); layer = techno->getLayer(Name(PyString_AsString(arg0)));
} else if (IsPyLayerMask(arg0)) { } else if (IsPyLayerMask(arg0)) {
bool useWorking = (arg1 != NULL) ? PyObject_IsTrue(arg1) : true; bool useSymbolic = (arg1 != NULL) ? PyObject_IsTrue(arg1) : true;
layer = techno->getLayer(PYLAYERMASK_O(arg0), useWorking); layer = techno->getLayer(PYLAYERMASK_O(arg0), useSymbolic);
} else { } else {
PyErr_SetString(ConstructorError, "invalid number of parameters for getLayer."); PyErr_SetString(ConstructorError, "invalid number of parameters for getLayer.");
return NULL; return NULL;
@ -188,26 +188,26 @@ extern "C" {
} }
static PyObject* PyTechnology_setWorkingLayer ( PyTechnology *self, PyObject* args ) { static PyObject* PyTechnology_setSymbolicLayer ( PyTechnology *self, PyObject* args ) {
cdebug_log(20,0) << "Technology.setWorkingLayer()" << endl; cdebug_log(20,0) << "Technology.setSymbolicLayer()" << endl;
METHOD_HEAD("Technology.setWorkingLayer()") METHOD_HEAD("Technology.setSymbolicLayer()")
bool rvalue = false; bool rvalue = false;
HTRY HTRY
PyObject* arg0 = NULL; PyObject* arg0 = NULL;
if (PyArg_ParseTuple(args,"O:Technology.setWorkingLayer", &arg0)) { if (PyArg_ParseTuple(args,"O:Technology.setSymbolicLayer", &arg0)) {
if (PyString_Check(arg0)) { if (PyString_Check(arg0)) {
rvalue = techno->setWorkingLayer(Name(PyString_AsString(arg0))); rvalue = techno->setSymbolicLayer(Name(PyString_AsString(arg0)));
} else if (IsPyLayer(arg0)) { } else if (IsPyLayer(arg0)) {
rvalue = techno->setWorkingLayer(PYLAYER_O(arg0)); rvalue = techno->setSymbolicLayer(PYLAYER_O(arg0));
} else { } else {
PyErr_SetString(ConstructorError, "Hurricane.setWorkingLayer(): Invalid number of parameters."); PyErr_SetString(ConstructorError, "Hurricane.setSymbolicLayer(): Invalid number of parameters.");
return NULL; return NULL;
} }
} else { } else {
PyErr_SetString(ConstructorError, "Hurricane.setWorkingLayer(): Bad parameter type."); PyErr_SetString(ConstructorError, "Hurricane.setSymbolicLayer(): Bad parameter type.");
return NULL; return NULL;
} }
HCATCH HCATCH
@ -218,21 +218,21 @@ extern "C" {
// Standart Accessors (Attributes). // Standart Accessors (Attributes).
GetNameMethod (Technology,techno) GetNameMethod (Technology,techno)
SetNameMethod (Technology,techno) SetNameMethod (Technology,techno)
predicateFromLayer (isMetal ,PyTechnology,Technology) predicateFromLayer (isMetal ,PyTechnology,Technology)
accessorAnyLayerFromName (getBasicLayer ,PyTechnology,Technology,BasicLayer ) accessorAnyLayerFromName (getBasicLayer ,PyTechnology,Technology,BasicLayer )
accessorAnyLayerFromName (getRegularLayer ,PyTechnology,Technology,RegularLayer) accessorAnyLayerFromName (getRegularLayer ,PyTechnology,Technology,RegularLayer)
accessorAnyLayerFromName (getViaLayer ,PyTechnology,Technology,ViaLayer ) accessorAnyLayerFromName (getViaLayer ,PyTechnology,Technology,ViaLayer )
accessorCollectionFromVoid (getLayers ,PyTechnology,Technology,Layer ) accessorCollectionFromVoid (getLayers ,PyTechnology,Technology,Layer )
accessorCollectionFromVoid (getRegularLayers,PyTechnology,Technology,RegularLayer) accessorCollectionFromVoid (getRegularLayers,PyTechnology,Technology,RegularLayer)
accessorCollectionFromVoid (getViaLayers ,PyTechnology,Technology,ViaLayer ) accessorCollectionFromVoid (getViaLayers ,PyTechnology,Technology,ViaLayer )
accessorLayerFromLayerOptBool(getMetalAbove ,PyTechnology,Technology) accessorLayerFromLayerOptBool (getMetalAbove ,PyTechnology,Technology)
accessorLayerFromLayerOptBool(getMetalBelow ,PyTechnology,Technology) accessorLayerFromLayerOptBool (getMetalBelow ,PyTechnology,Technology)
accessorLayerFromLayerOptBool(getCutAbove ,PyTechnology,Technology) accessorLayerFromLayerOptBool (getCutAbove ,PyTechnology,Technology)
accessorLayerFromLayerOptBool(getCutBelow ,PyTechnology,Technology) accessorLayerFromLayerOptBool (getCutBelow ,PyTechnology,Technology)
accessorLayerFromLayerLayer (getViaBetween ,PyTechnology,Technology) accessorLayerFromLayerLayerOptBool(getViaBetween ,PyTechnology,Technology)
accessorLayerFromInt (getNthMetal ,PyTechnology,Technology) accessorLayerFromInt (getNthMetal ,PyTechnology,Technology)
// Standard destroy (Attribute). // Standard destroy (Attribute).
DBoDestroyAttribute(PyTechnology_destroy, PyTechnology) DBoDestroyAttribute(PyTechnology_destroy, PyTechnology)
@ -280,8 +280,8 @@ extern "C" {
, "Returns Nth metal (zero is nearest substrate)." } , "Returns Nth metal (zero is nearest substrate)." }
, { "setName" , (PyCFunction)PyTechnology_setName , METH_VARARGS , { "setName" , (PyCFunction)PyTechnology_setName , METH_VARARGS
, "Allows to change the technology name." } , "Allows to change the technology name." }
, { "setWorkingLayer" , (PyCFunction)PyTechnology_setWorkingLayer , METH_VARARGS , { "setSymbolicLayer" , (PyCFunction)PyTechnology_setSymbolicLayer, METH_VARARGS
, "Mark a Layer as the working one (by name or by Layer)." } , "Mark a Layer as the symbolic one (by name or by Layer)." }
, { "destroy" , (PyCFunction)PyTechnology_destroy , METH_NOARGS , { "destroy" , (PyCFunction)PyTechnology_destroy , METH_NOARGS
, "Destroy associated hurricane object The python object remains." } , "Destroy associated hurricane object The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */

View File

@ -457,9 +457,9 @@ extern "C" {
HTRY \ HTRY \
GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \ GENERIC_METHOD_HEAD(SELF_TYPE,cobject,#SELF_TYPE"."#FUNC_NAME"()") \
\ \
PyObject* arg0 = NULL; \ PyObject* arg0 = NULL; \
PyObject* arg1 = NULL; \ PyObject* arg1 = NULL; \
bool useWorking = true; \ bool useSymbolic = true; \
\ \
if (PyArg_ParseTuple( args, "O|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0, &arg1)) { \ if (PyArg_ParseTuple( args, "O|O:"#SELF_TYPE"."#FUNC_NAME"()", &arg0, &arg1)) { \
if (not IsPyLayer(arg0)) { \ if (not IsPyLayer(arg0)) { \
@ -468,14 +468,14 @@ extern "C" {
return NULL; \ return NULL; \
} \ } \
if (arg1 != NULL) { \ if (arg1 != NULL) { \
useWorking = PyObject_IsTrue(arg1); \ useSymbolic = PyObject_IsTrue(arg1); \
} \ } \
} else { \ } else { \
PyErr_SetString ( ConstructorError \ PyErr_SetString ( ConstructorError \
, "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \ , "Invalid number of parameters passed to "#SELF_TYPE"."#FUNC_NAME"()." ); \
return NULL; \ 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 \ HCATCH \
\ \
if (rlayer == NULL) Py_RETURN_NONE; \ 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) \ # define accessorLayerFromInt(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \ static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
{ \ { \