# -*- Mode:Python; explicit-buffer-name: "technology.conf<common>" -*-
#
# Those settings are common to all the symbolic technologies.

from Hurricane          import BasicLayer
from helpers            import l, u, n
from helpers.Technology import TypeRegular
from helpers.Technology import TypeDiffusion
from helpers.Technology import TypeTransistor
from helpers.Technology import TypeContact
from helpers.Technology import TypeVia


#viewerConfig = { 'precision':2, 'gridstep':1.0 }

# The informations here are extracted from the Alliance ".rds" file,
# and must be coherent with it.
#
# Format of <realLayerTable>:
#     The third parameter must be present only for blockage material.
#     ('layer_name'   , MATERIAL                    , ASSOCIATED ROUTING)
#
# Note: concerning the LayerMask, real layers are implementeds as BasicLayer,
#       and are associated to exactly one bit of the mask. Symbolic layers
#       then combine BasicLayer to create composite objects, an thus can have
#       a mask which have multiple bits set. Getting the mask from a layer
#       is straigthforward, but the reverse is not true. One mask may match
#       multiple symbolic layers. To overcome this ambiguity we introduce the
#       concept of "working layer", which, for one given mask tells the layer
#       that will be returned (generally the symbolic one).

realLayersTable = \
    ( ('nWell'        , BasicLayer.Material.nWell   )  # Non-Routing Layers.
    , ('pWell'        , BasicLayer.Material.pWell   )
    , ('nImplant'     , BasicLayer.Material.nImplant)
    , ('pImplant'     , BasicLayer.Material.pImplant)
    , ('active'       , BasicLayer.Material.active  )
    , ('poly'         , BasicLayer.Material.poly    )
    , ('poly2'        , BasicLayer.Material.poly    )
    , ('cut0'         , BasicLayer.Material.cut     )  # Routing Layers & VIA Cuts.
    , ('metal1'       , BasicLayer.Material.metal   )  # WARNING: order *is* meaningful.
    , ('cut1'         , BasicLayer.Material.cut     )
    , ('metal2'       , BasicLayer.Material.metal   )
    , ('metcap'       , BasicLayer.Material.other   )
    , ('cut2'         , BasicLayer.Material.cut     )
    , ('metal3'       , BasicLayer.Material.metal   )
    , ('cut3'         , BasicLayer.Material.cut     )
    , ('metal4'       , BasicLayer.Material.metal   )
    , ('cut4'         , BasicLayer.Material.cut     )
    , ('metal5'       , BasicLayer.Material.metal   )
    , ('cut5'         , BasicLayer.Material.cut     )
    , ('metal6'       , BasicLayer.Material.metal   )
    , ('cut6'         , BasicLayer.Material.cut     )
    , ('metal7'       , BasicLayer.Material.metal   )
    , ('cut7'         , BasicLayer.Material.cut     )
    , ('metal8'       , BasicLayer.Material.metal   )
    , ('cut8'         , BasicLayer.Material.cut     )
    , ('metal9'       , BasicLayer.Material.metal   )
    , ('cut9'         , BasicLayer.Material.cut     )
    , ('metal10'      , BasicLayer.Material.metal   )
   #, ('topmim6'      , BasicLayer.Material.other   )  # For Capacitances & Pads.
    , ('metbot_r'     , BasicLayer.Material.other   )
   #, ('padopen'      , BasicLayer.Material.other   )
   #, ('alucap'       , BasicLayer.Material.other   )
    
    , ('text.cell'    , BasicLayer.Material.other   )  # Misc. non-physical layers.
    , ('text.instance', BasicLayer.Material.other   )  # Used by the software for visualization
    , ('SPL1'         , BasicLayer.Material.other   )  # purposes only.
    , ('AutoLayer'    , BasicLayer.Material.other   )
    , ('blockage1'    , BasicLayer.Material.blockage, 'metal1')  # Blockages
    , ('blockage2'    , BasicLayer.Material.blockage, 'metal2')
    , ('blockage3'    , BasicLayer.Material.blockage, 'metal3')
    , ('blockage4'    , BasicLayer.Material.blockage, 'metal4')
    , ('blockage5'    , BasicLayer.Material.blockage, 'metal5')
    , ('blockage6'    , BasicLayer.Material.blockage, 'metal6')
    , ('blockage7'    , BasicLayer.Material.blockage, 'metal7')
    , ('blockage8'    , BasicLayer.Material.blockage, 'metal8')
    , ('blockage9'    , BasicLayer.Material.blockage, 'metal9')
    , ('blockage10'   , BasicLayer.Material.blockage, 'metal10')
    , ('gmetalh'      , BasicLayer.Material.metal   )  # Special BasicLayers for Knik & Kite Routers.
    , ('gcut'         , BasicLayer.Material.cut     )  # *Must be after all others*
    , ('gmetalv'      , BasicLayer.Material.metal   )
    )


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

