;================================================================================ ; Robert Johnstone ; Simon Fraser University ; ; Last Modified: 2001/11/07 ; ; Copyright 2000 Robert W. Johnstone ;-------------------------------------------------------------------------------- ; 2001/11/07 ; - added code to create dimples on opaque Fresnel zones when wide enough ; - added code to create dimples on outside region of square frame unless( boundp( 'admLibraryName ) warn( "Setting the destination library to default value of ADM" ) admLibraryName = "ADM" ) pcDefinePCell( list( ddGetObj(admLibraryName) "fresnel_zone_plate_2" "layout" ) ; end of list for first argument ( ( focal_length 500.0 ) ( wavelength 1.550 ) ( radius 150.0 ) ( outside_ring 5.0 ) ( square_frame t ) ) ; end of parameter list prog( ; these are the variables ( pcTechFile rodObj minSpacing minWidth nomWidth maxWidth h_nomWidth pd_enclosure d_nomWidth d_maxSpacing poly hole n r0 r1 r2 count count2 tmp1 tmp2 tmp3 tmp4 x y theta x1 y1 x2 y2 x3 y3 x4 y4 ) poly = "POLY2" hole = "HOLE2" ; load tech file rules pcTechFile = techGetTechFile( pcCellView ) minSpacing = techGetSpacingRule( pcTechFile "minSpacing" poly ) unless( minSpacing warn( strcat( "minSpacing rule for " poly " not set") ) ) minWidth = techGetSpacingRule( pcTechFile "minWidth" poly ) unless( minWidth warn( strcat( "minWidth rule for " poly " not set") ) ) nomWidth = techGetSpacingRule( pcTechFile "nomWidth" poly ) unless( nomWidth warn( strcat( "nomWidth rule for " poly " not set") ) ) maxWidth = techGetSpacingRule( pcTechFile "maxWidth" poly ) unless( maxWidth warn( strcat( "nomWidth rule for " poly " not set") ) ) h_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" hole ) unless( h_nomWidth warn( strcat( "nomWidth rule for " hole " not set") ) ) pd_enclosure = techGetOrderedSpacingRule( pcTechFile "minEnclosure" poly "DIMPLE" ) unless( pd_enclosure warn( strcat( "minEnclosure rule for " poly "->DIMPLE not set") ) ) d_nomWidth = techGetSpacingRule( pcTechFile "nomWidth" "DIMPLE" ) unless( d_nomWidth warn( "nomWidth rule for DIMPLE not set") ) d_maxSpacing = techGetSpacingRule( pcTechFile "maxSpacing" "DIMPLE" ) unless( d_maxSpacing warn( "maxSpacing rule for DIMPLE not set" ) ) ; check parameters outside_ring = if( (outside_ringradius-outside_ring) radius r1) r1 = if( (r2>radius-outside_ring) radius r1) ; reassign r2 to outside of previous ring if( (n>2) then tmp1 = sqrt( (n-1)*focal_length*wavelength + (n-1)*(n-1)*wavelength*wavelength/4 ) tmp2 = sqrt( (n-1.5)*focal_length*wavelength + (n-1.5)*(n-1.5)*wavelength*wavelength/4 ) if( (r0-tmp1 > nomWidth*2) then dbCreatePolygon( pcCellView poly list( nomWidth*0.5:tmp2 nomWidth*0.5:r0-nomWidth nomWidth*1.5:r0 -nomWidth*1.5:r0 -nomWidth*0.5:r0-nomWidth -nomWidth*0.5:tmp2 ) ) dbCreatePolygon( pcCellView poly list( tmp2:nomWidth*0.5 r0-nomWidth:nomWidth*0.5 r0:nomWidth*1.5 r0:-nomWidth*1.5 r0-nomWidth:-nomWidth*0.5 tmp2:-nomWidth*0.5 ) ) dbCreatePolygon( pcCellView poly list( nomWidth*0.5:-tmp2 nomWidth*0.5:-r0+nomWidth nomWidth*1.5:-r0 -nomWidth*1.5:-r0 -nomWidth*0.5:-r0+nomWidth -nomWidth*0.5:-tmp2 ) ) dbCreatePolygon( pcCellView poly list( -tmp2:nomWidth*0.5 -r0+nomWidth:nomWidth*0.5 -r0:nomWidth*1.5 -r0:-nomWidth*1.5 -r0+nomWidth:-nomWidth*0.5 -tmp2:-nomWidth*0.5 ) ) else if( (r0-tmp1 > minWidth*2) then dbCreatePolygon( pcCellView poly list( nomWidth*0.5:tmp2 nomWidth*0.5:r0-minWidth nomWidth*0.5+minWidth:r0 -nomWidth*0.5-minWidth:r0 -nomWidth*0.5:r0-minWidth -nomWidth*0.5:tmp2 ) ) dbCreatePolygon( pcCellView poly list( tmp2:nomWidth*0.5 r0-minWidth:nomWidth*0.5 r0:nomWidth*0.5+minWidth r0:-nomWidth*0.5-minWidth r0-minWidth:-nomWidth*0.5 tmp2:-nomWidth*0.5 ) ) dbCreatePolygon( pcCellView poly list( nomWidth*0.5:-tmp2 nomWidth*0.5:-r0+minWidth nomWidth*0.5+minWidth:-r0 -nomWidth*0.5-minWidth:-r0 -nomWidth*0.5:-r0+minWidth -nomWidth*0.5:-tmp2 ) ) dbCreatePolygon( pcCellView poly list( -tmp2:nomWidth*0.5 -r0+minWidth:nomWidth*0.5 -r0:nomWidth*0.5+minWidth -r0:-nomWidth*0.5-minWidth -r0+minWidth:-nomWidth*0.5 -tmp2:-nomWidth*0.5 ) ) else dbCreateRect( pcCellView poly list( nomWidth*0.5:tmp2 -nomWidth*0.5:r0 ) ) dbCreateRect( pcCellView poly list( tmp2:nomWidth*0.5 r0:-nomWidth*0.5 ) ) dbCreateRect( pcCellView poly list( nomWidth*0.5:-tmp2 -nomWidth*0.5:-r0 ) ) dbCreateRect( pcCellView poly list( -tmp2:nomWidth*0.5 -r0:-nomWidth*0.5 ) ) ) ) ) ; create donut if( (r1d_nomWidth+2*pd_enclosure ) then count = ceiling( r1 / d_maxSpacing ) count = if( (count<4) 4 count ) tmp = 0.5 * ( r0 + r1 ) for( lp 0 count-1 theta = 2 * 3.1415926536 * lp / count x1 = - d_nomWidth*0.5 * cos( theta ) - ( tmp - d_nomWidth*0.5 ) * sin( theta ) y1 = - d_nomWidth*0.5 * sin( theta ) + ( tmp - d_nomWidth*0.5 ) * cos( theta ) x2 = d_nomWidth*0.5 * cos( theta ) - ( tmp - d_nomWidth*0.5 ) * sin( theta ) y2 = d_nomWidth*0.5 * sin( theta ) + ( tmp - d_nomWidth*0.5 ) * cos( theta ) x3 = d_nomWidth*0.5 * cos( theta ) - ( tmp + d_nomWidth*0.5 ) * sin( theta ) y3 = d_nomWidth*0.5 * sin( theta ) + ( tmp + d_nomWidth*0.5 ) * cos( theta ) x4 = - d_nomWidth*0.5 * cos( theta ) - ( tmp + d_nomWidth*0.5 ) * sin( theta ) y4 = - d_nomWidth*0.5 * sin( theta ) + ( tmp + d_nomWidth*0.5 ) * cos( theta ) dbCreatePolygon( pcCellView "DIMPLE" list( x1:y1 x2:y2 x3:y3 x4:y4 ) ) ) ) ; increment count n = n+2 ) ; create last ring, with either a square frame or a round frame depending if( (square_frame==t) then tmp1 = list( ) tmp2 = list( ) tmp3 = list( ) tmp4 = list( ) for( lp 0 fix(radius) theta = lp * 1.570796327 / fix(radius) x = cos(theta) * r0 y = sin(theta) * r0 tmp1 = cons( x:y tmp1 ) tmp2 = cons( -x:y tmp2 ) tmp3 = cons( x:-y tmp3 ) tmp4 = cons( -x:-y tmp4 ) ) tmp1 = cons( 0:radius tmp1 ) tmp1 = cons( radius:radius tmp1 ) tmp1 = cons( radius:0 tmp1 ) dbCreatePolygon( pcCellView poly tmp1 ) tmp2 = cons( 0:radius tmp2 ) tmp2 = cons( -radius:radius tmp2 ) tmp2 = cons( -radius:0 tmp2 ) dbCreatePolygon( pcCellView poly tmp2 ) tmp3 = cons( 0:-radius tmp3 ) tmp3 = cons( radius:-radius tmp3 ) tmp3 = cons( radius:0 tmp3 ) dbCreatePolygon( pcCellView poly tmp3 ) tmp4 = cons( 0:-radius tmp4 ) tmp4 = cons( -radius:-radius tmp4 ) tmp4 = cons( -radius:0 tmp4 ) dbCreatePolygon( pcCellView poly tmp4 ) else dbCreateDonut( pcCellView poly 0:0 radius r0 ) ) ; create etch holes if necessary r0 = sqrt( (n-2)*focal_length*wavelength + (n-2)*(n-2)*wavelength*wavelength/4 ); if( (square_frame==t) then count = ceiling( (radius*1.414213562-r0) / maxWidth ) for( lp 1 count-1 r1 = lp * (radius*1.414213562-r0) / count + r0 count2 = ceiling( 2 * 3.141592654 * r1 / maxWidth ) count2 = ceiling( count2 / 4 ) * 4 for( lp2 0 count2-1 tmp1 = lp2 * 2 * 3.141592654 / count2 tmp2 = sin( tmp1 ) * r1 tmp1 = cos( tmp1 ) * r1 tmp3 = radius - nomWidth - h_nomWidth * 0.5 if( (abs(tmp1)-radius) then tmp1 = if( (tmp1>radius-pd_enclosure-d_nomWidth*0.5) radius-pd_enclosure-d_nomWidth*0.5 tmp1 ) tmp1 = if( (tmp1<-radius+pd_enclosure+d_nomWidth*0.5) -radius+pd_enclosure+d_nomWidth*0.5 tmp1 ) ) if( ( tmp2-radius ) then tmp2 = if( (tmp2>radius-pd_enclosure-d_nomWidth*0.5) radius-pd_enclosure-d_nomWidth*0.5 tmp2 ) tmp2 = if( (tmp2<-radius+pd_enclosure+d_nomWidth*0.5) -radius+pd_enclosure+d_nomWidth*0.5 tmp2 ) ) if( (abs(tmp1)