;================================================================================ ; Robert Johnstone ; Simon Fraser University ; ; Copyright 2000 Robert W. Johnstone ;-------------------------------------------------------------------------------- ; 2002/06/03 ; - modified code because interface to dbCreateRoundRect changed ; 2000/10/28 ; - created unless( boundp( 'admLibraryName ) warn( "Setting the destination library to default value of ADM" ) admLibraryName = "ADM" ) pcDefinePCell( list( ddGetObj(admLibraryName) "gear_dt" "layout" ) ; end of list for first argument ( ( radius 40.0 ) ( tooth_height 8.0 ) ( tooth_width_o 4.0 ) ( tooth_width_i 6.0 ) ( tooth_count 16 ) ( tooth_angle 0.0 ) ) ; end of parameter list prog( let( pcTechFile p1_minSpacing p1_maxWidth p1a1_enclosure p1p2_enclosure p1d_enclosure p1v_enclosure a1_nomWidth p2_nomSpacing p2_nomWidth p2p1_minOverlap p2v_enclosure v_nomWidth d_maxSpacing d_nomWidth h1_nomWidth h2_nomWidth h2h1_enclosure vp1_enclosure hub_o hub_i radius_d radius_fi radius_fo tmp1 tmp2 count_r count_t count_d x1 x2 x3 x4 y1 y2 y3 y4 theta ) ; to make definition of gear radius match definition of bearing radius ; upon which the gear is built radius = radius - tooth_height * 0.5 ; load tech file rules pcTechFile = techGetTechFile( pcCellView ) p1_minSpacing = techGetSpacingRule( pcTechFile "minSpacing" "POLY1" ) unless( p1_minSpacing warn("minSpacing rule for POLY1 not set") ) p1_maxWidth = techGetSpacingRule( pcTechFile "maxWidth" "POLY1" ) unless( p1_maxWidth warn("maxWidth 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") ) p1v_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY1" "P1P2VIA" ) unless( p1v_enclosure warn("minEnclosure rule for POLY1->P1P2VIA not set") ) a1_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "ANCHOR1" ) unless( a1_nomWidth warn("nomWidth rule for ANCHOR1 not set") ) p2_nomSpacing = techGetSpacingRule( pcTechFile "nomSpacing" "POLY2" ) unless( p2_nomSpacing warn("nomSpacing rule for POLY2 not set") ) p2_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "POLY2" ) unless( p2_nomWidth warn("nomWidth rule for POLY2 not set") ) p2p1_minOverlap = techGetOrderedSpacingRule( pcTechFile "minOverlap" "POLY2" "POLY1" ) unless( p2p1_minOverlap warn("minOverlap rule for POLY2->POLY1 not set") ) p2v_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "POLY2" "P1P2VIA" ) unless( p2v_enclosure warn("minEnclosure rule for POLY2->P1P2VIA not set") ) v_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "P1P2VIA" ) unless( v_nomWidth warn("nomWidth rule for P1P2VIA 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") ) h1_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "HOLE1" ) unless( h1_nomWidth warn("nomWidth rule for HOLE1 not set") ) h2_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "HOLE2" ) unless( h2_nomWidth warn("nomWidth rule for HOLE2 not set") ) h2h1_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "HOLE2" "HOLE1" ) unless( h2h1_enclosure warn("minEnclosure rule for HOLE2->HOLE1 not set") ) vp1_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" "P1P2VIA" "POLY1" ) unless( vp1_enclosure warn("minEnclosure rule for P1P2VIA->POLY1 not set (double thickness structures)" ) ) ; check parameters tooth_count = if( (tooth_count<4) 4 tooth_count ) h2_nomWidth = if( (h2_nomWidth v_nomWidth+p1v_enclosure ) (a1_nomWidth+p1a1_enclosure)*1.1 (v_nomWidth+p1v_enclosure)*1.1 ) dbCreateEllipse( pcCellView "POLY1" list( -hub_i:-hub_i hub_i:hub_i ) ) dbCreateEllipse( pcCellView "ANCHOR1" list( -(hub_i-p1a1_enclosure*1.1):-(hub_i-p1a1_enclosure*1.1) (hub_i-p1a1_enclosure*1.1):(hub_i-p1a1_enclosure*1.1) ) ) dbCreateEllipse( pcCellView "P1P2VIA" list( -(hub_i-p1v_enclosure*1.1):-(hub_i-p1v_enclosure*1.1) (hub_i-p1v_enclosure*1.1):(hub_i-p1v_enclosure*1.1) ) ) ; create bulk of wheel hub_o = hub_i + p1_minSpacing*1.1 dbCreateDonut( pcCellView "POLY1" 0:0 (radius+tooth_height+p1p2_enclosure*1.2) hub_o ) ; create flange radius_fo = radius - p1v_enclosure*1.1 - p2v_enclosure*1.1 radius_fi = radius_fo - p2_nomSpacing dbCreateEllipse( pcCellView "POLY2" list( -radius_fi:-radius_fi radius_fi:radius_fi ) ) dbCreateDonut( pcCellView "POLY2" 0:0 radius radius_fo ) dbCreateDonut( pcCellView "P1P2VIA" 0:0 radius+tooth_height+p1p2_enclosure*1.2+vp1_enclosure*1.1 radius_fo+p2v_enclosure*1.1 ) ; create teeth tooth_count = if( (tooth_count<4) 4 tooth_count ) for( lp 0 (tooth_count-1) theta = lp * 2 * 3.141592654 / tooth_count + tooth_angle * 3.141592654 / 180 x1 = ( tooth_width_o*0.5 ) * cos(theta) - ( radius + tooth_height ) * sin(theta) y1 = ( tooth_width_o*0.5 ) * sin(theta) + ( radius + tooth_height ) * cos(theta) x2 = ( -tooth_width_o*0.5 ) * cos(theta) - ( radius + tooth_height ) * sin(theta) y2 = ( -tooth_width_o*0.5 ) * sin(theta) + ( radius + tooth_height ) * cos(theta) x3 = ( -tooth_width_i*0.5 ) * cos(theta) - ( radius - 1 ) * sin(theta) y3 = ( -tooth_width_i*0.5 ) * sin(theta) + ( radius - 1 ) * cos(theta) x4 = ( tooth_width_i*0.5 ) * cos(theta) - ( radius - 1 ) * sin(theta) y4 = ( tooth_width_i*0.5 ) * sin(theta) + ( radius - 1) * cos(theta) dbCreatePolygon( pcCellView "POLY2" list( x1:y1 x2:y2 x3:y3 x4:y4 ) ) ) ; create dimples outside POLY2 radius_d = radius - p1d_enclosure - d_nomWidth*0.7 count_d = ceiling( radius_d * 2 * 3.141592654 / d_maxSpacing ) for( lp 0 (count_d-1) theta = lp * 2 * 3.141592654 / count_d x1 = - d_nomWidth*0.5 * cos( theta ) - ( radius_d - d_nomWidth*0.5 ) * sin( theta ) y1 = - d_nomWidth*0.5 * sin( theta ) + ( radius_d - d_nomWidth*0.5 ) * cos( theta ) x2 = d_nomWidth*0.5 * cos( theta ) - ( radius_d - d_nomWidth*0.5 ) * sin( theta ) y2 = d_nomWidth*0.5 * sin( theta ) + ( radius_d - d_nomWidth*0.5 ) * cos( theta ) x3 = d_nomWidth*0.5 * cos( theta ) - ( radius_d + d_nomWidth*0.5 ) * sin( theta ) y3 = d_nomWidth*0.5 * sin( theta ) + ( radius_d + d_nomWidth*0.5 ) * cos( theta ) x4 = - d_nomWidth*0.5 * cos( theta ) - ( radius_d + d_nomWidth*0.5 ) * sin( theta ) y4 = - d_nomWidth*0.5 * sin( theta ) + ( radius_d + d_nomWidth*0.5 ) * cos( theta ) dbCreatePolygon( pcCellView "DIMPLE" list( x1:y1 x2:y2 x3:y3 x4:y4 ) ) ) ; create etch holes count_r = floor( (radius - hub_o) / (p1_maxWidth+h1_nomWidth) ) for( lp 1 count_r tmp1 = hub_o + (radius-hub_o)*lp/(count_r+1) tmp2 = hub_o + (radius-hub_o)*(lp+0.5)/(count_r+1) count_t = floor( 6.283185307*tmp2 / (p1_maxWidth+h1_nomWidth*0.5) ) count_t = if( (count_t<2) 2 count_t ) ;count_t = if( (count_t<4) 4 count_t ) ;count_t = count_t + mod( count_t 2 ) for( lp2 0 count_t-1 theta = 6.283185307 * lp2 / count_t x1 = tmp1 * cos( theta ) y1 = tmp1 * sin( theta ) tmp2 = h1_nomWidth*0.5 dbCreateRect( pcCellView "HOLE1" list( x1-tmp2:y1-tmp2 x1+tmp2:y1+tmp2 ) ) tmp2 = h1_nomWidth*0.5 + h2h1_enclosure dbCreateRoundRect( pcCellView "HOLE2" list( x1-tmp2:y1-tmp2 x1+tmp2:y1+tmp2 ) h2h1_enclosure*0.5 ) ) ) ; create dimples count_d = ceiling( (radius-hub_o) / (d_maxSpacing+d_nomWidth*0.5) ) for( lp 0 count_d-1 ; align dimples with offset from etch holes lp = floor( lp * count_r / count_d ) tmp1 = hub_o + (radius-hub_o)*lp / (count_r+1) if( (lp>0) then tmp1 = tmp1 + h1_nomWidth*0.5 + h2h1_enclosure ) tmp1 = tmp1 + p2p1_minOverlap + h2_nomWidth*0.5 count_t = floor( 6.283185307*tmp1 / d_maxSpacing ) count_t = if( (count_t<2) 2 count_t ) ;count_t = if( (count_t<4) 4 count_t ) ;count_t = count_t + mod( count_t 2 ) for( lp2 0 count_t-1 theta = 6.283185307 * lp2 / count_t x1 = tmp1 * cos( theta ) y1 = tmp1 * sin( theta ) dbCreateRect( pcCellView "DIMPLE" list( x1-d_nomWidth*0.5:y1-d_nomWidth*0.5 x1+d_nomWidth*0.5:y1+d_nomWidth*0.5 ) ) dbCreateRect( pcCellView "HOLE2" list( x1-h2_nomWidth*0.5:y1-h2_nomWidth*0.5 x1+h2_nomWidth*0.5:y1+h2_nomWidth*0.5 ) ) ) ) ; Create the instNamePrefix property dbReplaceProp( pcCellView "instNamePrefix" "string" "gear" ) ; set version string dbReplaceProp( pcCellView "version" "string" "1.0.1" ) ; body SKILL code returns value t return(t) ) ; end of body-of-SKILL-code prog ) ; ; end of pcDefinePCell