compositeLayersTable  = \
    ( ('NWELL'      , TypeRegular   , ('nWell'    ,))
    , ('PWELL'      , TypeRegular   , ('pWell'    ,))
    , ('NTIE'       , TypeDiffusion , ('nImplant' , 'active', 'nWell'))
    , ('PTIE'       , TypeDiffusion , ('pImplant' , 'active', 'pWell'))
    , ('NDIF'       , TypeDiffusion , ('nImplant' , 'active', None   ))
    , ('PDIF'       , TypeDiffusion , ('pImplant' , 'active', None   ))
    , ('GATE'       , TypeDiffusion , ('poly'     , 'active', None   ))
    , ('NTRANS'     , TypeTransistor, ('nImplant' , 'active', 'poly', None   ))
    , ('PTRANS'     , TypeTransistor, ('pImplant' , 'active', 'poly', 'nWell'))
    , ('POLY'       , TypeRegular   , ('poly'     ,))
    , ('POLY2'      , TypeRegular   , ('poly2'    ,))
    , ('METAL1'     , TypeRegular   , ('metal1'   ,))
    , ('METAL2'     , TypeRegular   , ('metal2'   ,))
    , ('metcapdum'  , TypeRegular   , ('metcap'   ,))
    , ('metbot'     , TypeRegular   , ('metal2'   ,))
    , ('METAL3'     , TypeRegular   , ('metal3'   ,))
    , ('METAL4'     , TypeRegular   , ('metal4'   ,))
    , ('METAL5'     , TypeRegular   , ('metal5'   ,))
    , ('METAL6'     , TypeRegular   , ('metal6'   ,))
    , ('METAL7'     , TypeRegular   , ('metal7'   ,))
    , ('METAL8'     , TypeRegular   , ('metal8'   ,))
    , ('METAL9'     , TypeRegular   , ('metal9'   ,))
    , ('METAL10'    , TypeRegular   , ('metal10'  ,))
    , ('CONT_BODY_N', TypeContact   , ('nImplant' , 'active', 'cut0', 'metal1', 'nWell'))
    , ('CONT_BODY_P', TypeContact   , ('pImplant' , 'active', 'cut0', 'metal1', 'pWell'))
    , ('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' ))
    , ('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'))
    , ('BLOCKAGE1'  , TypeRegular   , ('blockage1' , ))
    , ('BLOCKAGE2'  , TypeRegular   , ('blockage2' , ))
    , ('BLOCKAGE3'  , TypeRegular   , ('blockage3' , ))
    , ('BLOCKAGE4'  , TypeRegular   , ('blockage4' , ))
    , ('BLOCKAGE5'  , TypeRegular   , ('blockage5' , ))
    , ('BLOCKAGE6'  , TypeRegular   , ('blockage6' , ))
    , ('BLOCKAGE7'  , TypeRegular   , ('blockage7' , ))
    , ('BLOCKAGE8'  , TypeRegular   , ('blockage8' , ))
    , ('BLOCKAGE9'  , TypeRegular   , ('blockage9' , ))
    , ('BLOCKAGE10' , TypeRegular   , ('blockage10', ))
    , ('gcontact'   , TypeVia       , ('gmetalh'   , 'gcut', 'gmetalv'))
    )


# Format of <symbolicLayersTable>:
#     This is a simple list of Symbolic layers.

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'
            , 'gcut'     , 'gmetalh'  , 'gmetalv'  , 'gcontact'
    ]


# Format of <layersExtensionsTable>:
#    Each entry is a pair of (string, value).
#    * 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.
#    Values/dimensions must be given using one of the following conversion
#    function:
#    * l(value) : value expressed in lambda (symbolic).
#    * u(value) : value is expressed in microns.
#    * n(value) : value is expressed in nanometers.

