From 5c9c6ecefc2ad75edeb620832bf0de752a6de5d8 Mon Sep 17 00:00:00 2001 From: Julian Daube Date: Thu, 6 Dec 2018 16:55:09 +0100 Subject: [PATCH] add gnd shield --- inductor_2 | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 236 insertions(+), 10 deletions(-) diff --git a/inductor_2 b/inductor_2 index e32bbf6..964798d 100644 --- a/inductor_2 +++ b/inductor_2 @@ -46,6 +46,23 @@ debug = nil (multVect vect 1.0/(lenVect vect)) ) +; multiplies a point p with a 2x2 matrix m +(defun matmult (m p) + result = list() + + for(j 1 2 + temp = 0 + for(i 1 2 + a = nthelem(j nthelem(i m)) + b = nthelem(i p) + temp += a*b + ) + result = append(result list(temp)) + ) + + result +) + ; DRAWING HELPER FUNCTIONS ; creates a pin using database functions ; and a corresponding net with name name @@ -80,7 +97,8 @@ debug = nil (defun ind_createEnd (id start w dir) (output "[createEnd] start=%P dir=%P\n", start, dir) (let - (center points left right up) + (center points left right up viaDef) + viaDef = (techFindViaDefByName (techGetTechFile id) "TM2_TM1") center = (addVect start (multVect dir (snap -w/2))) left = (addVect center (multVect dir (snap -w/2))) right = (addVect center (multVect dir (snap w/2))) @@ -93,12 +111,34 @@ debug = nil (addVect left (invVect up)) ) - (ind_createPin + /*(dbCreateVia + id + viaDef + (addVect center (multVect dir -w)) + "R0" + list( + list("cutWidth" (snap w-0.6)) + list("cutHeight" (snap w-0.6)) + ) + )*/ + + ; create underpass + /*(dbCreatePathSeg + id + underpassLayer + (addVect center (multVect dir -w)) + (addVect (addVect center (multVect dir -w)) (multVect up -20)) + w*2 + "extend" + "extend" + )*/ + + /*(ind_createPin id "inner" points list("TopMetal2" "drawing") - ) + )*/ ) ) @@ -113,12 +153,12 @@ debug = nil (addVect center width:(-width)) (addVect center (-width):(-width)) ) - (ind_createPin + /*(ind_createPin id "outer" points list("TopMetal2" "drawing") - ) + )*/ ) ; creates one segment of the inductor and calls itself recursively to complete @@ -209,6 +249,171 @@ debug = nil ) ; 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 + m = 1/tan(mconst.PI/nseg) + segw = 2*r/m + pitch += width + + (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) + + start = 0:0 + end = 0:0 + (print n) + + (case n + (0 + start = -a:b + end = a:b + ) + (1 + start = b:-a + end = a:-b + ) + (2 + start = b:-a + end = b:a + ) + (3 + start = a:b + end = b:a + ) + (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 -window:-window) + ) + ) + + ; draw contact ring + (apply 'dbCreatePathSeg + id + gndshield_layer + start + end + w + if(mod(n 2)==0 + then list( + "truncate" + "truncate" + list(0 0) + ) + else list( + "custom" + (if n==7 then "truncate" else "custom") + list( + w1/2 + (if n==7 then 0 else w1/2) + list(w1/2 w1/2 w2/2 w1/2 w1/2 w2/2) + ) + ) + ) + ) + ) + ) + +) + ; uses ind_drawSegment to create a complete inductor with ; the given specification defun(drawInductor (n r width pitch) @@ -220,12 +425,9 @@ defun(drawInductor (n r width pitch) ) ; when - ; get manufacturing grid spacing and set global accordingly - mfgGrid=1/techGetMfgGridResolution(techGetTechFile(id)) - (output "using manufacturing grid of %L\n", mfgGrid) - ; set multiple globals inductorLayer = '("TopMetal2", "drawing") + underpassLayer = '("TopMetal1", "drawing") output("generating inductor with r=%L, turns=%L, pitch=%L and width=%L\n" r n pitch width) whalv = snap(width/2) @@ -248,6 +450,21 @@ defun(drawInductor (n r width pitch) (ind_drawSegment id n*nseg 0 -hl:r r) ) +(defun drawGndShield (r pitch width window) + ; setup gndshield + id = pcCellView + gndshield_layer = '("Metal1" "drawing") + nseg = 8 + + (ind_gndshield r pitch width width*2 (snap window)) +) + +(defun setup () + ; get manufacturing grid spacing and set global accordingly + mfgGrid=1/techGetMfgGridResolution(techGetTechFile(pcCellView)) + (output "using manufacturing grid of %L\n", mfgGrid) +) + ; defines the inductor PCell (pcDefinePCell list( (ddGetObj "mmic14_inductors") "inductorPcell" "layout") @@ -256,10 +473,19 @@ defun(drawInductor (n r width pitch) ( radius "float" 100.0 ) ( width "float" 2.1 ); techGetSpacingRule(techGetTechFile(pcCellView) "minWidth" "TopMetal2" )) ( pitch "float" 2.1 ) + ( gndshield "boolean" nil ) + ( gndpitch "float" 2.1 ) + ( gndwidth "float" 2.1 ) + ( gndoverlap "float" 3 ) + ( gndwindow "float" 2.1 ) ) (let () - drawInductor(turns radius width pitch) + (setup) + (drawInductor turns radius width pitch) + (when gndshield + (drawGndShield radius+gndoverlap gndwidth gndpitch gndwindow) + ) ) )