;================================================================================ ; Robert Johnstone ; Simon Fraser University ; ; Copyright 2000,2002 Robert W. Johnstone ;-------------------------------------------------------------------------------- ; 2002/06/15 ; - fixed a bug that in drawing nitride breach when the width was not equal to ; the height ; 2002/06/07 ; - modified code so that capacitor is between poly0 and substrate ; 2002/06/04 ; - modified code to calculate capacitance when etch holes are not present ; 2002/06/03 ; - modified because dbCreateMumpsPin function interface was changed ; 2000/07/01 ; - created unless( boundp( 'admLibraryName ) warn( "Setting the destination library to default value of ADM" ) admLibraryName = "ADM" ) pcDefinePCell( list( ddGetObj(admLibraryName) "capacitor_0" "layout" ) ; end of list for first argument ( ( width 100.0 ) ( height 100.0 ) ( pin_size 20.0 ) ( include_C t ) ) ; end of parameter list prog( ( pcTechFile pcNet pcShape rodObj p0p1_minEnclosure p0p1_minSpacing p1p2_minEnclosure p1p2_minSPacing p2a2_minEnclosure p2v_minEnclosure p2m_minEnclosure v_minWidth v_nomWidth a2_minWidth a2_nomWidth b_nomWidth tmp tmp2 tmp3 ) ; load tech file rules pcTechFile = techGetTechFile( pcCellView ) p0p1_minEnclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY0" "POLY1" ) unless( p0p1_minEnclosure warn("minEnclosure rule for POLY0->POLY1 not set") ) p0p1_minSpacing = techGetSpacingRule( pcTechFile "minSpacing" "POLY0" "POLY1" ) unless( p0p1_minSpacing warn( "minSpacing rule for POLY0->POLY1 not set") ) p1p2_minEnclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "POLY2" ) unless( p1p2_minEnclosure warn( "minEnclosure rule for POLY1->POLY2 not set") ) p1p2_minSpacing = techGetSpacingRule( pcTechFile "minSpacing" "POLY1" "POLY2" ) unless( p1p2_minSpacing warn( "minSpacing rule for POLY1->POLY2 not set") ) p2a2_minEnclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "ANCHOR2" ) unless( p2a2_minEnclosure warn("minEnclosure rule for POLY2->ANCHOR2 not set") ) p2v_minEnclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "P1P2VIA" ) unless( p2v_minEnclosure warn("minEnclosure rule for POLY2->P1P2VIA not set") ) p2m_minEnclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "METAL" ) unless( p2m_minEnclosure warn("minEnclosure rule for POLY2->METAL not set") ) v_minWidth = techGetSpacingRule( pcTechFile "minWidth" "P1P2VIA" ) unless( v_minWidth warn( "minWidth rule for P1P2VIA not set" ) ) v_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "P1P2VIA" ) unless( v_nomWidth warn( "nomWidth rule for P1P2VIA not set" ) ) a2_minWidth = techGetSpacingRule( pcTechFile "minWidth" "ANCHOR2" ) unless( a2_minWidth warn( "minWidth rule for ANCHOR2 not set" ) ) a2_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "ANCHOR2" ) unless( a2_nomWidth warn( "nomWidth rule for ANCHOR2 not set" ) ) b_nomWidth = max( v_nomWidth 2*v_minWidth a2_nomWidth 2*a2_minWidth ) ; check parameters width = techGetMumpsPinSize( pcTechFile width-2*p0p1_minEnclosure ) + 2*p0p1_minEnclosure height = techGetMumpsPinSize( pcTechFile height-2*p0p1_minEnclosure ) + 2*p0p1_minEnclosure ; create bulk of capacitor dbCreateRect( pcCellView "POLY0" list( -width*0.5:-height*0.5 width*0.5:height*0.5 ) ) dbCreateMumpsRect( pcCellView nil list( -width*0.5+p0p1_minEnclosure:-height*0.5+p0p1_minEnclosure width*0.5-p0p1_minEnclosure:height*0.5-p0p1_minEnclosure ) ) ; nitride breach ring tmp = b_nomWidth + 2*max( p2v_minEnclosure p2a2_minEnclosure ) tmp2 = width*0.5 + p0p1_minSpacing + tmp*0.5 tmp3 = height*0.5 + p0p1_minSpacing + tmp*0.5 dbCreatePath( pcCellView "POLY2" list( -tmp2:pin_size*0.5 + p1p2_minSpacing -tmp2:tmp3 tmp2:tmp3 tmp2:-tmp3 -tmp2:-tmp3 -tmp2:-pin_size*0.5 - p1p2_minSpacing ) tmp ) dbCreatePath( pcCellView "METAL" list( -tmp2:pin_size*0.5 + p1p2_minSpacing + p2m_minEnclosure -tmp2:tmp3 tmp2:tmp3 tmp2:-tmp3 -tmp2:-tmp3 -tmp2:-pin_size*0.5 - p1p2_minSpacing - p2m_minEnclosure) tmp-2*p2m_minEnclosure ) dbCreatePath( pcCellView "P1P2VIA" list( -tmp2:pin_size*0.5 + p1p2_minSpacing + p2v_minEnclosure -tmp2:tmp3 tmp2:tmp3 tmp2:-tmp3 -tmp2:-tmp3 -tmp2:-pin_size*0.5 - p1p2_minSpacing - p2v_minEnclosure) tmp-2*p2v_minEnclosure ) dbCreatePath( pcCellView "ANCHOR2" list( -tmp2:pin_size*0.5 + p1p2_minSpacing + p2a2_minEnclosure -tmp2:tmp3 tmp2:tmp3 tmp2:-tmp3 -tmp2:-tmp3 -tmp2:-pin_size*0.5 - p1p2_minSpacing - p2a2_minEnclosure) tmp-2*p2a2_minEnclosure ) ; create first pin pcNet = dbMakeNet( pcCellView "C1" ) tmp = -width*0.5 - p0p1_minSpacing - b_nomWidth - 2*max(p2v_minEnclosure p2a2_minEnclosure) + pin_size*0.5 pcPin = dbCreateMumpsPin( pcCellView pcNet tmp:0 pin_size 0 ) pcPin~>accessDir = list( "left" ) dbCreateMumpsRect( pcCellView nil list( tmp-pin_size*0.5:-pin_size*0.5 width*0.5-p0p1_minEnclosure:pin_size*0.5 0 ) ) ; create second pin pcNet = dbMakeNet( pcCellView "C2" ) tmp = width*0.5 + p0p1_minSpacing + b_nomWidth + 2*max(p2v_minEnclosure p2a2_minEnclosure ) tmp2 = height*0.5 + p0p1_minSpacing + b_nomWidth + 2*max(p2v_minEnclosure p2a2_minEnclosure ) dbCreateMumpsRect( pcCellView pcNet list( tmp+p1p2_minSpacing:-tmp2 tmp+p1p2_minSpacing+pin_size:tmp2 ) ) dbCreateRect( pcCellView "POLY2" list( tmp:-tmp2+p1p2_minEnclosure tmp+p1p2_minSpacing+p1p2_minEnclosure:tmp2-p1p2_minEnclosure ) ) dbCreateRect( pcCellView "METAL" list( tmp-p2m_minEnclosure:-tmp2+p1p2_minEnclosure+p2m_minEnclosure tmp+p1p2_minSpacing+p1p2_minEnclosure+p2m_minEnclosure:tmp2-p1p2_minEnclosure-p2m_minEnclosure ) ) ; put capacitance estimate? if( (include_C==t) then ; get relative permittivity tmp = 7.5 ; get capacitance tmp = height * width * tmp * 8.854187818e-12 * 1e-12 / 0.6e-6 dbCreateLabel( pcCellView '("TMP" "drawing") 0:0 sprintf(nil "C = %1.3g" tmp) "centerCenter" "R0" "stick" pin_size*0.5 ) ) ; add stretch handles rodObj = rodGetObj( "" pcCellView ) rodAssignHandleToParameter( ?parameter "width" ?rodObj rodObj ?handleName list( "centerLeft" "centerRight" ) ?displayName "width" ?stretchDir "x" ?userFunction lambda( (SPCInfo) SPCInfo->paramVal + 2*SPCInfo->increment ) ) rodAssignHandleToParameter( ?parameter "height" ?rodObj rodObj ?handleName list( "lowerCenter" "upperCenter" ) ?displayName "height" ?stretchDir "y" ?userFunction lambda( (SPCInfo) SPCInfo->paramVal + 2*SPCInfo->increment ) ) ; Create the instNamePrefix property dbReplaceProp( pcCellView "instNamePrefix" "string" "capacitor" ) ; set version string dbReplaceProp( pcCellView "version" "string" "1.2.2" ) ; body SKILL code returns value t return(t) ) ; end of body-of-SKILL-code prog ) ; ; end of pcDefinePCell