CMosBObjectsImpl.mesa
Copyright © 1983, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, May 3, 1983 11:22 am
Last edited by: Christian Jacobi, March 30, 1987 3:44:35 pm PST
DIRECTORY
CMosB,
CMosBObjects,
CD,
CDAtomicObjects,
CDBasics,
CDLayers,
CDOps,
CDStretchyBackdoor,
Rope;
CMosBObjectsImpl: CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDBasics, CDLayers, CDOps, CDStretchyBackdoor, CMosB, Rope
EXPORTS CMosBObjects =
BEGIN
lambda: CD.Number = CMosB.lambda;
wellSurround: CD.Number = CMosB.wellSurround;
--Client stuff
SDiff: PROC [l: CD.Layer] RETURNS [CD.Layer] = {
SELECT l FROM
CMosB.wpdif, CMosB.wndif, CMosB.pdif, CMosB.ndif => RETURN [l];
ENDCASE => RETURN [CMosB.wpdif]
};
XDiff: PROC [l: CD.Layer] RETURNS [CD.Layer] = {
SELECT l FROM
CMosB.wpdif, CMosB.wndif, CMosB.pdif, CMosB.ndif, CMosB.nwellCont, CMosB.pwellCont => RETURN [l];
ENDCASE => RETURN [CMosB.wpdif]
};
CreateAtomic: PROC [classKey: ATOM, size: CD.Position, layer: CD.Layer ← CD.undefLayer] RETURNS [CD.Object] = {
RETURN [CDAtomicObjects.CreateAtomicOb[classKey, size, CMosB.cmosB, layer]];
};
CreatePolyCon: PUBLIC PROC [] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2SimpleCon, [0, 0], CMosB.pol]];
};
CreateDifCon: PUBLIC PROC [difLayer: CD.Layer] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2SimpleCon, [0, 0], XDiff[difLayer]]];
};
CreateDifShortCon: PUBLIC PROC [difLayer: CD.Layer] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2DifShortCon, [0, 0], SDiff[difLayer]]];
};
CreateVia: PUBLIC PROC [] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2Via, [0, 0]]];
};
CreateTransistor: PUBLIC PROC [size: CD.Position, difLayer: CD.Layer] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2Trans, size, XDiff[difLayer]]];
};
CreateAngleTransistor: PUBLIC PROC [size: CD.Position, difLayer: CD.Layer] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2LTrans, size, XDiff[difLayer]]];
};
CreateLargePolyCon: PUBLIC PROC [sz: CD.Position] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2LargeSimpleCon, sz, CMosB.pol]];
};
CreateLargeDifCon: PUBLIC PROC [sz: CD.Position, difLayer: CD.Layer] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2LargeSimpleCon, sz, XDiff[difLayer]]];
};
CreateLargeVia: PUBLIC PROC [sz: CD.Position] RETURNS [CD.Object] = {
RETURN [CreateAtomic[$C2LargeVia, sz]];
};
--Real implementations
-- straight transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MatchTrans: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = {
--poly, dif, welldif, via
-- Don't care about different diffusions and such
RETURN [layer=me.layer OR layer=CMosB.pol]
};
wellTransClass: CD.ObjectClass;
transClass: CD.ObjectClass;
FillTransistor: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
dExt: CD.Number = 3*lambda;
pExt: CD.Number = 2*lambda;
dif: CD.Layer;
inr: CD.Rect ← ob.bbox;
inr.x2 ← MAX[inr.x2, 2*lambda+2*pExt];
inr.y2 ← MAX[inr.y2, 2*lambda+2*dExt];
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif THEN {
ob.class ← wellTransClass;
IF ob.layer=CMosB.wpdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1-wellSurround+pExt,
x2: inr.x2+wellSurround-pExt,
y1: inr.y1-wellSurround,
y2: inr.y2+wellSurround],
layer: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
}
ELSE {
IF ob.layer=CMosB.pdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
};
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1+pExt,
x2: inr.x2-pExt,
y1: inr.y1,
y2: inr.y2],
layer: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1,
x2: inr.x2,
y1: inr.y1+dExt,
y2: inr.y2-dExt],
layer: CMosB.pol
];
};
DescribeT: CD.DescribeProc = {
dExt: CD.Number = 3*lambda;
pExt: CD.Number = 2*lambda;
sz: CD.Position = CD.InterestSize[ob];
RETURN [
Rope.Cat[
"transistor ",
CDOps.LayerRope[ob.layer],
Rope.Cat[" [",
CDOps.LambdaRope[sz.x-2*pExt, lambda],
CDOps.LambdaRope[sz.y-2*dExt, lambda],
"]"]
]
]
};
-- L transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
lTransClass: CD.ObjectClass;
wellLTransClass: CD.ObjectClass;
oldBadWellLTransClass: CD.ObjectClass;
OldBadFillLTransistor: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
ob.class ← lTransClass;
RETURN [FillLTransistor[ob]]
};
FillLTransistor: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
pExt: CD.Number = 2*lambda; --poly extends gate
dExt: CD.Number = 3*lambda; --diffusion extends gate
dW: CD.Number = 2*lambda; --witdth of diffusion in gate (not width of gate)
pW: CD.Number = 2*lambda; --witdth of poly in gate (not width of gate)
minSz: CD.Number = pExt+2*dExt+dW;
dif: CD.Layer;
inr: CD.Rect ← ob.bbox;
inr.x2 ← MAX[inr.x2, minSz];
inr.y2 ← MAX[inr.y2, minSz];
ob.bbox ← inr;
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif THEN {
wR: CD.Rect;
ob.class ← wellLTransClass;
IF ob.layer=CMosB.wpdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
--horizontal piece of nwell
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1-wellSurround+pExt,
x2: inr.x2+wellSurround,
y1: inr.y1-wellSurround ,
y2: inr.y1+wellSurround+dW+2*dExt],
layer: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
--vertical piece of nwell if ~empty
wR ← [x1: inr.x2-(dW+2*dExt)-wellSurround,
x2: inr.x2+wellSurround,
y1: inr.y1+wellSurround+dW+2*dExt,
y2: inr.y2+wellSurround-pExt];
IF CDBasics.NonEmpty[wR] THEN
CDAtomicObjects.Incorporate[ob: ob,
r: wR,
layer: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
}
ELSE {
IF ob.layer=CMosB.pdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
};
--horizontal piece of diff
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1+pExt,
x2: inr.x2,
y1: inr.y1,
y2: 2*dExt+dW],
layer: dif
];
--vertical piece of diff
IF 2*dExt+dW < inr.y2-pExt THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x2-2*dExt-dW,
x2: inr.x2,
y1: 2*dExt+dW,
y2: inr.y2-pExt ],
layer: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1,
x2: inr.x2-dExt,
y1: dExt,
y2: dExt+pW],
layer: CMosB.pol
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x2-pW-dExt,
x2: inr.x2-dExt,
y1: inr.y1+pW+dExt,
y2: inr.y2],
layer: CMosB.pol
];
};
-- simple contacts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
simpleContactClass: CD.ObjectClass;
wellSimpleContactClass: CD.ObjectClass;
largeContactClass: CD.ObjectClass;
wellLargeContactClass: CD.ObjectClass;
FillSimpleCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
rimW: CD.Number ~ lambda; -- therefore NOT large
inr: CD.Rect ← [0, 0, 2*lambda+2*rimW, 2*lambda+2*rimW];
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif OR ob.layer=CMosB.wpwellCont OR ob.layer=CMosB.wnwellCont THEN {
ob.class ← wellSimpleContactClass;
CDAtomicObjects.Incorporate[ob: ob,
r: CDBasics.Extend[inr, CDLayers.layerData[ob.layer].wSurr],
layer: CDLayers.layerData[ob.layer].well,
inside: FALSE
];
};
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CDLayers.layerData[ob.layer].paint];
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -rimW], layer: CMosB.cut];
};
FillLargeSimpleCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
rimW: CD.Number = 2*lambda; -- therefore large
inr: CD.Rect ← ob.bbox;
inr.x2 ← MAX[inr.x2, 2*lambda+2*rimW];
inr.y2 ← MAX[inr.y2, 2*lambda+2*rimW];
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif OR ob.layer=CMosB.wpwellCont OR ob.layer=CMosB.wnwellCont THEN {
ob.class ← wellLargeContactClass;
CDAtomicObjects.Incorporate[ob: ob,
r: CDBasics.Extend[inr, CDLayers.layerData[ob.layer].wSurr],
layer: CDLayers.layerData[ob.layer].well,
inside: FALSE
];
};
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CDLayers.layerData[ob.layer].paint];
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -rimW], layer: CMosB.cut];
};
DescribeC: CD.DescribeProc = {
RETURN [Rope.Cat["contact ", CDOps.LayerRope[ob.layer]]]
};
DescribeLargeC: CD.DescribeProc = {
RETURN [Rope.Cat["large contact ", CDOps.LayerRope[ob.layer]]]
};
-- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
wellDiffShortConClass: CD.ObjectClass;
FillDiffShortCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
dif, ctDif: CD.Layer;
inr: CD.Rect ~ [x1: 0, y1: 0, x2: 4*lambda, y2: 8*lambda];
difR: CD.Rect ~ [x1: 0, y1: 0, x2: 4*lambda, y2: 4*lambda];
ctR: CD.Rect ~ [x1: 0, y1: 4*lambda, x2: 4*lambda, y2: 8*lambda];
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif THEN {
wrd: CD.Rect ← CDBasics.Extend[difR, CMosB.wellSurround];
wrc: CD.Rect ← CDBasics.Extend[ctR, CMosB.wellCntSurround];
IF ob.layer=CMosB.wpdif THEN {
dif ← CMosB.pdif; ctDif ← CMosB.nwellCont
}
ELSE IF ob.layer=CMosB.wndif THEN {
dif ← CMosB.ndif; ctDif ← CMosB.pwellCont
};
wrc.y1 ← wrd.y2;
CDAtomicObjects.Incorporate[ob: ob, r: wrd, layer: CDLayers.layerData[ob.layer].well, inside: FALSE];
CDAtomicObjects.Incorporate[ob: ob, r: wrc, layer: CDLayers.layerData[ob.layer].well, inside: FALSE];
}
ELSE IF ob.layer=CMosB.ndif THEN {
dif ← CMosB.ndif; ctDif ← CMosB.pwellCont
}
ELSE {
dif ← CMosB.pdif; ctDif ← CMosB.nwellCont;
ob.layer ← CMosB.pdif; --reduce junk
};
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob, r: difR, layer: dif];
CDAtomicObjects.Incorporate[ob: ob, r: ctR, layer: ctDif];
CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -lambda], layer: CMosB.cut];
};
OldFillDiffShortCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
dif, ctDif: CD.Layer;
inr: CD.Rect ~ [x1: 0, y1: 0, x2: 4*lambda, y2: 8*lambda];
difR: CD.Rect ~ [x1: 0, y1: 0, x2: 4*lambda, y2: 4*lambda];
ctR: CD.Rect ~ [x1: 0, y1: 4*lambda, x2: 4*lambda, y2: 8*lambda];
IF ob.layer=CMosB.wpdif OR ob.layer=CMosB.wndif THEN {
ob.class ← wellDiffShortConClass;
IF ob.layer=CMosB.wpdif THEN {
dif ← CMosB.pdif; ctDif ← CMosB.nwellCont
}
ELSE IF ob.layer=CMosB.wndif THEN {
dif ← CMosB.ndif; ctDif ← CMosB.pwellCont
};
CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[difR, CMosB.wellSurround], layer: CDLayers.layerData[ob.layer].well, inside: FALSE];
}
ELSE IF ob.layer=CMosB.ndif THEN {
dif ← CMosB.ndif; ctDif ← CMosB.pwellCont
}
ELSE {
dif ← CMosB.pdif; ctDif ← CMosB.nwellCont;
ob.layer ← CMosB.pdif; --reduce junk
};
CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob, r: difR, layer: dif];
CDAtomicObjects.Incorporate[ob: ob, r: ctR, layer: ctDif];
CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -lambda], layer: CMosB.cut];
};
--via -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FillVia: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
viaRimWidth: CD.Number = lambda;
cut2min: CD.Number = 2*lambda;
ob.bbox ← [0, 0, cut2min+2*viaRimWidth, cut2min+2*viaRimWidth];
ob.layer ← CMosB.met2;
CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMosB.met2];
CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: viaRimWidth,
x2: cut2min+viaRimWidth,
y1: viaRimWidth,
y2: cut2min+viaRimWidth],
layer: CMosB.cut2
];
};
FillLargeVia: PROC [ob: CD.Object] RETURNS [mustFail: BOOLFALSE] = {
viaRimWidth: CD.Number = 2*lambda;
cut2min: CD.Number = 2*lambda;
ob.bbox.x2 ← MAX[ob.bbox.x2, cut2min+2*viaRimWidth];
ob.bbox.y2 ← MAX[ob.bbox.y2, cut2min+2*viaRimWidth];
ob.layer ← CMosB.met2;
CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMosB.met2];
CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: viaRimWidth,
x2: ob.bbox.x2-viaRimWidth,
y1: viaRimWidth,
y2: ob.bbox.y2-viaRimWidth],
layer: CMosB.cut2
];
};
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MatchSimpleCon: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = {
--poly, dif, welldif, via
-- Don't care about different diffusions and such
RETURN [layer=me.layer OR layer=CMosB.met]
};
Init: PROC [] = {
Register: PROC [key: ATOM, creator: CDAtomicObjects.FillObjectProc, desc: Rope.ROPE, match: CDStretchyBackdoor.MatchProc←NIL, describe: CD.DescribeProc←NIL] RETURNS [p: CD.ObjectClass] = {
p ← CDAtomicObjects.RegisterAtomicObClass[key, creator, desc, CMosB.cmosB];
IF p=NIL THEN ERROR;
IF describe#NIL THEN p.describe ← describe;
IF match=NIL THEN match ← MatchSimpleCon;
CDStretchyBackdoor.InstallMatchProc[p, match];
};
--transistors
transClass ← Register[$C2Trans, FillTransistor, "transistor", MatchTrans, DescribeT];
wellTransClass ← Register[$C2WellTrans, FillTransistor, "transistor", MatchTrans, DescribeT];
lTransClass ← Register[$C2LTrans, FillLTransistor, "L-transistor", MatchTrans];
oldBadWellLTransClass ← Register[$CLWellTrans, OldBadFillLTransistor, "L-transistor", MatchTrans];
wellLTransClass ← Register[$C2LWellTrans, FillLTransistor, "L-transistor", MatchTrans];
--contacts
simpleContactClass ← Register[$C2SimpleCon, FillSimpleCon, "contact", NIL, DescribeC];
wellSimpleContactClass ← Register[$C2WellSimpleCon, FillSimpleCon, "contact", NIL, DescribeC];
largeContactClass ← Register[$C2LargeSimpleCon, FillLargeSimpleCon, "large contact", NIL, DescribeLargeC];
wellLargeContactClass ← Register[$C2LargeWellSimpleCon, FillLargeSimpleCon, "large contact", NIL, DescribeLargeC];
[] ← Register[$C2DiffShortCon, FillDiffShortCon, "diff short contact"];
[] ← Register[$C2DifShortCon, OldFillDiffShortCon, "diff short contact"];--old
wellDiffShortConClass ← Register[$C2WellDifShortCon, OldFillDiffShortCon, "fdif short contact"];
[] ← Register[$C2Via, FillVia, "via"];
[] ← Register[$C2LargeVia, FillLargeVia, "large via"];
};
Init[];
END.