DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, NMos, NMosContacts, NMosTransistors, Core, CoreClasses, CoreGeometry, PW, PWObjects, Sinix, SinixOps; SinixNMos: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, NMos, CoreClasses, CoreGeometry, PW, PWObjects, Sinix, SinixOps SHARES CDCells, CDLayers, CDRects, CDSymbolicObjects, CDTexts = BEGIN CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; Object: TYPE = CD.Object; Properties: TYPE = Core.Properties; ROPE: TYPE = Core.ROPE; mode: Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PW.RegisterProp[$NMosExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["NMos"], nbOfLayers: NbOfInterestingLayers, instanceLayer: InstanceLayer, touchProc: CoreGeometry.Touch, equalProc: Sinix.CompareProps ]]; InterestingLayers: ARRAY [0 .. NbOfInterestingLayers) OF CD.Layer _ [NMos.dif, NMos.pol, NMos.met, NMos.met2, NMos.cut, NMos.cut2, NMos.imp, NMos.imp0, NMos.impWeak, NMos.ovg, NMos.bur]; NbOfInterestingLayers: NAT = 11; lambda: CD.Number = NMos.nmos.lambda; InstanceLayer: PROC [inst: CD.Instance] RETURNS [Sinix.LayerRange] = { IF inst.ob.class=CDRects.bareRectClass THEN FOR i: NAT IN [0 .. NbOfInterestingLayers) DO IF InterestingLayers[i]=CDLayers.AbstractToPaint[inst.ob.layer] THEN RETURN [[i, i]]; ENDLOOP; RETURN [[0, NbOfInterestingLayers-1]]; }; MakeAbstract: PROC [abstract, represents: CD.Layer] RETURNS [sameAbstract: CD.Layer] = { CDLayers.MakeAbstract[abstract, represents]; RETURN [abstract]; }; TransistorFlattenProc: TYPE = PROC [obj: CD.Object] RETURNS [sList: CDAtomicObjects.DrawList _ NIL, dList: CDAtomicObjects.DrawList _ NIL, gList: CDAtomicObjects.DrawList _ NIL, xList: CDAtomicObjects.DrawList _ NIL]; AddRectList: PROC [mode: Sinix.Mode, wire: Wire, list: CDAtomicObjects.DrawList] = { WHILE list#NIL DO instance: CD.Instance _ CDInstances.NewInst[ ob: CDRects.CreateRect[CDBasics.SizeOfRect[list.first.r], list.first.lev], location: CDBasics.BaseOfRect[list.first.r] ]; CoreGeometry.PutPins[mode.decoration, wire, CONS [instance, CoreGeometry.GetPins[mode.decoration, wire]]]; list _ list.rest; ENDLOOP; }; ExtractTransistor: Sinix.ExtractProc ~ { tp: NMosTransistors.TransistorPtr = NARROW[obj.specificRef]; cellType: CellType; gateWire, sourceWire, drainWire: Wire; sList, dList, gList, xList: CDAtomicObjects.DrawList; flatten: REF TransistorFlattenProc = NARROW [CDProperties.GetProp[from: obj.class, prop: $TransistorFlatten]]; cellType _ CoreClasses.CreateTransistor[[nE, tp.length, tp.width]]; gateWire _ cellType.public[0]; sourceWire _ cellType.public[1]; drainWire _ cellType.public[2]; [sList, dList, gList, xList] _ flatten[obj]; AddRectList[mode, sourceWire, sList]; AddRectList[mode, drainWire, dList]; AddRectList[mode, gateWire, gList]; CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]]; result _ cellType; }; depletionOverlap: CD.Number = (3*lambda)/2; source: CD.Layer _ MakeAbstract[CD.NewLayer[NMos.nmos, $NSource], NMos.dif]; drain: CD.Layer _ MakeAbstract[CD.NewLayer[NMos.nmos, $NDrain], NMos.dif]; RegularTransistor: TransistorFlattenProc = { class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef]; sList _ CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: 0, y2: class.lExt], source], sList]; dList _ CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: class.lExt+class.length, y2: obj.size.y], drain], dList]; gList _ CONS [[[x1: 0, x2: obj.size.x, y1: class.lExt, y2: class.lExt+class.length], NMos.pol], gList]; IF class.implant>0 THEN xList _ CONS [[ [x1: class.wExt-depletionOverlap, x2: obj.size.x-class.wExt+depletionOverlap, y1: class.lExt-depletionOverlap, y2: obj.size.y-class.lExt+depletionOverlap], SELECT class.implant FROM NMosTransistors.strongDepletion => NMos.imp, NMosTransistors.weakDepletion => NMos.impWeak, NMosTransistors.zeroTresh => NMos.imp0, NMosTransistors.enhancement => CD.errorLayer, ENDCASE => CD.errorLayer ], xList]; }; AngleTransistor: TransistorFlattenProc = { class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef]; ele: CD.Number = 2*class.lExt+class.length; hPoly: CD.Rect = [x1: 0, x2: obj.size.x-class.lExt, y1: class.lExt, y2: class.length+class.lExt]; -- horizontal vPoly: CD.Rect = [x1: obj.size.x-class.length-class.lExt, x2: hPoly.x2, y1: hPoly.y2, y2: obj.size.y]; -- vertical nDrain: CD.Rect = [x1: class.wExt, x2: obj.size.x, y1: 0, y2: hPoly.y1]; -- north eDrain: CD.Rect = [x1: vPoly.x2, x2: nDrain.x2, y1: nDrain.y2, y2: obj.size.y-class.wExt]; -- east wSource: CD.Rect = [x1: obj.size.x-ele, x2: vPoly.x1, y1: vPoly.y1, y2: eDrain.y2]; -- west sSource: CD.Rect = [x1: MIN[nDrain.x1, wSource.x1], x2: wSource.x1, y1: wSource.y1, y2: MIN[ele, wSource.y2]]; -- south gList _ CONS [[hPoly, NMos.pol], gList]; gList _ CONS [[vPoly, NMos.pol], gList]; IF class.lExt>0 THEN BEGIN dList _ CONS [[nDrain, drain], dList]; dList _ CONS [[eDrain, drain], dList]; END; sList _ CONS [[wSource, source], sList]; IF sSource.x1 < sSource.x2 THEN sList _ CONS [[sSource, source], sList]; IF class.implant>0 THEN BEGIN xList _ CONS [ [[x1: nDrain.x1-depletionOverlap, x2: hPoly.x2+depletionOverlap, y1: hPoly.y1-depletionOverlap, y2: hPoly.y2+depletionOverlap], NMos.imp], xList]; xList _ CONS [ [[x1: vPoly.x1-depletionOverlap, x2: vPoly.x2+depletionOverlap, y1: vPoly.y1-depletionOverlap, y2: eDrain.y2+depletionOverlap], NMos.imp], xList]; END; }; PullUp: TransistorFlattenProc = { class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef]; middleX: CD.Number = obj.size.x/2; metal: CD.Rect = [x1: middleX-2*lambda, y1: middleX+2*lambda, x2: middleX+2*lambda, y2: obj.size.y]; contact: CD.Rect = [x1: metal.x1+lambda, x2: metal.x2-lambda, y1: metal.y1+lambda, y2: metal.y2-lambda]; hPoly: CD.Rect = [x1: 0, x2: obj.size.x, y1: class.lExt, y2: class.lExt+class.length]; gList _ CONS [[hPoly, NMos.pol], gList]; gList _ CONS [[contact, NMos.cut], gList]; dList _ CONS [[metal, NMos.met], dList]; dList _ CONS [[contact, NMos.cut], dList]; dList _ CONS [[[x1: metal.x1, x2: metal.x2, y1: hPoly.y2, y2: metal.y2], obj.layer], dList]; sList _ CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: 0, y2: hPoly.y1], obj.layer], sList]; xList _ CONS [[[x1: 0, x2: hPoly.x2, y1: 0, y2: obj.size.y-lambda], NMos.imp], xList]; }; InitContact: PROC [className: ATOM] = { class: CD.ObjectClass = CD.FetchObjectClass[className, NMos.nmos]; CDProperties.PutProp[class, mode.extractProcProp, $ExtractAtomic]; }; InitTransistor: PROC [className: ATOM, flattenProc: TransistorFlattenProc] = { class: CD.ObjectClass = CD.FetchObjectClass[className, NMos.nmos]; CDProperties.PutProp[class, mode.extractProcProp, $NMosExtractTransistor]; CDProperties.PutProp[class, $TransistorFlatten, NEW [TransistorFlattenProc _ flattenProc]]; }; Sinix.RegisterExtractProc[$NMosExtractTransistor, ExtractTransistor]; CDProperties.PutProp[CDCells.cellClass, mode.extractProcProp, $ExtractCell]; CDProperties.PutProp[PWObjects.abutXClass, mode.extractProcProp, $ExtractAbut]; CDProperties.PutProp[PWObjects.abutYClass, mode.extractProcProp, $ExtractAbut]; CDProperties.PutProp[CDSymbolicObjects.pinClass, mode.extractProcProp, $ExtractPin]; CDProperties.PutProp[CDSymbolicObjects.segmentClass, mode.extractProcProp, $ExtractPin]; CDProperties.PutProp[CDSymbolicObjects.markClass, mode.extractProcProp, $ExtractPin]; CDProperties.PutProp[CDRects.bareRectClass, mode.extractProcProp, $ExtractRect]; InitContact[$NMosContactDifAndPol]; InitContact[$NMosContactBut]; InitContact[$NMosBurContact]; InitContact[$NMosMmContact]; InitTransistor[$NMosTransistor, RegularTransistor]; InitTransistor[$NMosATransistor, AngleTransistor]; InitTransistor[$NMosPullUp, PullUp]; CDProperties.PutProp[CDTexts.textClass, mode.extractProcProp, $ExtractNull]; SinixOps.RegisterDefaultLayoutMode[NMos.nmos, mode]; END. ®SinixNMos.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Jean-Marc Frailong July 1, 1986 1:13:15 pm PDT Bertrand Serlet October 6, 1986 12:21:32 pm PDT As ever Properties and extraction of common objects Utilities Transistors This is necessary because CD does not keep the list of rectangles anywhere but generates them inline at drawing time. Return geometry for source, drain, gate and special unconnected layers. New layers for transistors Flatten a regular transistor Flatten an angle transistor -- Warning: This code is absurd, but so is NMosTransistorsImpl.DrawMeForATransistors in CDNMos23. It is incorrect if ele+wExt > size (which may make sense). -- The right code should compute the lowx/highy values for dif and go from there, not assuming the structure of the overlap. The CD graphics are wrong, and anyway it is impossible to stretch angle NMos transistors, so only one size is really available! Flatten a pullup transistor Initialization Registering extract procs Cells, Abuts We could do hand-crafted contacts by calling ExtractCell or ExtractAtomic depending on some property Pins Rectangles Contacts Transistors Texts Highlight for this technology Êt˜codešœ™Kšœ Ïmœ1™žœžœ ˜UKšžœ˜ ——Jšžœ ˜&J˜J˜—š Ÿ œžœžœžœžœ ˜XKšœ-žœ ˜?K˜——™ šœžœžœžœ žœ$žœ$žœ$žœ$žœ˜ÙK™½K™—šŸ œžœC˜Tšžœžœž˜šœ žœ ˜,JšœK˜KJšœ+˜+Jšœ˜—Jšœ,žœ:˜jK˜Kšžœ˜—J˜J˜—šŸœ˜(Jšœ$žœ˜