;================================================================================ ; Robert Johnstone ; Simon Fraser University ; ; Copyright 2002 Robert W. Johnstone ;-------------------------------------------------------------------------------- ; 2002/06/03 ; - updated code because interface to dbCreateMumpsPin was changed ; 2002/01/19 ; - fixed bug that could lead to drc violations ; 2002/01/10 ; - first version unless( boundp( 'admLibraryName ) warn( "Setting the destination library to default value of ADM" ) admLibraryName = "ADM" ) pcDefinePCell( list( ddGetObj(admLibraryName) "curvuator" "layout" ) ; end of list for first argument ( ( length 200.0 ) ( actuation 30.0 ) ( order 2.5 ) ( chamfer 0.0 ) ( pin_size 20.0 ) ( include_dimples t ) ( include_poly0 t ) ) ; end of parameter list prog( ; declare variables ( pcTechFile pcNet pcPin rodObj p0p1_enclosure p0p1_minSpacing p1_minSpacing p1_minWidth p1_nomSpacing p1d_enclosure p1a1_enclosure p1p2_enclosure p2p0_enclosure p2v_enclosure p2m_enclosure a1_nomWidth d_maxSpacing d_nomWidth d_count a_offset poly1 poly2 tmp1 tmp2 tmp3 tmp4 tmp5 dydx count ) ; load tech file rules pcTechFile = techGetTechFile( pcCellView ) p0p1_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY0" "POLY1" ) unless( p0p1_enclosure 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") ) p0a1_minSpacing = techGetSpacingRule( pcTechFile "minSpacing" "POLY0" "ANCHOR1" ) unless( p0a1_minSpacing warn("minSpacing rule for POLY0->ANCHOR1 not set") ) p1_minSpacing = techGetSpacingRule( pcTechFile "minSpacing" "POLY1" ) unless( p1_minSpacing warn("minSpacing rule for POLY1 not set") ) p1_minWidth = techGetSpacingRule( pcTechFile "minWidth" "POLY1" ) unless( p1_minWidth warn("minWidth rule for POLY1 not set") ) p1_nomSpacing = techGetSpacingRule( pcTechFile "nomSpacing" "POLY1" ) unless( p1_nomSpacing warn("nomSpacing rule for POLY1 not set") ) p1a1_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "ANCHOR1" ) unless( p1a1_enclosure warn("minEnclosure rule for POLY1->ANCHOR1 not set") ) p1p2_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "POLY2" ) unless( p1p2_enclosure warn("minEnclosure rule for POLY1->POLY2 not set") ) p1d_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "DIMPLE" ) unless( p1d_enclosure warn("minEnclosure rule for POLY1->DIMPLE not set") ) a1_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "ANCHOR1" ) unless( a1_nomWidth warn("nomWidth rule for ANCHOR1 not set") ) p2p0_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "POLY0" ) unless( p2p0_enclosure warn("minEnclosure rule for POLY2->POLY0 not set") ) p2v_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "P1P2VIA" ) unless( p2v_enclosure warn("minEnclosure rule for POLY2->P1P2VIA not set" ) ) p2m_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "METAL" ) unless( p2m_enclosure warn("minEnclosure rule for POLY2->METAL not set" ) ) p1d_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "DIMPLE" ) unless( p1d_enclosure warn("minEnclosure rule for POLY1->DIMPLE not set") ) d_maxSpacing = techGetSpacingRule( pcTechFile "maxSpacing" "DIMPLE" ) unless( d_maxSpacing warn("maxSpacing rule for DIMPLE not set") ) d_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "DIMPLE" ) unless( d_nomWidth warn("nomWidth rule for DIMPLE not set") ) ; check parameters pin_size = techGetMumpsPinSize( pcTechFile pin_size ) ; precalculate parameters a_offset = if( (include_poly0==t) p0a1_minSpacing 0 ) ; create deflecting section dbCreateRect( pcCellView "POLY1" list( 0:-p1_minWidth*0.5 length:p1_minWidth*0.5 ) ) if( (include_dimples==t) then d_count = floor( length / d_maxSpacing ) for( lp 1 d_count tmp1 = lp * length / d_count tmp2 = d_nomWidth + 2*p1d_enclosure dbCreateRect( pcCellView "POLY1" list( tmp1-tmp2:p1_minWidth*0.5 tmp1:p1_minWidth*0.5-tmp2 ) ) dbCreateRect( pcCellView "DIMPLE" list( tmp1-tmp2+p1d_enclosure:p1_minWidth*0.5-p1d_enclosure tmp1-p1d_enclosure:p1_minWidth*0.5-tmp2+p1d_enclosure ) ) ) ) ; create curved electrode poly1 = list() poly2 = list() tmp5 = a1_nomWidth*1.01 + 2.02*p1a1_enclosure count = ceiling( length / p1_minWidth ) for( lp 0 count tmp1 = lp * length / count tmp2 = actuation * ( tmp1 / length ) ** order + p1_minWidth*0.5 + p1_minSpacing poly1 = cons( tmp1:tmp2 poly1 ) dydx = atan( actuation * order / length * ( tmp1 / length ) ** (order-1) ) tmp3 = tmp1 - tmp5 * sin( dydx ) tmp4 = tmp2 + tmp5 * cos( dydx ) + a_offset poly2 = cons( tmp3:tmp4 poly2 ) ) poly1 = append( poly1 reverse( poly2 ) ) dbCreatePolygon( pcCellView "POLY1" poly1 ) tmp4 = actuation + p1_minWidth*0.5 + p1_minSpacing dbCreateRect( pcCellView "POLY1" list( length:tmp4 length-tmp5:tmp4+tmp5+a_offset ) ) dbCreateRect( pcCellView "ANCHOR1" list( length-p1a1_enclosure:tmp4+p1a1_enclosure+a_offset length-tmp5+p1a1_enclosure:tmp4+tmp5-p1a1_enclosure+a_offset ) ) poly1 = list() poly1 = cons( -p1a1_enclosure:p1a1_enclosure+p1_minWidth*0.5+p1_minSpacing+a_offset poly1 ) poly2 = list() poly2 = cons( -p1a1_enclosure:p1a1_enclosure+p1_minWidth*0.5+p1_minSpacing+a1_nomWidth+a_offset poly1 ) count = ceiling( (length-p1a1_enclosure) / p1_minWidth ) for( lp 0 count tmp1 = lp * (length-p1a1_enclosure) / count tmp2 = actuation * ( tmp1 / length ) ** order + p1_minWidth*0.5 + p1_minSpacing dydx = atan( actuation * order / length * ( tmp1 / length ) ** (order-1) ) tmp3 = tmp1 - (a1_nomWidth + p1a1_enclosure) * 1.01 * sin( dydx ) tmp4 = tmp2 + (a1_nomWidth + p1a1_enclosure) * 1.01 * cos( dydx ) tmp1 = tmp1 - p1a1_enclosure * 1.01 * sin( dydx ) tmp2 = tmp2 + p1a1_enclosure * 1.01 * cos( dydx ) poly1 = cons( tmp1:tmp2+a_offset poly1 ) poly2 = cons( tmp3:tmp4+a_offset poly2 ) ) tmp1 = length - p1a1_enclosure tmp2 = actuation * ( tmp1 / length ) ** order + p1_minWidth*0.5 + p1_minSpacing dydx = atan( actuation * order / length * (tmp1 / length ) ** (order-1) ) tmp2 = tmp2 + p1a1_enclosure * 1.01 / cos( dydx ) poly1 = cons( tmp1:tmp2+a_offset poly1 ) tmp2 = tmp2 + a1_nomWidth * 1.01 / cos( dydx ) poly1 = cons( tmp1:tmp2+a_offset poly1 ) poly1 = append( poly1 reverse( poly2 ) ) dbCreatePolygon( pcCellView "ANCHOR1" poly1 ) ; create ground plane if( (include_poly0==t) then poly1 = list() tmp5 = a1_nomWidth*1.01 + 2.02*p1a1_enclosure count = ceiling( (length-p0p1_minSpacing) / p1_minWidth ) for( lp 0 count tmp1 = p0p1_minSpacing + lp * (length-p0p1_minSpacing) / count tmp2 = actuation * ( tmp1 / length ) ** order + p1_minWidth*0.5 + p1_minSpacing poly1 = cons( tmp1:tmp2+p0p1_enclosure poly1 ) ) poly1 = cons( length+p0p1_enclosure:tmp2+p0p1_enclosure poly1 ) if( (include_dimples==t) then poly1 = cons( length+p0p1_enclosure:p1_minWidth*0.5-p1d_enclosure*2-d_nomWidth-p0p1_enclosure poly1 ) poly1 = cons( p0p1_minSpacing:p1_minWidth*0.5-p1d_enclosure*2-d_nomWidth-p0p1_enclosure poly1 ) else poly1 = cons( length+p0p1_enclosure:-p1_minWidth*0.5-p0p1_enclosure poly1 ) poly1 = cons( p0p1_minSpacing:-p1_minWidth*0.5-p0p1_enclosure poly1 ) ) dbCreatePolygon( pcCellView "POLY0" poly1 ) tmp1 = -pin_size+p1_minWidth*0.5+p1p2_enclosure+p2p0_enclosure tmp2 = p1_minWidth*0.5-p1p2_enclosure-p2p0_enclosure dbCreateRect( pcCellView "POLY0" list( -pin_size+p1p2_enclosure+p2p0_enclosure:tmp1 p0p1_minSpacing:tmp2 ) ) if( (tmp1<-p1_minWidth*0.5-p0p1_enclosure) then dbCreatePolygon( pcCellView "POLY0" list( p0p1_minSpacing:tmp1 p0p1_minSpacing:-p1_minWidth*0.5-p0p1_enclosure p0p1_minSpacing-p1_minWidth*0.5-p0p1_enclosure-tmp1:-p1_minWidth*0.5-p0p1_enclosure ) ) ) ) ; create PWR pin pcNet = dbMakeNet( pcCellView "PWR" ) pcPin = dbCreateMumpsPin( pcCellView pcNet -pin_size*0.5:pin_size*0.5+p1_minWidth*0.5+p1_minSpacing pin_size chamfer ) pcPin~>accessDir = list( "bottom" "left" ) ; create GND pin pcNet = dbMakeNet( pcCellView "GND" ) pcPin = dbCreateMumpsPin( pcCellView pcNet -pin_size*0.5:-pin_size*0.5+p1_minWidth*0.5 pin_size chamfer ) pcPin~>accessDir = list( "bottom" "right" ) ; set default instance name prefix dbReplaceProp( pcCellView "instNamePrefix" "string" "actuator" ) ; set version string dbReplaceProp( pcCellView "version" "string" "1.1.1" ) ; body SKILL code returns value t return(t) ) ; end of body-of-SKILL-code prog ) ; ; end of pcDefinePCell