added nofill layers, refactor code
This commit is contained in:
parent
c6499cab23
commit
4f25a4a4aa
374
inductor_2.il
374
inductor_2.il
@ -12,7 +12,6 @@ debug = nil
|
|||||||
; DEBUG output function, uncomment to get all output
|
; DEBUG output function, uncomment to get all output
|
||||||
(procedure output( @rest args)
|
(procedure output( @rest args)
|
||||||
(when debug (apply 'printf args))
|
(when debug (apply 'printf args))
|
||||||
;()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
; VECTOR HELPER FUNCTIONS
|
; VECTOR HELPER FUNCTIONS
|
||||||
@ -63,6 +62,33 @@ debug = nil
|
|||||||
result
|
result
|
||||||
)
|
)
|
||||||
|
|
||||||
|
; Tests if a float x is zero in respect to the manufacturing grid
|
||||||
|
; (smaller then one grid spacing)
|
||||||
|
(defun ind_isZero (x)
|
||||||
|
abs(x)<1/mfgGrid
|
||||||
|
)
|
||||||
|
|
||||||
|
; return the sign of the input
|
||||||
|
; (ind_sign 20) = 1
|
||||||
|
; (ind_sign -10) = -1
|
||||||
|
; (ind_sign 0) = 0
|
||||||
|
(defun ind_sign (x)
|
||||||
|
(if ind_isZero(x)
|
||||||
|
then 0
|
||||||
|
else
|
||||||
|
(if (x > 0)
|
||||||
|
then 1
|
||||||
|
else -1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
; only returns vectors with their sign as components
|
||||||
|
; e.g. (cleanupDirVect 0.1:-20) == 1:-1
|
||||||
|
(defun cleanDirVect (vect)
|
||||||
|
(ind_sign car(vect)):(ind_sign cadr(vect))
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
; DRAWING HELPER FUNCTIONS
|
; DRAWING HELPER FUNCTIONS
|
||||||
; creates a pin using database functions
|
; creates a pin using database functions
|
||||||
; and a corresponding net with name name
|
; and a corresponding net with name name
|
||||||
@ -145,6 +171,7 @@ debug = nil
|
|||||||
; Creates the start of the inductor
|
; Creates the start of the inductor
|
||||||
; and places a pin there
|
; and places a pin there
|
||||||
(defun ind_createStart (id start width dir)
|
(defun ind_createStart (id start width dir)
|
||||||
|
(let (center points)
|
||||||
center = start; (addVect start multVect((invVect dir) width/2))
|
center = start; (addVect start multVect((invVect dir) width/2))
|
||||||
|
|
||||||
points = list(
|
points = list(
|
||||||
@ -153,12 +180,13 @@ debug = nil
|
|||||||
(addVect center width:(-width))
|
(addVect center width:(-width))
|
||||||
(addVect center (-width):(-width))
|
(addVect center (-width):(-width))
|
||||||
)
|
)
|
||||||
/*(ind_createPin
|
(ind_createPin
|
||||||
id
|
id
|
||||||
"outer"
|
"outer"
|
||||||
points
|
points
|
||||||
list("TopMetal2" "drawing")
|
list("TopMetal2" "drawing")
|
||||||
)*/
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
; creates one segment of the inductor and calls itself recursively to complete
|
; creates one segment of the inductor and calls itself recursively to complete
|
||||||
@ -201,7 +229,7 @@ debug = nil
|
|||||||
isend = (n < 1)
|
isend = (n < 1)
|
||||||
|
|
||||||
; DEBUG
|
; DEBUG
|
||||||
output("seg: %d, n: %L (start: %L, end: %L)\n", mod(seg, nseg), n, isstart, isend)
|
(output "seg: %d, n: %L (start: %L, end: %L)\n", mod(seg, nseg), n, isstart, isend)
|
||||||
|
|
||||||
when(isend
|
when(isend
|
||||||
l = (lenVect dir)
|
l = (lenVect dir)
|
||||||
@ -238,8 +266,9 @@ debug = nil
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
when(isstart ind_createStart(id start whalv ndir))
|
; FIXME: broken, and underpass is not generated anyway
|
||||||
when((n<=1) ind_createEnd(id end whalv ndir))
|
;when(isstart ind_createStart(id start whalv ndir))
|
||||||
|
;when((n<=1) ind_createEnd(id end whalv ndir))
|
||||||
|
|
||||||
n -= 1
|
n -= 1
|
||||||
(output "n=%L\n", n)
|
(output "n=%L\n", n)
|
||||||
@ -249,106 +278,20 @@ debug = nil
|
|||||||
) ; when
|
) ; when
|
||||||
)
|
)
|
||||||
|
|
||||||
defun(ind_gndshield (r width pitch gap window)
|
|
||||||
(output "draw gnd shield with r=%L and w=%L\n", r, width)
|
|
||||||
|
|
||||||
r2 = r + width
|
(defun ind_drawOctagon (r w1 w2 layer shorting)
|
||||||
m = 1/tan(mconst.PI/nseg)
|
(let (a b start end)
|
||||||
segw = 2*r/m
|
; define start
|
||||||
pitch += width
|
a = (snap r*tanalpha)
|
||||||
|
; a = (floor r*tanalpha*mfgGrid)/(0.25*mfgGrid)
|
||||||
(defun iszero (x)
|
|
||||||
abs(x) < 1/mfgGrid
|
|
||||||
)
|
|
||||||
|
|
||||||
(defun sign (x)
|
|
||||||
(if iszero(x)
|
|
||||||
then 0
|
|
||||||
else
|
|
||||||
(if (x > 0)
|
|
||||||
then 1
|
|
||||||
else -1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(defun cleanup (vect)
|
|
||||||
(sign car(vect)):(sign cadr(vect))
|
|
||||||
)
|
|
||||||
|
|
||||||
for(n 0 nseg-1
|
|
||||||
angle = mconst.PI*2/nseg * n
|
|
||||||
rotmat = list(
|
|
||||||
list(cos(angle) -sin(angle))
|
|
||||||
list(sin(angle) cos(angle))
|
|
||||||
)
|
|
||||||
|
|
||||||
w1 = width
|
|
||||||
w = w1
|
|
||||||
(when ((mod n 2) == 1)
|
|
||||||
w2 = w1*sqrt(2)
|
|
||||||
w= w2
|
|
||||||
)
|
|
||||||
|
|
||||||
w1 = (snap w1)
|
|
||||||
w2 = (snap w2)
|
|
||||||
|
|
||||||
w = (snap w)
|
|
||||||
|
|
||||||
; contact_ring = append(contact_ring list(list(r2*cos(angle-mconst.PI/nseg) r2*sin(angle-mconst.PI/nseg))))
|
|
||||||
|
|
||||||
for(y 0 floor(segw/(2*pitch))
|
|
||||||
yr = (snap y*pitch)
|
|
||||||
a = (snap min(yr*m + gap, r))
|
|
||||||
l = (r-a)
|
|
||||||
|
|
||||||
(when ((mod n 2) == 1)
|
|
||||||
l /= sqrt(2)
|
|
||||||
)
|
|
||||||
|
|
||||||
l = (snap l)
|
|
||||||
|
|
||||||
|
|
||||||
dir = (cleanup matmult(rotmat 0:-1))
|
|
||||||
|
|
||||||
(output "%P\n", dir)
|
|
||||||
|
|
||||||
start = matmult(rotmat yr:r)
|
|
||||||
start = (floor((car start)*50.0)/50.0):(floor((cadr start)*50.0)/50.0)
|
|
||||||
end = (addVect start (multVect dir l))
|
|
||||||
|
|
||||||
(dbCreatePathSeg
|
|
||||||
id
|
|
||||||
gndshield_layer
|
|
||||||
start
|
|
||||||
end
|
|
||||||
w
|
|
||||||
"truncate"
|
|
||||||
"truncate"
|
|
||||||
)
|
|
||||||
|
|
||||||
when(y != 0
|
|
||||||
start = -car(start):cadr(start)
|
|
||||||
end = -car(end):cadr(end)
|
|
||||||
|
|
||||||
dbCreatePathSeg(
|
|
||||||
id
|
|
||||||
gndshield_layer
|
|
||||||
start
|
|
||||||
end
|
|
||||||
w
|
|
||||||
"truncate"
|
|
||||||
"truncate"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) ; for
|
|
||||||
|
|
||||||
a = (floor r/m*mfgGrid/2)/(0.5*mfgGrid)
|
|
||||||
b = (snap r)
|
b = (snap r)
|
||||||
|
|
||||||
start = 0:0
|
start = 0:0
|
||||||
end = 0:0
|
end = 0:0
|
||||||
(print n)
|
|
||||||
|
(for n 0 8
|
||||||
|
(let (w)
|
||||||
|
w = (if mod(n 2)==1 then w2 else w1)
|
||||||
|
|
||||||
(case n
|
(case n
|
||||||
(0
|
(0
|
||||||
@ -381,11 +324,11 @@ defun(ind_gndshield (r width pitch gap window)
|
|||||||
)
|
)
|
||||||
(7
|
(7
|
||||||
start = -b:a
|
start = -b:a
|
||||||
end = (addVect -a:b -window:-window)
|
end = (addVect -a:b -shorting:-shorting)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
; draw contact ring
|
; draw ring segment
|
||||||
(apply 'dbCreatePathSeg
|
(apply 'dbCreatePathSeg
|
||||||
id
|
id
|
||||||
gndshield_layer
|
gndshield_layer
|
||||||
@ -408,15 +351,91 @@ defun(ind_gndshield (r width pitch gap window)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
) ; END apply
|
||||||
|
) ; END let
|
||||||
|
) ; END for
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(defun ind_gndshield2 (yr)
|
||||||
|
(let (a l)
|
||||||
|
a = min((yr*m + gap) r)
|
||||||
|
l = (r-a)
|
||||||
|
|
||||||
|
when(l>0
|
||||||
|
; DEBUG
|
||||||
|
(output "(r=%L, m=%L, w=%L) yr=%L, a=%L, length=%L\n" m r w yr a l)
|
||||||
|
|
||||||
|
(when ((mod n 2) == 1)
|
||||||
|
l /= sqrt(2)
|
||||||
|
)
|
||||||
|
|
||||||
|
l = (snap l)
|
||||||
|
|
||||||
|
dir = (cleanDirVect matmult(rotmat 0:-1))
|
||||||
|
|
||||||
|
start = matmult(rotmat yr:r)
|
||||||
|
; start = (snap (car start)):(snap (cadr start))
|
||||||
|
start = (floor((car start)*50.0)/50.0):(floor((cadr start)*50.0)/50.0)
|
||||||
|
end = (addVect start (multVect dir l))
|
||||||
|
|
||||||
|
; DEBUG
|
||||||
|
(output "start=%P, end=%P (dir=%P)\n" start end dir)
|
||||||
|
|
||||||
|
(dbCreatePathSeg
|
||||||
|
id
|
||||||
|
gndshield_layer
|
||||||
|
start
|
||||||
|
end
|
||||||
|
w
|
||||||
|
"truncate"
|
||||||
|
"truncate"
|
||||||
|
)
|
||||||
|
|
||||||
|
when(yr != 0
|
||||||
|
; DEBUG
|
||||||
|
(output "create mirror at y=%L\n" -yr)
|
||||||
|
start = -car(start):cadr(start)
|
||||||
|
end = -car(end):cadr(end)
|
||||||
|
|
||||||
|
dbCreatePathSeg(
|
||||||
|
id
|
||||||
|
gndshield_layer
|
||||||
|
start
|
||||||
|
end
|
||||||
|
w
|
||||||
|
"truncate"
|
||||||
|
"truncate"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(ind_gndshield2 yr+pitch)
|
||||||
|
) ; END when
|
||||||
|
) ; END let
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun ind_gndshield (r w1 w2 pitch gap window)
|
||||||
|
(let (n w)
|
||||||
|
for(n 0 nseg-1
|
||||||
|
; DEBUG
|
||||||
|
angle = mconst.PI*2/nseg * n
|
||||||
|
rotmat = list(
|
||||||
|
list(cos(angle) -sin(angle))
|
||||||
|
list(sin(angle) cos(angle))
|
||||||
|
)
|
||||||
|
|
||||||
|
w = if((mod n 2)==1 then w2 else w1)
|
||||||
|
|
||||||
|
(output "draw a gndshield part with w=%L\n" w)
|
||||||
|
(ind_gndshield2 0)
|
||||||
|
) ; END for
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
; uses ind_drawSegment to create a complete inductor with
|
; uses ind_drawSegment to create a complete inductor with
|
||||||
; the given specification
|
; the given specification
|
||||||
defun(drawInductor (n r width pitch)
|
defun(drawInductor (n r width pitch)
|
||||||
|
(let (id w whalv w2 w2halv ahalv talpha hl nseg)
|
||||||
; the PCell cell view id
|
; the PCell cell view id
|
||||||
id = pcCellView
|
id = pcCellView
|
||||||
|
|
||||||
@ -436,7 +455,6 @@ defun(drawInductor (n r width pitch)
|
|||||||
w2halv = snap(width*sqrt(2)/2)
|
w2halv = snap(width*sqrt(2)/2)
|
||||||
w2 = 2*w2halv
|
w2 = 2*w2halv
|
||||||
|
|
||||||
|
|
||||||
pitch = snap(pitch + w) ; pitch from segment sides
|
pitch = snap(pitch + w) ; pitch from segment sides
|
||||||
r = snap(r - whalv) ; middle radius
|
r = snap(r - whalv) ; middle radius
|
||||||
nseg = 8 ; octagonal inductor
|
nseg = 8 ; octagonal inductor
|
||||||
@ -447,16 +465,130 @@ defun(drawInductor (n r width pitch)
|
|||||||
hl = snap((r-w/2)*talpha) ; start point
|
hl = snap((r-w/2)*talpha) ; start point
|
||||||
|
|
||||||
; draw inductor
|
; draw inductor
|
||||||
|
(let (dir)
|
||||||
(ind_drawSegment id n*nseg 0 -hl:r r)
|
(ind_drawSegment id n*nseg 0 -hl:r r)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
(defun drawGndShield (r pitch width window)
|
(defun drawGndShield (r layer pitch width window)
|
||||||
; setup gndshield
|
; setup gndshield
|
||||||
id = pcCellView
|
(let (id gndshield_layer nseg dir tanalpha m w1 w2 ymax)
|
||||||
gndshield_layer = '("Metal1" "drawing")
|
r -= (snap width/2)
|
||||||
nseg = 8
|
w1 = (snap width*1.0)
|
||||||
|
w2 = (snap width*1.0*sqrt(2))
|
||||||
|
|
||||||
(ind_gndshield r pitch width width*2 (snap window))
|
id = pcCellView
|
||||||
|
gndshield_layer = layer
|
||||||
|
nseg = 8
|
||||||
|
tanalpha = tan(mconst.PI/nseg)
|
||||||
|
|
||||||
|
segw = r/2.0*tanalpha
|
||||||
|
pitch += width
|
||||||
|
m = 1/tanalpha
|
||||||
|
ymax = floor(segw/(2*pitch))
|
||||||
|
|
||||||
|
(output "draw gnd shield with nfins=%L, r=%L, segw=%L, segcount=%L and w=%L on %L\n" ymax r segw (floor segw/(2*pitch)) width gndshield_layer)
|
||||||
|
|
||||||
|
; draw the gndshield itself
|
||||||
|
(ind_gndshield r w1 w2 pitch width*2 (snap window))
|
||||||
|
|
||||||
|
; draw contact ring
|
||||||
|
(ind_drawOctagon r w1 w2 gndshield_layer window)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(defun ind_getOctagonPoints (r w1 w2 shorting)
|
||||||
|
(let (a b start end)
|
||||||
|
; define start
|
||||||
|
a = (floor r*tan(mconst.PI/8)*mfgGrid*0.5)/(0.5*mfgGrid)
|
||||||
|
b = (snap r)
|
||||||
|
|
||||||
|
start = 0:0
|
||||||
|
end = 0:0
|
||||||
|
result=list()
|
||||||
|
|
||||||
|
(for n 0 8
|
||||||
|
(let (w)
|
||||||
|
w = (if mod(n 2)==1 then w2 else w1)
|
||||||
|
|
||||||
|
(case n
|
||||||
|
(0
|
||||||
|
start = -a:b
|
||||||
|
end = a:b
|
||||||
|
)
|
||||||
|
(1
|
||||||
|
start = a:b
|
||||||
|
end = b:a
|
||||||
|
)
|
||||||
|
(2
|
||||||
|
start = b:a
|
||||||
|
end = b:-a
|
||||||
|
)
|
||||||
|
(3
|
||||||
|
start = b:-a
|
||||||
|
end = a:-b
|
||||||
|
)
|
||||||
|
(4
|
||||||
|
start = a:-b
|
||||||
|
end = -a:-b
|
||||||
|
)
|
||||||
|
(5
|
||||||
|
start = -a:-b
|
||||||
|
end = -b:-a
|
||||||
|
)
|
||||||
|
(6
|
||||||
|
start = -b:-a
|
||||||
|
end = -b:a
|
||||||
|
)
|
||||||
|
(7
|
||||||
|
start = -b:a
|
||||||
|
end = (addVect -a:b -shorting:-shorting)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result=(append result list(list(start end w)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun ind_segmentsToPolygon (seg)
|
||||||
|
(output "segments=%L\n" seg)
|
||||||
|
result = list(caar(seg))
|
||||||
|
seg = cdr(seg)
|
||||||
|
|
||||||
|
(when seg
|
||||||
|
result = (append result (ind_segmentsToPolygon seg))
|
||||||
|
)
|
||||||
|
result
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun drawBlockLayer (points layers)
|
||||||
|
(let (layer)
|
||||||
|
layer = car(layers)
|
||||||
|
layers = cdr(layers)
|
||||||
|
|
||||||
|
; DEBUG
|
||||||
|
(output "draw block layer %L\n", layer)
|
||||||
|
|
||||||
|
(dbCreatePolygon
|
||||||
|
pcCellView
|
||||||
|
layer
|
||||||
|
points
|
||||||
|
)
|
||||||
|
|
||||||
|
(when layers
|
||||||
|
(drawBlockLayer points layers)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun drawBlockLayers (r layers)
|
||||||
|
points = (ind_segmentsToPolygon (ind_getOctagonPoints r 0 0 0))
|
||||||
|
(output "polygon points %L\n", points)
|
||||||
|
(drawBlockLayer points layers)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun setup ()
|
(defun setup ()
|
||||||
@ -471,20 +603,38 @@ defun(drawInductor (n r width pitch)
|
|||||||
list(
|
list(
|
||||||
( turns "float" 1.0 )
|
( turns "float" 1.0 )
|
||||||
( radius "float" 100.0 )
|
( radius "float" 100.0 )
|
||||||
( width "float" 2.1 ); techGetSpacingRule(techGetTechFile(pcCellView) "minWidth" "TopMetal2" ))
|
( width "float" 2.1 )
|
||||||
( pitch "float" 2.1 )
|
( pitch "float" 2.1 )
|
||||||
|
; gndshield parameters
|
||||||
( gndshield "boolean" nil )
|
( gndshield "boolean" nil )
|
||||||
( gndpitch "float" 2.1 )
|
( gndpitch "float" 2.1 )
|
||||||
( gndwidth "float" 2.1 )
|
( gndwidth "float" 2.1 )
|
||||||
( gndoverlap "float" 3 )
|
( gndoverlap "float" 3 )
|
||||||
( gndwindow "float" 2.1 )
|
( gndwindow "float" 2.1 )
|
||||||
|
; layer setup
|
||||||
|
( blockLayers "ilList" '(
|
||||||
|
("Metal1" "nofill")
|
||||||
|
("Metal2" "nofill")
|
||||||
|
("Metal3" "nofill")
|
||||||
|
("TopMetal1" "nofill")
|
||||||
|
("TopMetal2" "nofill")
|
||||||
|
("GatPoly" "nofill")
|
||||||
|
("Activ" "nofill")
|
||||||
|
("PWell" "block")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
( gndShieldLayer "ilList" '("Metal1" "drawing"))
|
||||||
)
|
)
|
||||||
(let
|
(let
|
||||||
()
|
()
|
||||||
(setup)
|
(setup)
|
||||||
|
; (print blockLayers)
|
||||||
(drawInductor turns radius width pitch)
|
(drawInductor turns radius width pitch)
|
||||||
(when gndshield
|
(when gndshield
|
||||||
(drawGndShield radius+gndoverlap gndwidth gndpitch gndwindow)
|
(drawGndShield radius+gndoverlap gndShieldLayer gndwidth gndpitch gndwindow)
|
||||||
|
)
|
||||||
|
(when blockLayers
|
||||||
|
(drawBlockLayers radius+gndoverlap blockLayers)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user