first working pcell
This commit is contained in:
commit
65adac2bd5
266
inductor_2
Normal file
266
inductor_2
Normal file
@ -0,0 +1,266 @@
|
||||
(defMathConstants 'mconst)
|
||||
mfgGrid = 100.0
|
||||
debug = nil
|
||||
|
||||
; SNAPS STUFF TO GRID
|
||||
; uses global mfgGrid to do so, which gets redefined in generator
|
||||
; to the tech mfg grid using the techFile
|
||||
(defun snap (p)
|
||||
floor(p*mfgGrid)/mfgGrid
|
||||
)
|
||||
|
||||
; DEBUG output function, uncomment to get all output
|
||||
(procedure output( @rest args)
|
||||
(when debug (apply 'printf args))
|
||||
;()
|
||||
)
|
||||
|
||||
; VECTOR HELPER FUNCTIONS
|
||||
; add a vector vect to a point p
|
||||
(defun addVect (p vect)
|
||||
(car(p)+car(vect)):(cadr(p)+cadr(vect))
|
||||
)
|
||||
; multiplies a vector vect with a scalar
|
||||
(defun multVect (vect scalar)
|
||||
(car(vect)*scalar):(cadr(vect)*scalar)
|
||||
)
|
||||
; multiplies a vector vect with -1 (inverse)
|
||||
(defun invVect (vect)
|
||||
(multVect vect -1)
|
||||
)
|
||||
; subtracts two vectors from one another
|
||||
; (does vect2 - vect1)
|
||||
(defun subVect (vect1 vect2)
|
||||
(car(vect2)-car(vect1)):(cadr(vect2)-cadr(vect1))
|
||||
)
|
||||
; returns length of a vector
|
||||
(defun lenVect (vect)
|
||||
sqrt((1.0*car(vect)**2)+(1.0*cadr(vect)**2))
|
||||
)
|
||||
; rotates a vector vect by 90 CCW
|
||||
(defun rotVect (vect)
|
||||
cadr(vect):-car(vect)
|
||||
)
|
||||
; normalizes a vector vect by its length
|
||||
(defun normalizeVect (vect)
|
||||
(multVect vect 1.0/(lenVect vect))
|
||||
)
|
||||
|
||||
; DRAWING HELPER FUNCTIONS
|
||||
; creates a pin using database functions
|
||||
; and a corresponding net with name name
|
||||
; does so on the layer layer
|
||||
(defun ind_createPin (id name points layer)
|
||||
(leCreatePin
|
||||
id
|
||||
layer
|
||||
"polygon"
|
||||
points
|
||||
name
|
||||
"inputOutput"
|
||||
'("none")
|
||||
)
|
||||
|
||||
/*
|
||||
net = dbCreateNet(id name)
|
||||
fig = dbCreatePolygon(id layer points)
|
||||
trm = dbCreateTerm(net name "inputOutput")
|
||||
pin = dbCreatePin(net fig name trm)
|
||||
pin~>accessDir = '( "none" )
|
||||
*/
|
||||
|
||||
lab = dbCreateLabel(id '("TEXT") cadr(points) name "centerLeft" "R0" "roman" 3)
|
||||
|
||||
;output("created pin %s\n", name)
|
||||
)
|
||||
|
||||
; Creates the end connection for the inductor and
|
||||
; places a pin there
|
||||
; TODO: create underpass here
|
||||
(defun ind_createEnd (id start w dir)
|
||||
(output "[createEnd] start=%P dir=%P\n", start, dir)
|
||||
(let
|
||||
(center points left right up)
|
||||
center = (addVect start (multVect dir (snap -w/2)))
|
||||
left = (addVect center (multVect dir (snap -w/2)))
|
||||
right = (addVect center (multVect dir (snap w/2)))
|
||||
up = (multVect (rotVect dir) (snap w/2))
|
||||
|
||||
points = list(
|
||||
(addVect left up)
|
||||
(addVect right up)
|
||||
(addVect right (invVect up))
|
||||
(addVect left (invVect up))
|
||||
)
|
||||
|
||||
(ind_createPin
|
||||
id
|
||||
"inner"
|
||||
points
|
||||
list("TopMetal2" "drawing")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; Creates the start of the inductor
|
||||
; and places a pin there
|
||||
(defun ind_createStart (id start width dir)
|
||||
center = start; (addVect start multVect((invVect dir) width/2))
|
||||
|
||||
points = list(
|
||||
(addVect center (-width):width)
|
||||
(addVect center width:width)
|
||||
(addVect center width:(-width))
|
||||
(addVect center (-width):(-width))
|
||||
)
|
||||
(ind_createPin
|
||||
id
|
||||
"outer"
|
||||
points
|
||||
list("TopMetal2" "drawing")
|
||||
)
|
||||
)
|
||||
|
||||
; creates one segment of the inductor and calls itself recursively to complete
|
||||
; one inductor
|
||||
(defun ind_drawSegment (id n seg start r)
|
||||
dx = snap(r*talpha)
|
||||
|
||||
(case mod(seg, 8)
|
||||
(0
|
||||
end = dx:r
|
||||
)
|
||||
(1
|
||||
end = r:dx
|
||||
)
|
||||
(2
|
||||
end = r:-dx
|
||||
)
|
||||
(3
|
||||
end = dx:-r
|
||||
)
|
||||
(4
|
||||
end = -dx:-r
|
||||
)
|
||||
(5
|
||||
end = -r:-dx
|
||||
)
|
||||
(6
|
||||
end = -r:dx
|
||||
)
|
||||
(7
|
||||
r -= pitch
|
||||
end = (addVect start (r-dx):(r-dx))
|
||||
)
|
||||
)
|
||||
|
||||
dir = (subVect start end)
|
||||
ndir = (normalizeVect dir)
|
||||
|
||||
isstart = (seg == 0)
|
||||
isend = (n < 1)
|
||||
|
||||
; DEBUG
|
||||
output("seg: %d, n: %L (start: %L, end: %L)\n", mod(seg, nseg), n, isstart, isend)
|
||||
|
||||
when(isend
|
||||
l = (lenVect dir)
|
||||
|
||||
if((mod(seg,2)==0)
|
||||
then
|
||||
end = addVect(end multVect(ndir (snap l*(n-1))))
|
||||
else
|
||||
end = addVect(start multVect(ndir (snap l*(n-1))))
|
||||
)
|
||||
)
|
||||
|
||||
if((mod(seg, 2) == 0)
|
||||
then
|
||||
(dbCreatePathSeg
|
||||
id
|
||||
inductorLayer
|
||||
start
|
||||
end
|
||||
w
|
||||
if(!isstart then "custom" else "extend")
|
||||
if(!isend then "custom" else "truncate")
|
||||
list(if(isstart then 0 else whalv) if(isend then 0 else whalv) list(w2halv w2halv whalv w2halv w2halv whalv))
|
||||
)
|
||||
else
|
||||
(dbCreatePathSeg
|
||||
id
|
||||
inductorLayer
|
||||
start
|
||||
end
|
||||
w2
|
||||
"truncate"
|
||||
"truncate"
|
||||
)
|
||||
)
|
||||
|
||||
when(isstart ind_createStart(id start whalv ndir))
|
||||
when((n<=1) ind_createEnd(id end whalv ndir))
|
||||
|
||||
n -= 1
|
||||
(output "n=%L\n", n)
|
||||
|
||||
(when (n > 0)
|
||||
(ind_drawSegment id n seg+1 end r)
|
||||
) ; when
|
||||
)
|
||||
|
||||
; uses ind_drawSegment to create a complete inductor with
|
||||
; the given specification
|
||||
defun(drawInductor (n r width pitch)
|
||||
; the PCell cell view id
|
||||
id = pcCellView
|
||||
|
||||
(when (not id)
|
||||
(error "could not find cell view")
|
||||
) ; 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")
|
||||
output("generating inductor with r=%L, turns=%L, pitch=%L and width=%L\n" r n pitch width)
|
||||
|
||||
whalv = snap(width/2)
|
||||
w = whalv*2
|
||||
; diagonal segment width
|
||||
w2halv = snap(width*sqrt(2)/2)
|
||||
w2 = 2*w2halv
|
||||
|
||||
|
||||
pitch = snap(pitch + w) ; pitch from segment sides
|
||||
r = snap(r - whalv) ; middle radius
|
||||
nseg = 8 ; octagonal inductor
|
||||
|
||||
; calculation globals
|
||||
ahalv = mconst.PI/nseg ; angle between segments
|
||||
talpha = tan(ahalv)
|
||||
hl = snap((r-w/2)*talpha) ; start point
|
||||
|
||||
; draw inductor
|
||||
(ind_drawSegment id n*nseg 0 -hl:r r)
|
||||
)
|
||||
|
||||
; defines the inductor PCell
|
||||
(pcDefinePCell
|
||||
list( (ddGetObj "mmic14_inductors") "inductorPcell" "layout")
|
||||
list(
|
||||
( turns "float" 1.0 )
|
||||
( radius "float" 100.0 )
|
||||
( width "float" 2.1 ); techGetSpacingRule(techGetTechFile(pcCellView) "minWidth" "TopMetal2" ))
|
||||
( pitch "float" 2.1 )
|
||||
)
|
||||
(let
|
||||
()
|
||||
drawInductor(turns radius width pitch)
|
||||
)
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user