DIRECTORY Atom, CMosCMTransistors, CMosObjects, CD, CDBasics, CDIO, CDLRUCache, CDOps, CDStretchyBackdoor, CMos, Rope, TokenIO; CMosCMTransistorsImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDIO, CDLRUCache, CDOps, CDStretchyBackdoor, CMos, CMosObjects, Rope, TokenIO EXPORTS CMosCMTransistors = BEGIN OPEN CMos; lambda: CD.Number = CMos.lambda; undef: CD.Layer = CD.undefLayer; depletionOverlap: CD.Number = (3*lambda)/2; wXExtension: CD.Number = CMosCMTransistors.wXExtension; lXExtension: CD.Number = CMosCMTransistors.lXExtension; wellSurround: CD.Number = CMos.wellSurround; TransistorPtr: TYPE = CMosCMTransistors.TransistorPtr; TransistorRec: TYPE = CMosCMTransistors.TransistorRec; tCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 15, aequivalenceProc: Aequivalent, newProc: NewTrans]; aCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 15, aequivalenceProc: Aequivalent, newProc: NewTrans]; Init: PROC [] = { pForTransistors.drawMe _ pForTransistors.quickDrawMe _ DrawMeForTransistors; pForTransistors.internalRead _ ReadTrans; pForTransistors.internalWrite _ WriteTrans; pForTransistors.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForTransistors, MatchTrans]; pForPTypeTransistors.drawMe _ pForPTypeTransistors.quickDrawMe _ DrawPTypeTransistors; pForPTypeTransistors.internalRead _ ReadTrans; pForPTypeTransistors.internalWrite _ WriteTrans; pForPTypeTransistors.interestRect _ PTransInterestRect; pForPTypeTransistors.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForPTypeTransistors, MatchTrans]; pForATransistors.drawMe _ pForATransistors.quickDrawMe _ DrawMeForATransistors; pForATransistors.internalRead _ ReadATrans; pForATransistors.internalWrite _ WriteATrans; pForATransistors.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForATransistors, MatchTrans]; pForPTypeATransistors.drawMe _ pForPTypeATransistors.quickDrawMe _ DrawPTypeATransistors; pForPTypeATransistors.internalRead _ ReadATrans; pForPTypeATransistors.internalWrite _ WriteATrans; pForPTypeATransistors.interestRect _ APTransInterestRect; pForPTypeATransistors.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForPTypeATransistors, MatchTrans]; }; Aequivalent: PROC[mySpecific, other: REF ANY] RETURNS [BOOL] = { WITH other SELECT FROM tp2: TransistorPtr => RETURN [NARROW[mySpecific, TransistorPtr]^=tp2^]; ENDCASE => RETURN [FALSE] }; NewTrans: PROC [] RETURNS [CD.Object] = { ob: CD.Object _ NEW[CD.ObjectRep]; ob.specific _ NEW[TransistorRec]; RETURN [ob] }; Describe: CD.DescribeProc = { tp: TransistorPtr = NARROW[ob.specific]; RETURN [ Rope.Cat[ (IF tp.angle THEN "angle transistor " ELSE "transistor "), Atom.GetPName[CD.LayerKey[ob.layer]], Rope.Cat[ " [", CDOps.LambdaRope[tp.width, 2], CDOps.LambdaRope[tp.length, 2], "]" ] ] ] }; PTransInterestRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = { beyondPolyX: CD.Number = MAX[0, wellSurround-NARROW[ob.specific, TransistorPtr].wExt]; RETURN [CD.Rect[x1: 0, y1: 0, x2: ob.bbox.x2-beyondPolyX, y2: ob.bbox.y2-wellSurround]] }; APTransInterestRect: PROC [ob: CD.Object] RETURNS [CD.Rect] = { beyondPolyX: CD.Number = MAX[0, wellSurround-NARROW[ob.specific, TransistorPtr].wExt]; RETURN [CD.Rect[x1: 0, y1: 0, x2: ob.bbox.x2-wellSurround, y2: ob.bbox.y2-beyondPolyX]] }; pForTransistors: CD.ObjectClass ~ RegisterObjectClass[$CMosTransistor]; pForPTypeTransistors: CD.ObjectClass ~ RegisterObjectClass[$CMosPTypeTransistor]; CreateTransistor: PUBLIC PROC [w, l: CD.Number, wExt: CD.Number_wXExtension, lExt: CD.Number_lXExtension, difLev: CD.Layer_undef] RETURNS [CD.Object] = BEGIN tob: CD.Object _ tCache.UnusedOrNew[]; tp: TransistorPtr _ NARROW[tob.specific]; IF difLev=undef THEN difLev_ndif; tob.class _ pForTransistors; w _ MAX[w, 2*lambda]; l _ MAX[l, 2*lambda]; wExt _ MAX[wExt, 0]; lExt _ MAX[lExt, 0]; tp.width _ w; tp.length _ l; tp.wExt _ wExt; tp.lExt _ lExt; tp.angle _ FALSE; tob.layer _ difLev; IF difLev=pdif THEN { beyondPolyX: CD.Number = MAX[0, wellSurround-tp.wExt]; tob.class _ pForPTypeTransistors; tob.bbox _ [-beyondPolyX, -wellSurround, w+2*wExt+beyondPolyX, l+2*lExt+wellSurround]; } ELSE { tob.bbox _ [0, 0, w+2*wExt, l+2*lExt]; tob.class _ pForTransistors; }; IF wExt=wXExtension AND lExt=lXExtension THEN { IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; RETURN [CMosObjects.CreateTransistor[[w+2*wExt, l+2*lExt], difLev]] }; RETURN [tCache.ReplaceByAequivalent[tob]] END; MatchTrans: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN RETURN [layer=CMos.pol OR layer=me.layer] END; ReadTrans: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN w: INT = TokenIO.ReadInt[h]; l: INT = TokenIO.ReadInt[h]; wExt: INT = TokenIO.ReadInt[h]; lExt: INT = TokenIO.ReadInt[h]; difLev: CD.Layer = CDIO.ReadLayer[h]; RETURN [CreateTransistor[w: w, l: l, wExt: wExt, lExt: lExt, difLev: difLev]]; END; WriteTrans: CD.InternalWriteProc -- PROC [ob: Object] -- = BEGIN tp: TransistorPtr = NARROW[ob.specific]; TokenIO.WriteInt[h, tp.width]; TokenIO.WriteInt[h, tp.length]; TokenIO.WriteInt[h, tp.wExt]; TokenIO.WriteInt[h, tp.lExt]; CDIO.WriteLayer[h, ob.layer]; END; DrawMeForTransistors: CD.DrawProc = BEGIN class: TransistorPtr = NARROW[ob.specific]; CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[r, trans], l] }; CDDraw[[class.wExt, 0, class.wExt+class.width, ob.bbox.y2], ob.layer]; -- ndif or pdiff CDDraw[[0, class.lExt, ob.bbox.x2, class.lExt+class.length], pol]; END; DrawPTypeTransistors: CD.DrawProc = BEGIN CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[r, trans], l] }; class: TransistorPtr = NARROW[ob.specific]; beyondWellX: CD.Number = MAX[0, class.wExt-wellSurround]; --object outside well beyondDiffusionX: CD.Number = MAX[class.wExt, wellSurround]; --object outside diffusion beyondPolyX: CD.Number = MAX[0, wellSurround-class.wExt]; --object outside poly CDDraw[ob.bbox, nwell]; CDDraw[[class.wExt, 0, class.wExt+class.width, ob.bbox.y2-wellSurround], ob.layer]; -- dif or pdiff CDDraw[[0, class.lExt, ob.bbox.x2-beyondPolyX, class.lExt+class.length], pol]; END; pForATransistors: CD.ObjectClass ~ RegisterObjectClass[$CMosATransistor]; pForPTypeATransistors: CD.ObjectClass ~ RegisterObjectClass[$CMosPTypeATransistor]; CreateAngleTransistor: PUBLIC PROC [w, l: CD.Number, wExt: CD.Number_wXExtension, lExt: CD.Number_lXExtension, aExt: CD.Number_0, difLev: CD.Layer_undef] RETURNS [CD.Object] = BEGIN tob: CD.Object _ aCache.UnusedOrNew[]; tp: TransistorPtr _ NARROW[tob.specific]; IF difLev=undef THEN difLev_ndif; wExt _ MAX[wExt, 0]; lExt _ MAX[lExt, 0]; aExt _ MAX[aExt, -lExt]; w _ MAX[w, 2*lExt]; -- the width of the straight-line l _ MAX[l, 2*lambda]; tp.width _ w; tp.length _ l; tp.wExt _ wExt; tp.lExt _ lExt; tp.angle _ TRUE; tob.layer _ difLev; IF difLev=pdif THEN { beyondPolyX: CD.Number = MAX[0, wellSurround-tp.wExt]; tob.class _ pForPTypeATransistors; tob.bbox _ [-beyondPolyX, -wellSurround, w+l+wExt-aExt+wellSurround, wExt+2*lExt+aExt+l+beyondPolyX]; } ELSE { tob.bbox _ [0, 0, w+l+wExt-aExt, wExt+2*lExt+aExt+l]; tob.class _ pForATransistors; }; RETURN [aCache.ReplaceByAequivalent[tob]] END; ReadATrans: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN w: INT = TokenIO.ReadInt[h]; l: INT = TokenIO.ReadInt[h]; wExt: INT = TokenIO.ReadInt[h]; lExt: INT = TokenIO.ReadInt[h]; aExt: INT = TokenIO.ReadInt[h]; difLev: CD.Layer = CDIO.ReadLayer[h]; RETURN [ CreateAngleTransistor[w: w, l: l, wExt: wExt, lExt: lExt, aExt: aExt, difLev: difLev] ]; END; AngleExt: PROC[tob: CD.Object] RETURNS [CD.Number] = { tp: TransistorPtr = NARROW[tob.specific]; IF tob.layer=pdif OR tob.layer=nwellCont THEN { beyondPolyX: CD.Number = MAX[0, wellSurround-tp.wExt]; RETURN [tp.width+tp.length+tp.wExt+beyondPolyX+wellSurround-tob.bbox.x2+tob.bbox.x1] }; RETURN [tp.width+tp.length+tp.wExt-tob.bbox.x2] }; WriteATrans: CD.InternalWriteProc -- PROC [ob: Object] -- = BEGIN tp: TransistorPtr = NARROW[ob.specific]; TokenIO.WriteInt[h, tp.width]; TokenIO.WriteInt[h, tp.length]; TokenIO.WriteInt[h, tp.wExt]; TokenIO.WriteInt[h, tp.lExt]; TokenIO.WriteInt[h, AngleExt[ob]]; CDIO.WriteLayer[h, ob.layer]; END; DrawMeForATransistors: CD.DrawProc = BEGIN class: TransistorPtr = NARROW[ob.specific]; CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[r, trans], l] }; r: CD.Rect = CDBasics.MapRect[ob.bbox, trans]; IF CDBasics.Intersect[r, pr.interestClip] THEN { ele: CD.Number = 2*class.lExt+class.length; sz: CD.Position _ CDBasics.SizeOfRect[ob.bbox]; hPoly: CD.Rect = [0, class.lExt, sz.x-class.lExt, class.length+class.lExt]; -- horizontal vPoly: CD.Rect = [sz.x-class.length-class.lExt, hPoly.y2, hPoly.x2, sz.y]; -- vertical nDrain: CD.Rect = [class.wExt, 0, sz.x, hPoly.y1]; -- north eDrain: CD.Rect = [vPoly.x2, nDrain.y2, nDrain.x2, sz.y-class.wExt]; -- east wSource: CD.Rect = [sz.x-ele, eDrain.y1, eDrain.x1, sz.y-class.wExt]; -- west sSource: CD.Rect = [MIN[class.wExt, wSource.x1], nDrain.y2, wSource.x1, MIN[ele, wSource.y2]]; -- south IF class.lExt>0 THEN BEGIN CDDraw[nDrain, ob.layer]; CDDraw[eDrain, ob.layer]; END; CDDraw[wSource, ob.layer]; CDDraw[sSource, ob.layer]; CDDraw[hPoly, pol]; CDDraw[vPoly, pol]; } END; DrawPTypeATransistors: CD.DrawProc = BEGIN class: TransistorPtr = NARROW[ob.specific]; CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[r, trans], l] }; r: CD.Rect = CDBasics.MapRect[ob.bbox, trans]; IF CDBasics.Intersect[r, pr.interestClip] THEN { sz: CD.Position _ CD.InterestSize[ob]; ele: CD.Number = 2*class.lExt+class.length; hPoly: CD.Rect = [0, class.lExt, sz.x-class.lExt, class.length+class.lExt]; -- horizontal vPoly: CD.Rect = [sz.x-class.length-class.lExt, hPoly.y2, hPoly.x2, sz.y]; -- vertical nDrain: CD.Rect = [class.wExt, 0, sz.x, hPoly.y1]; -- north eDrain: CD.Rect = [vPoly.x2, nDrain.y2, nDrain.x2, sz.y-class.wExt]; -- east wSource: CD.Rect = [sz.x-ele, eDrain.y1, eDrain.x1, sz.y-class.wExt]; -- west sSource: CD.Rect = [MIN[class.wExt, wSource.x1], nDrain.y2, wSource.x1, MIN[ele, wSource.y2]]; -- south IF class.lExt>0 THEN BEGIN CDDraw[nDrain, ob.layer]; CDDraw[eDrain, ob.layer]; END; CDDraw[wSource, ob.layer]; CDDraw[sSource, ob.layer]; CDDraw[hPoly, pol]; CDDraw[vPoly, pol]; CDDraw[ob.bbox, nwell]; } END; Init[]; END. LCMosCMTransistorsImpl.mesa (part of Chipndale) Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. Created by: Christian Jacobi June 24, 1983 5:03 pm Last edited by: Christian Jacobi, October 31, 1986 4:12:31 pm PST ?? RETURN [CD.Rect[x1: beyondPolyX, y1: wellSurround, x2: ob.size.x-wellSurround, y2: ob.size.y-beyondPolyX]] -- Transistor -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Don't care about different diffusions and such --uses outer stuff!! uses outer stuff!! -- Angle Transistor -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- parts of the gate, excluding corner uses outer stuff!! --The transistor makes a 90-degree bend, going eastward and --then southward. The diffusion on the outer side of the angle, --that is, on the northeast side, is arbitrarily called the drain. uses outer stuff!! --The transistor makes a 90-degree bend, going eastward and --then southward. The diffusion on the outer side of the angle, --that is, on the northeast side, is arbitrarily called the drain. Κ *˜codešœ/™/Kšœ Οmœ7™BKšœ5™5K™AK˜—šΟk ˜ K˜Kšœ˜Kšœ ž˜ Kšžœ˜K˜ K˜K˜ Kšœ˜Kšœ˜K˜K˜K˜K˜—šΟbœžœžœ˜%Kšžœb˜iKšžœ˜—Kšžœžœ˜K˜Kšœžœ˜ Kšœžœ˜ K˜Kšœžœ˜+Kšœ žœ(˜7Kšœ žœ(˜7Kšœžœ˜,K˜Kšœžœ#˜6Kšœžœ#˜6Kšœl˜lKšœl˜lK˜šΟnœžœ˜šœL˜LKšœ)˜)Kšœ+˜+Kšœ$˜$KšœA˜A—šœV˜VKšœ.˜.Kšœ0˜0Kšœ7˜7Kšœ)˜)KšœF˜F—šœO˜OKšœ+˜+Kšœ-˜-Kšœ%˜%KšœB˜B—šœY˜YKšœ0˜0Kšœ2˜2Kšœ9˜9Kšœ*˜*KšœG˜G—Kšœ˜—K˜š   œžœžœžœžœžœ˜@šžœžœž˜Kšœžœžœ#˜GKšžœžœžœ˜—K˜—K˜š œžœžœžœ ˜)Kšœžœ žœžœ ˜"Kšœžœ˜!Kšžœ˜ K˜—K˜š œ˜Kšœžœ˜(šžœ˜šœ ˜ Kšœžœ žœžœ˜:Kšœžœ˜%šœ ˜ Kšœ˜Kšœ˜Kšœ˜K˜K˜—Kšœ˜—Kšœ˜—Kšœ˜—K˜š  œžœžœ žœžœ ˜>Kšœ žœ žœžœ#˜VKšžœžœN˜XKšœ˜K˜—š  œžœžœ žœžœ ˜?Kšœ žœ žœžœ#˜VKšžœžœN˜XKšž œžœa™nKšœ˜K˜—Kšœ\™\K˜Kšœžœ4˜GKšœžœ9˜QK˜š œžœžœžœžœžœžœžœžœ ˜—Kšž˜Kšœžœ˜&Kšœžœ˜)Kšžœžœ˜"Kšœ˜Kšœžœ˜Kšœžœ˜Kšœžœ ˜Kšœžœ ˜K˜ K˜K˜K˜Kšœ žœ˜K˜šžœ žœ˜Kšœ žœ žœ˜6K˜!JšœW˜WKšœ˜—šžœ˜J˜'Kšœ˜Kšœ˜—šžœžœžœ˜/Kšžœžœ˜-Kšžœ=˜CK˜—Kšžœ#˜)šžœ˜K˜——š Πbn Ÿžœ4žœžœžœžœ˜fKšž˜Kšœ1™1Kšžœžœ˜)Kšžœ˜—K˜K˜šŸ œžœΟcœ˜=Kšž˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ%˜%KšžœH˜NKšžœ˜—K˜š  œžœ’œ˜:Kšž˜Kšœžœ˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜Kšžœ˜—K˜š œžœ ˜#Kšž˜Kšœžœ˜+K˜š  œžœžœ žœ žœ˜0Kš’™Kšœ/˜/Kšœ˜K˜—KšœG’˜WKšœB˜BKšžœ˜—K˜š œžœ ˜#Kšž˜K˜š  œžœžœ žœ žœ˜0Kšœ™Kšœ/˜/Kšœ˜K˜—Kšœžœ˜+Kšœ žœ žœ’˜OKšœžœ žœ’˜WKšœ žœ žœ’˜OK™Kšœ˜JšœT’˜cJšœN˜NKšžœ˜—K˜K˜Kšœb™bK˜Kšœžœ5˜IKšœžœ:˜SK˜š œžœžœžœ ˜6Kšœžœ˜Kšœžœ˜Kšœžœ ˜Kšœžœ˜Kšžœžœ ˜Kšž˜Kšœžœ˜&Kšœžœ˜)Kšžœžœ˜"Kšœžœ ˜Kšœžœ ˜Kšœžœ˜šœžœ ’!˜5Kšœ&™&—Kšœžœ˜K˜ K˜K˜K˜Kšœ žœ˜K˜šžœ žœ˜Kšœ žœ žœ˜6Kšœ"˜"Jšœf˜fKšœ˜—šžœ˜J˜6Kšœ˜Kšœ˜—Kšžœ#˜)Kšžœ˜K˜—š‘ œžœ’œ˜>Kšž˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ žœ˜%Kšžœ[˜aKšžœ˜—K˜š  œžœžœ žœžœ ˜6Kšœžœ˜)šžœžœžœ˜/Kšœ žœ žœ˜6KšžœN˜TK˜—Kšžœ)˜/Kšœ˜—K˜š  œžœ’œ˜;Kšž˜Kšœžœ˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ"˜"Kšžœ˜Kšžœ˜—K˜š œžœ ˜$Kšž˜Kšœžœ˜+K˜š  œžœžœ žœ žœ˜0Kšœ™Kšœ/˜/Kšœ˜—J™Kš’;™;Kš’@™@Kš’B™BK™Jšœžœ)˜.šžœ(žœ˜0Kšœžœ$˜+Kšœžœ)˜/KšœžœC’ ˜YKšœžœB’ ˜VKšœžœ)’˜;Kšœžœ;’˜LKšœ žœ;’˜MKšœ žœ žœ1žœ’˜gšžœž˜Kšž˜Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜K˜K˜Kšœ˜—Kšžœ˜K˜—š œžœ ˜$Kšž˜Kšœžœ˜+K˜š  œžœžœ žœ žœ˜0Kšœ™Kšœ/˜/Kšœ˜—K™Kš’;™;Kš’@™@Kš’B™BK˜Jšœžœ)˜.šžœ(žœ˜0Kšœžœ žœ˜&Kšœžœ$˜+KšœžœC’ ˜YKšœžœB’ ˜VKšœžœ)’˜;Kšœžœ;’˜LKšœ žœ;’˜MKšœ žœ žœ1žœ’˜gšžœž˜Kšž˜Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜K˜K˜Kšœ˜K˜—Kšžœ˜—K˜K˜Kšžœ˜K˜—…—(Œ9