symbolicLayersExtensionsTable = \
    [ ('NWELL.nWell.extention.cap'          , l( 0.0))
    , ('PWELL.pWell.extention.cap'          , l( 0.0))

    , ('NTIE.minimum.width'                 , l( 3.0))
    , ('NTIE.nWell.extention.cap'           , l( 1.5))
    , ('NTIE.nWell.extention.width'         , l( 0.5))
    , ('NTIE.nImplant.extention.cap'        , l( 1.0))
    , ('NTIE.nImplant.extention.width'      , l( 0.5))
    , ('NTIE.active.extention.cap'          , l( 0.5))
    , ('NTIE.active.extention.width'        , l( 0.0))

    , ('PTIE.minimum.width'                 , l( 3.0))
    , ('PTIE.pWell.extention.cap'           , l( 1.5))
    , ('PTIE.pWell.extention.width'         , l( 0.5))
    , ('PTIE.pImplant.extention.cap'        , l( 1.0))
    , ('PTIE.pImplant.extention.width'      , l( 0.5))
    , ('PTIE.active.extention.cap'          , l( 0.5))
    , ('PTIE.active.extention.width'        , l( 0.0))

    , ('NDIF.minimum.width'                 , l( 3.0))
    , ('NDIF.nImplant.extention.cap'        , l( 1.0))
    , ('NDIF.nImplant.extention.width'      , l( 0.5))
    , ('NDIF.active.extention.cap'          , l( 0.5))
    , ('NDIF.active.extention.width'        , l( 0.0))

    , ('PDIF.minimum.width'                 , l( 3.0))
    , ('PDIF.pImplant.extention.cap'        , l( 1.0))
    , ('PDIF.pImplant.extention.width'      , l( 0.5))
    , ('PDIF.active.extention.cap'          , l( 0.5))
    , ('PDIF.active.extention.width'        , l( 0.0))

    , ('GATE.minimum.width'                 , l( 1.0))
    , ('GATE.poly.extention.cap'            , l( 1.5))

    , ('NTRANS.minimum.width'               , l( 1.0))
    , ('NTRANS.nImplant.extention.cap'      , l(-1.0))
    , ('NTRANS.nImplant.extention.width'    , l( 2.5))
    , ('NTRANS.active.extention.cap'        , l(-1.5))
    , ('NTRANS.active.extention.width'      , l( 2.0))

    , ('PTRANS.minimum.width'               , l( 1.0))
    , ('PTRANS.nWell.extention.cap'         , l(-1.0))
    , ('PTRANS.nWell.extention.width'       , l( 4.5))
    , ('PTRANS.pImplant.extention.cap'      , l(-1.0))
    , ('PTRANS.pImplant.extention.width'    , l( 4.0))
    , ('PTRANS.active.extention.cap'        , l(-1.5))
    , ('PTRANS.active.extention.width'      , l( 3.0))

    , ('POLY.minimum.width'                 , l( 1.0))
    , ('POLY.poly.extention.cap'            , l( 0.5))
    , ('POLY2.minimum.width'                , l( 1.0))
    , ('POLY2.poly.extention.cap'           , l( 0.5))

    # Routing Layers (symbolic).
    , ('METAL1.minimum.width'               , l( 1.0))
    , ('METAL1.metal1.extention.cap'        , l( 0.5))
    , ('METAL2.minimum.width'               , l( 1.0))
    , ('METAL2.metal2.extention.cap'        , l( 1.0))
    , ('METAL3.minimum.width'               , l( 1.0))
    , ('METAL3.metal3.extention.cap'        , l( 1.0))
    , ('METAL4.minimum.width'               , l( 1.0))
    , ('METAL4.metal4.extention.cap'        , l( 1.0))
    , ('METAL4.minimalSpacing'              , l( 3.0))
    , ('METAL5.minimum.width'               , l( 2.0))
    , ('METAL5.metal5.extention.cap'        , l( 1.0))
    , ('METAL6.minimum.width'               , l( 2.0))
    , ('METAL6.metal6.extention.cap'        , l( 1.0))
    , ('METAL7.minimum.width'               , l( 2.0))
    , ('METAL7.metal7.extention.cap'        , l( 1.0))
    , ('METAL8.minimum.width'               , l( 2.0))
    , ('METAL8.metal8.extention.cap'        , l( 1.0))
    , ('METAL9.minimum.width'               , l( 2.0))
    , ('METAL9.metal9.extention.cap'        , l( 1.0))
    , ('METAL10.minimum.width'              , l( 2.0))
    , ('METAL10.metal10.extention.cap'      , l( 1.0))

    # Contacts (i.e. Active <--> Metal) (symbolic).
    , ('CONT_BODY_N.minimum.side'           , l( 1.0))
    , ('CONT_BODY_N.nWell.enclosure'        , l( 1.5))
    , ('CONT_BODY_N.nImplant.enclosure'     , l( 1.5))
    , ('CONT_BODY_N.active.enclosure'       , l( 1.0))
    , ('CONT_BODY_N.metal1.enclosure'       , l( 0.5))

    , ('CONT_BODY_P.minimum.side'           , l( 1.0))
    , ('CONT_BODY_P.pWell.enclosure'        , l( 1.5))
    , ('CONT_BODY_P.pImplant.enclosure'     , l( 1.5))
    , ('CONT_BODY_P.active.enclosure'       , l( 1.0))
    , ('CONT_BODY_P.metal1.enclosure'       , l( 0.5))

    , ('CONT_DIF_N.minimum.side'            , l( 1.0))
    , ('CONT_DIF_N.nImplant.enclosure'      , l( 1.0))
    , ('CONT_DIF_N.active.enclosure'        , l( 0.5))
    , ('CONT_DIF_N.metal1.enclosure'        , l( 0.5))

    , ('CONT_DIF_P.minimum.side'            , l( 1.0))
    , ('CONT_DIF_P.pImplant.enclosure'      , l( 1.0))
    , ('CONT_DIF_P.active.enclosure'        , l( 0.5))
    , ('CONT_DIF_P.metal1.enclosure'        , l( 0.5))

    , ('CONT_POLY.minimum.width'            , l( 1.0))
    , ('CONT_POLY.poly.enclosure'           , l( 0.5))
    , ('CONT_POLY.metal1.enclosure'         , l( 0.5))

    # VIAs (i.e. Metal <--> Metal) (symbolic).
    , ('VIA12.minimum.side'                 , l( 1.0))
    , ('VIA12.metal1.enclosure'             , l( 0.5))
    , ('VIA12.metal2.enclosure'             , l( 0.5))
    , ('VIA23.minimum.side'                 , l( 1.0))
    , ('VIA23.metal2.enclosure'             , l( 0.5))
    , ('VIA23.metal3.enclosure'             , l( 0.5))
    , ('VIA34.minimum.side'                 , l( 1.0))
    , ('VIA34.metal3.enclosure'             , l( 0.5))
    , ('VIA34.metal4.enclosure'             , l( 0.5))
    , ('VIA45.minimum.side'                 , l( 1.0))
    , ('VIA45.metal4.enclosure'             , l( 0.5))
    , ('VIA45.metal5.enclosure'             , l( 0.5))
    , ('VIA56.minimum.side'                 , l( 1.0))
    , ('VIA56.metal5.enclosure'             , l( 0.5))
    , ('VIA56.metal6.enclosure'             , l( 0.5))
    , ('VIA67.minimum.side'                 , l( 1.0))
    , ('VIA67.metal6.enclosure'             , l( 0.5))
    , ('VIA67.metal7.enclosure'             , l( 0.5))
    , ('VIA78.minimum.side'                 , l( 1.0))
    , ('VIA78.metal7.enclosure'             , l( 0.5))
    , ('VIA78.metal8.enclosure'             , l( 0.5))
    , ('VIA89.minimum.side'                 , l( 1.0))
    , ('VIA89.metal8.enclosure'             , l( 0.5))
    , ('VIA89.metal9.enclosure'             , l( 0.5))
    , ('VIA910.minimum.side'                , l( 1.0))
    , ('VIA910.metal9.enclosure'            , l( 0.5))
    , ('VIA910.metal10.enclosure'           , l( 0.5))

    # Blockages (symbolic).
    , ('BLOCKAGE1.minimum.width'            ,  l(1.0))
    , ('BLOCKAGE1.blockage1.extention.cap'  ,  l(0.5))
    , ('BLOCKAGE2.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE2.blockage2.extention.cap'  ,  l(0.5))
    , ('BLOCKAGE3.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE3.blockage3.extention.cap'  ,  l(0.5))
    , ('BLOCKAGE4.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE4.blockage4.extention.cap'  ,  l(0.5))
    , ('BLOCKAGE5.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE5.blockage5.extention.cap'  ,  l(1.0))
    , ('BLOCKAGE6.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE6.blockage6.extention.cap'  ,  l(1.0))
    , ('BLOCKAGE7.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE7.blockage7.extention.cap'  ,  l(1.0))
    , ('BLOCKAGE8.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE8.blockage8.extention.cap'  ,  l(1.0))
    , ('BLOCKAGE9.minimum.width'            ,  l(2.0))
    , ('BLOCKAGE9.blockage9.extention.cap'  ,  l(1.0))
    , ('BLOCKAGE10.minimum.width'           ,  l(2.0))
    , ('BLOCKAGE10.blockage10.extention.cap',  l(1.0))
    ]