<> <> <> <> <> <<>> DIRECTORY CD, CDAtomicObjects, CDBasics, CDCells, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, NMos, NMosContacts, NMosTransistors, Core, CoreClasses, CoreGeometry, PW, Sinix, SinixOps; SinixNMos: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, NMos, CoreClasses, CoreGeometry, PW, 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"], instanceEqualProc: Sinix.CompareProperties, objectEqualProc: Sinix.AlwaysTrue, nbOfLayers: NbOfInterestingLayers, instanceLayer: InstanceLayer, touchProc: CoreGeometry.Touch, nameProc: Sinix.DefaultName ]]; 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: CoreGeometry.Instance] RETURNS [Sinix.LayerRange] = { IF inst.obj.class=CDRects.bareRectClass THEN FOR i: NAT IN [0 .. NbOfInterestingLayers) DO IF InterestingLayers[i]=CDLayers.AbstractToPaint[inst.obj.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] = { instances: CoreGeometry.Instances = CoreGeometry.DrawListToInstances[list]; CoreGeometry.PutPins[mode.decoration, wire, instances]; CoreGeometry.PutGeometry[mode.decoration, wire, instances]; }; ExtractTransistor: Sinix.ExtractProc ~ { tp: NMosTransistors.TransistorPtr = NARROW [obj.specific]; 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.PutObject[mode.decoration, cellType, 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 = { size: CD.Position = CDBasics.SizeOfRect[obj.bbox]; class: NMosTransistors.TransistorPtr = NARROW [obj.specific]; 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: size.y], drain], dList]; gList _ CONS [[[x1: 0, x2: 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: size.x-class.wExt+depletionOverlap, y1: class.lExt-depletionOverlap, y2: 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 = { size: CD.Position = CDBasics.SizeOfRect[obj.bbox]; class: NMosTransistors.TransistorPtr = NARROW [obj.specific]; ele: CD.Number = 2*class.lExt+class.length; <<-- 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! >> hPoly: CD.Rect = [x1: 0, x2: size.x-class.lExt, y1: class.lExt, y2: class.length+class.lExt]; -- horizontal vPoly: CD.Rect = [x1: size.x-class.length-class.lExt, x2: hPoly.x2, y1: hPoly.y2, y2: size.y]; -- vertical nDrain: CD.Rect = [x1: class.wExt, x2: size.x, y1: 0, y2: hPoly.y1]; -- north eDrain: CD.Rect = [x1: vPoly.x2, x2: nDrain.x2, y1: nDrain.y2, y2: size.y-class.wExt]; -- east wSource: CD.Rect = [x1: 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 = { size: CD.Position = CDBasics.SizeOfRect[obj.bbox]; class: NMosTransistors.TransistorPtr = NARROW [obj.specific]; middleX: CD.Number = size.x/2; metal: CD.Rect = [x1: middleX-2*lambda, y1: middleX+2*lambda, x2: middleX+2*lambda, y2: 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: 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: 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.pCellClass, mode.extractProcProp, $ExtractCell]; <> CDProperties.PutProp[PW.abutXClass, mode.extractProcProp, $ExtractAbut]; CDProperties.PutProp[PW.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.rigidTextClass, mode.extractProcProp, $ExtractNull]; CDProperties.PutProp[CDTexts.flipTextClass, mode.extractProcProp, $ExtractNull]; <> SinixOps.RegisterDefaultLayoutMode[mode, NMos.nmos]; END.