SinixNMos.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Jean-Marc Frailong July 1, 1986 1:13:15 pm PDT
Bertrand Serlet December 16, 1986 6:01:57 am PST
DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts,
NMos, NMosContacts, NMosTransistors,
Core, CoreClasses,
CoreGeometry,
PWObjects,
Sinix, SinixOps;
SinixNMos: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDCells, CDLayers, CDProperties, CDRects, CDSymbolicObjects, CDTexts, NMos, CoreClasses, CoreGeometry, PWObjects, Sinix, SinixOps
SHARES CDCells, CDLayers, CDRects, CDSymbolicObjects, CDTexts =
BEGIN
As ever
CellType: TYPE = Core.CellType;
Wire: TYPE = Core.Wire;
Object: TYPE = CD.Object;
Properties: TYPE = Core.Properties;
ROPE: TYPE = Core.ROPE;
Properties and extraction of common objects
mode: Sinix.Mode ← NEW [Sinix.ModeRec ← [
extractProcProp: PWObjects.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;
Utilities
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];
};
Transistors
TransistorFlattenProc: TYPE = PROC [obj: CD.Object] RETURNS [sList: CDAtomicObjects.DrawList ← NIL, dList: CDAtomicObjects.DrawList ← NIL, gList: CDAtomicObjects.DrawList ← NIL, xList: CDAtomicObjects.DrawList ← NIL];
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.
AddRectList: PROC [mode: Sinix.Mode, wire: Wire, list: CDAtomicObjects.DrawList] = {
WHILE list#NIL DO
CoreGeometry.PutPins[mode.decoration, wire, CONS [[CDRects.CreateRect[CDBasics.SizeOfRect[list.first.r], list.first.layer], [CDBasics.BaseOfRect[list.first.r]]], CoreGeometry.GetPins[mode.decoration, wire]]];
list ← list.rest;
ENDLOOP;
};
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;
New layers for transistors
source: CD.Layer ← MakeAbstract[CD.NewLayer[NMos.nmos, $NSource], NMos.dif];
drain: CD.Layer ← MakeAbstract[CD.NewLayer[NMos.nmos, $NDrain], NMos.dif];
Flatten a regular transistor
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];
};
Flatten an angle transistor
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;
};
Flatten a pullup transistor
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];
};
Initialization
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]];
};
Registering extract procs
Sinix.RegisterExtractProc[$NMosExtractTransistor, ExtractTransistor];
Cells, Abuts
CDProperties.PutProp[CDCells.pCellClass, mode.extractProcProp, $ExtractCell];
We could do hand-crafted contacts by calling ExtractCell or ExtractAtomic depending on some property
CDProperties.PutProp[PWObjects.abutXClass, mode.extractProcProp, $ExtractAbut];
CDProperties.PutProp[PWObjects.abutYClass, mode.extractProcProp, $ExtractAbut];
Pins
CDProperties.PutProp[CDSymbolicObjects.pinClass, mode.extractProcProp, $ExtractPin];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, mode.extractProcProp, $ExtractPin];
CDProperties.PutProp[CDSymbolicObjects.markClass, mode.extractProcProp, $ExtractPin];
Rectangles
CDProperties.PutProp[CDRects.bareRectClass, mode.extractProcProp, $ExtractRect];
Contacts
InitContact[$NMosContactDifAndPol];
InitContact[$NMosContactBut];
InitContact[$NMosBurContact];
InitContact[$NMosMmContact];
Transistors
InitTransistor[$NMosTransistor, RegularTransistor];
InitTransistor[$NMosATransistor, AngleTransistor];
InitTransistor[$NMosPullUp, PullUp];
Texts
CDProperties.PutProp[CDTexts.rigidTextClass, mode.extractProcProp, $ExtractNull];
CDProperties.PutProp[CDTexts.flipTextClass, mode.extractProcProp, $ExtractNull];
Highlight for this technology
SinixOps.RegisterDefaultLayoutMode[mode, NMos.nmos];
END.