DIRECTORY CD, CDBasics, CDIO, CDBasicsInline, CDLRUCache, CDOps, CDStretchyBackdoor, NMos, NMosTransistors, Rope, TokenIO; NMosTransistorsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDBasicsInline, CDIO, CDLRUCache, CDOps, CDStretchyBackdoor, NMos, Rope, TokenIO EXPORTS NMosTransistors = BEGIN OPEN NMos; lambda: CD.Number = NMos.lambda; depletionOverlap: CD.Number = (3*lambda)/2; wXExtension: CD.Number = NMosTransistors.wXExtension; lXExtension: CD.Number = NMosTransistors.lXExtension; TransistorPtr: TYPE = NMosTransistors.TransistorPtr; TransistorRec: TYPE = NMosTransistors.TransistorRec; tCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 10, aequivalenceProc: Aequivalent, newProc: NewTrans]; aCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 10, aequivalenceProc: Aequivalent, newProc: NewTrans]; pCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 10, aequivalenceProc: Aequivalent, newProc: NewTrans]; 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] }; Init: PROC [] = BEGIN pForTransistors.drawMe _ pForTransistors.quickDrawMe _ DrawMeForTransistors; pForTransistors.internalRead _ ReadTrans; pForTransistors.internalWrite _ WriteTrans; pForTransistors.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForTransistors, MatchTrans]; CDStretchyBackdoor.InstallMakeSimilarProc[pForTransistors, MakeSimilarTrans]; pForATransistors.drawMe _ pForATransistors.quickDrawMe _ DrawMeForATransistors; pForATransistors.internalRead _ ReadATrans; pForATransistors.internalWrite _ WriteATrans; pForPullUps.drawMe _ pForPullUps.quickDrawMe _ DrawMeForPullUps; pForPullUps.internalRead _ ReadPull; pForPullUps.internalWrite _ WritePull; pForPullUps.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForPullUps, MatchTrans]; END; Describe: CD.DescribeProc = BEGIN tp: TransistorPtr = NARROW[ob.specific]; r: Rope.ROPE; IF tp.pullup THEN r _ "pullup " ELSE { r _ "transistor "; IF tp.angle THEN r _ Rope.Concat["angle ", r]; r _ Rope.Concat[r, SELECT tp.implant FROM NMosTransistors.enhancement => "enh ", NMosTransistors.zeroTresh => "0-tresh ", NMosTransistors.weakDepletion => "wk depl ", NMosTransistors.strongDepletion => "depl ", ENDCASE => "ERROR" ] }; r _ Rope.Cat[ r, " [", CDOps.LambdaRope[tp.width, 2], CDOps.LambdaRope[tp.length, 2], "]" ]; RETURN [r] END; MatchTrans: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN RETURN [layer=NMos.pol OR layer=me.layer] END; pForTransistors: CD.ObjectClass = RegisterObjectClass[$NMosTransistor]; CreateTransistor: PUBLIC PROC [w, l: CD.Number, implant: NMosTransistors.Implant_NMosTransistors.enhancement, wExt: CD.Number_wXExtension, lExt: CD.Number_lXExtension] RETURNS [CD.Object] = BEGIN tob: CD.Object ~ tCache.UnusedOrNew[]; tp: TransistorPtr ~ NARROW[tob.specific]; 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; tob.bbox _ [0, 0, w+2*wExt, l+2*lExt]; tp.implant _ implant; tp.angle _ FALSE; tp.pullup _ FALSE; tob.layer _ dif; RETURN [tCache.ReplaceByAequivalent[tob]] END; ReadTrans: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN w: INT = TokenIO.ReadInt[h]; l: INT = TokenIO.ReadInt[h]; implant: INT = TokenIO.ReadInt[h]; wExt: INT = TokenIO.ReadInt[h]; lExt: INT = TokenIO.ReadInt[h]; IF ~h.oldVersion AND CDIO.VersionKey[h]>=2 THEN RETURN [CreateTransistor[w: w, l: l, implant: implant, wExt: wExt, lExt: lExt]] ELSE RETURN [CreateTransistor[w: w, l: l, implant: (IF implant=1 THEN 3 ELSE 0), wExt: wExt, lExt: lExt]]; END; MakeSimilarTrans: CDStretchyBackdoor.MakeSimilarProc = { tp: TransistorPtr = NARROW[me.specific]; sz: CD.Position _ CDBasics.SizeOfRect[ir]; RETURN [ CreateTransistor[w: sz.x-2*tp.wExt, l: sz.y-2*tp.lExt, wExt: tp.wExt, lExt: tp.lExt,implant: tp.implant] ]; }; WriteTrans: CD.InternalWriteProc = BEGIN tp: TransistorPtr = NARROW[ob.specific]; TokenIO.WriteInt[h, tp.width]; TokenIO.WriteInt[h, tp.length]; TokenIO.WriteInt[h, tp.implant]; TokenIO.WriteInt[h, tp.wExt]; TokenIO.WriteInt[h, tp.lExt]; END; AngleExt: PROC[tob: CD.Object] RETURNS [CD.Number] = { tp: TransistorPtr = NARROW[tob.specific]; RETURN [tp.width+tp.length+tp.wExt-tob.bbox.x2] }; DrawMeForTransistors: CD.DrawProc = BEGIN class: TransistorPtr = NARROW[ob.specific]; CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[itemInCell: r, cellInWorld: trans], l]; }; CDDraw[[class.wExt, 0, class.wExt+class.width, ob.bbox.y2], ob.layer]; -- dif or pdiff CDDraw[[0, class.lExt, ob.bbox.x2, class.lExt+class.length], pol]; IF class.implant>0 THEN CDDraw[[class.wExt-depletionOverlap, class.lExt-depletionOverlap, ob.bbox.x2-class.wExt+depletionOverlap, ob.bbox.y2-class.lExt+depletionOverlap], SELECT class.implant FROM NMosTransistors.strongDepletion => imp, NMosTransistors.weakDepletion => impWeak, NMosTransistors.zeroTresh => imp0, NMosTransistors.enhancement => CD.errorLayer, ENDCASE => CD.errorLayer ]; END; pForATransistors: CD.ObjectClass = RegisterObjectClass[$NMosATransistor]; CreateAngleTransistor: PUBLIC PROC [w, l: CD.Number, implant: NMosTransistors.Implant_NMosTransistors.enhancement, wExt: CD.Number_wXExtension, lExt: CD.Number_lXExtension, aExt: CD.Number_0] RETURNS [CD.Object] = BEGIN tob: CD.Object _ aCache.UnusedOrNew[]; tp: TransistorPtr _ NARROW[tob.specific]; tob.class _ pForATransistors; 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; tob.bbox _ [0, 0, w+l+wExt-aExt, wExt+2*lExt+aExt+l]; tp.implant _ implant; tp.angle _ TRUE; tp.pullup _ FALSE; tob.layer _ dif; RETURN [aCache.ReplaceByAequivalent[tob]] END; ReadATrans: CD.InternalReadProc = BEGIN w: INT = TokenIO.ReadInt[h]; l: INT = TokenIO.ReadInt[h]; implant: INT = TokenIO.ReadInt[h]; wExt: INT = TokenIO.ReadInt[h]; lExt: INT = TokenIO.ReadInt[h]; aExt: INT = TokenIO.ReadInt[h]; IF ~h.oldVersion AND CDIO.VersionKey[h]>=2 THEN RETURN [ CreateAngleTransistor[w: w, l: l, implant: implant, wExt: wExt, lExt: lExt, aExt: aExt] ] ELSE RETURN [ CreateAngleTransistor[w: w, l: l, implant: (IF implant=1 THEN 3 ELSE 0), wExt: wExt, lExt: lExt, aExt: aExt] ]; END; WriteATrans: CD.InternalWriteProc = BEGIN tp: TransistorPtr = NARROW[ob.specific]; TokenIO.WriteInt[h, tp.width]; TokenIO.WriteInt[h, tp.length]; TokenIO.WriteInt[h, tp.implant]; TokenIO.WriteInt[h, tp.wExt]; TokenIO.WriteInt[h, tp.lExt]; TokenIO.WriteInt[h, tp.width+tp.length+tp.wExt-CD.InterestSize[ob].x]; END; DrawMeForATransistors: CD.DrawProc = BEGIN class: TransistorPtr = NARROW[ob.specific]; CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[itemInCell: r, cellInWorld: trans], l]; }; r: CD.Rect = CDBasicsInline.MapRect[ob.bbox, trans]; IF CDBasics.Intersect[r, pr.interestClip] THEN BEGIN ele: CD.Number = 2*class.lExt+class.length; hPoly: CD.Rect = [0, class.lExt, ob.bbox.x2-class.lExt, class.length+class.lExt]; -- horizontal vPoly: CD.Rect = [ob.bbox.x2-class.length-class.lExt, hPoly.y2, hPoly.x2, ob.bbox.y2]; -- vertical nDrain: CD.Rect = [class.wExt, 0, ob.bbox.x2, hPoly.y1]; -- north eDrain: CD.Rect = [vPoly.x2, nDrain.y2, nDrain.x2, ob.bbox.y2-class.wExt]; -- east wSource: CD.Rect = [ob.bbox.x2-ele, eDrain.y1, eDrain.x1, ob.bbox.y2-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 { CDDraw[nDrain, ob.layer]; CDDraw[eDrain, ob.layer]; }; CDDraw[wSource, ob.layer]; CDDraw[sSource, ob.layer]; CDDraw[hPoly, pol]; CDDraw[vPoly, pol]; IF class.implant>0 THEN { CDDraw[[nDrain.x1-depletionOverlap, hPoly.y1-depletionOverlap, hPoly.x2+depletionOverlap, hPoly.y2+depletionOverlap], imp]; CDDraw[[vPoly.x1-depletionOverlap, vPoly.y1-depletionOverlap, vPoly.x2+depletionOverlap, eDrain.y2+depletionOverlap], imp]; } END END; pForPullUps: CD.ObjectClass = RegisterObjectClass[$NMosPullUp]; CreatePullUp: PUBLIC PROC [w, l: CD.Number, wExt: CD.Number_wXExtension, lExt: CD.Number_lXExtension] RETURNS [CD.Object] = BEGIN puob: CD.Object ~ pCache.UnusedOrNew[]; pup: TransistorPtr ~ NARROW[puob.specific]; w _ MAX[w, 2*lambda]; l _ MAX[l, 2*lambda]; wExt _ MAX[wExt, 0]; lExt _ MAX[lExt, 0]; pup.wExt _ wExt; pup.lExt _ lExt; pup.width _ w; pup.length _ l; pup.pullup _ TRUE; puob.class _ pForPullUps; puob.bbox _ [0, 0, MAX[4*lambda, w+wExt*2], MAX[6*lambda, l+lExt+3*lambda]]; puob.layer _ dif; RETURN [pCache.ReplaceByAequivalent[puob]] END; ReadPull: 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]; RETURN [ CreatePullUp[w: w, l: l, wExt: wExt, lExt: lExt] ]; END; WritePull: CD.InternalWriteProc = 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]; END; DrawMeForPullUps: CD.DrawProc = BEGIN CDDraw: PROC[r: CD.Rect, l: CD.Layer] = INLINE { pr.drawRect[pr, CDBasics.MapRect[itemInCell: r, cellInWorld: trans], l]; }; r: CD.Rect = CDBasicsInline.MapRect[ob.bbox, trans]; IF CDBasics.Intersect[r, pr.interestClip] THEN { class: TransistorPtr = NARROW[ob.specific]; middleX: CD.Number = ob.bbox.x2/2; metal: CD.Rect = [x1: middleX-2*lambda, y1: ob.bbox.y2-6*lambda, x2: middleX+2*lambda, y2: ob.bbox.y2]; CDDraw[[class.wExt, 0, class.wExt+class.width, ob.bbox.y2], ob.layer]; CDDraw[[0, class.lExt, ob.bbox.x2, class.lExt+class.length], pol]; CDDraw[[0, 0, ob.bbox.x2, ob.bbox.y2-lambda], imp]; CDDraw[[metal.x1, metal.y1+2*lambda, metal.x2, metal.y2], ob.layer]; CDDraw[metal, met]; CDDraw[[metal.x1+lambda, metal.y1+lambda, metal.x2-lambda, metal.y2-lambda], cut]; } END; Init[]; END. .NMosTransistorsImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Created by: Christian Jacobi, June 24, 1983 5:03 pm Last edited by: Christian Jacobi, October 31, 1986 11:59:45 am PST -- Transistor -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --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. -- PullUp -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --uses outer stuff!! Κ ˜šœ-™-Jšœ Οmœ7™BJšœ4™4Icode™BJ˜—šΟk ˜ Jšžœ˜J˜ Jšœ˜Jšœ˜Jšœ ˜ J˜Jšœ˜J˜J˜J˜J˜J˜—šΟnœžœžœ˜#Jšžœ_˜fJšžœ˜—Jšžœžœ˜J˜Jšœžœ˜ J˜Jšœžœ˜+Jšœ žœ&˜5Jšœ žœ&˜5J˜Jšœžœ!˜4Jšœžœ!˜4J˜Jšœl˜lJšœl˜lJšœl˜lJ˜š Ÿ œžœžœžœžœžœ˜@šžœžœž˜Jšœžœžœ#˜GJšžœžœžœ˜—J˜—J˜šŸœžœžœžœ ˜)Jšœžœ žœžœ ˜"Jšœžœ˜!Jšžœ˜ Jšœ˜—J˜šŸœžœ˜Jšž˜JšœL˜LJšœ)˜)Jšœ+˜+Jšœ$˜$JšœA˜AJšœM˜MJ˜JšœO˜OJšœ+˜+Jšœ-˜-J˜Jšœ@˜@Jšœ$˜$Jšœ&˜&Jšœ ˜ Jšœ=˜=Jšžœ˜J˜—šŸœžœ˜Jšž˜Jšœžœ˜(Jšœžœ˜ Jšžœ žœ˜!šžœ˜Jšœ˜Jšžœ žœ˜.šœ˜šžœ ž˜Jšœ&˜&Jšœ(˜(Jšœ,˜,Jšœ+˜+Jšžœ ˜—J˜—J˜—šœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜Jšœ˜—Jšžœ˜ Jšžœ˜—J˜š Πbn Οbžœ4žœžœžœžœ˜fJšž˜Jšžœžœ˜)Jšžœ˜—J˜Jšœ\™\J˜Jšœžœ4˜GJ˜šŸœžœžœžœ ˜1Jšœ=˜=Jšœžœ˜Jšœžœ˜Jšžœžœ ˜Jšž˜Jšœžœ˜&Jšœžœ˜)Jšœ˜Jšœžœ˜Jšœžœ˜Jšœžœ ˜Jšœžœ ˜J˜ J˜J˜J˜J˜'J˜Jšœ žœ˜Jšœ žœ˜J˜Jšžœ#˜)Jšžœ˜J˜—š‘ œžœΟcœ˜=Jšž˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜"Jšœžœ˜Jšœžœ˜šžœžœžœžœ˜0JšžœI˜O—šž˜Jšžœ)žœ žœžœ˜e—Jšžœ˜—J˜š œ(˜8Kšœžœ˜(Kšœžœ$˜*Kšžœn˜tKšœ˜K˜—šŸ œžœ˜"Jšž˜Jšœžœ˜(Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšžœ˜—J˜J˜š Ÿœžœžœ žœžœ ˜6Jšœžœ˜)Jšžœ)˜/Jšœ˜—˜J˜—šŸœ˜#Jšž˜Jšœžœ˜+J˜š Ÿœžœžœ žœ ž˜0Jšœ™JšœH˜HJšžœ˜J˜—JšœG’˜VJšœB˜Bšžœž˜˜AJšœQ˜Qšžœž˜Jšœ'˜'Jšœ)˜)Jšœ"˜"Jšœžœ ˜-Jšžœžœ ˜—J˜——Jšžœ˜J˜J˜—Jšœb™bJ˜Jšœžœ5˜IJ˜šŸœžœžœžœ ˜6Jšœ=˜=Jšœžœ˜Jšœžœ˜Jšœžœ ˜Jšžœžœ ˜Jšž˜Jšœžœ˜&Jšœžœ˜)Jšœ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ˜šœžœ ’!˜5Jšœ&™&—Jšœžœ˜J˜ J˜J˜J˜J˜6J˜Jšœ žœ˜Jšœ žœ˜J˜Jšžœ#˜)Jšžœ˜J˜—š‘ œžœ˜!Jšž˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜"Jšœžœ˜Jšœžœ˜Jšœžœ˜šžœžœžœžœ˜0Jšžœ\˜b—šž˜Jšžœ/žœ žœžœ+˜x—Jšžœ˜—J˜šŸ œžœ˜#Jšž˜Jšœžœ˜(Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜JšœF˜FJšžœ˜—J˜šŸœžœ ˜$Jšž˜Jšœžœ˜+J˜š Ÿœžœžœ žœ žœ˜0Jš’™JšœH˜HJšœ˜J˜—Jš’;™;Jš’@™@Jš’B™BJ˜Jšœžœ5˜:šžœ(žœ˜/Jšž˜Jšœžœ$˜+JšœžœI’ ˜_JšœžœN’ ˜bJšœžœ/’˜AJšœžœA’˜RJšœ žœG’˜YJšœ žœ žœ1žœ’˜gšžœžœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜J˜J˜šžœžœ˜˜>J˜7J˜—˜=J˜8J˜—Jšœ˜—Jšž˜—Jšžœ˜J˜J˜—JšœX™XJ˜Jšœ žœ0˜?J˜šŸ œžœžœžœ ˜,Jšœžœ˜Jšœžœ˜Jšžœžœ ˜Jšž˜Jšœžœ˜'Jšœžœ˜+Jšœžœ˜Jšœžœ˜Jšœžœ ˜Jšœžœ ˜J˜J˜J˜J˜Jšœ žœ˜J˜Jšœžœžœ˜LJ˜Jšžœ$˜*Jšžœ˜J˜—š‘œžœ’œ˜