CMosBObsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Christian Jacobi, March 22, 1985 11:09:09 am PST
last edited Christian Jacobi, January 28, 1986 10:42:40 am PST
DIRECTORY
CD,
CDAtomicObjects,
CDBasics,
CDExtras,
CDOps,
CDStretchyExtras,
CMosB,
Rope;
CMosBObsImpl:
CEDAR
PROGRAM
IMPORTS CD, CDAtomicObjects, CDBasics, CDExtras, CDOps, CDStretchyExtras, CMosB, Rope =
BEGIN
lambda: CD.Number = CMosB.lambda;
wellSurround: CD.Number = CMosB.wellSurround;
-- straight transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MatchTrans:
PROC [me:
CD.Object, r:
CD.Rect, layer:
CD.Layer, prim:
BOOL, horz:
BOOL]
RETURNS [
BOOL] =
--poly, dif, welldif, via
BEGIN
-- Don't care about different diffusions and such
RETURN [layer=me.layer OR layer=CMosB.pol]
END;
wellTransClass: REF CD.ObjectClass;
transClass: REF CD.ObjectClass;
FillTransistor:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
dExt: CD.Number = 3*lambda;
pExt: CD.Number = 2*lambda;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
dif: CD.Layer;
ob.size ← CDBasics.MaxPoint[ob.size, [2*lambda+2*pExt, 2*lambda+2*dExt]];
IF ob.layer=CMosB.wpdif
OR ob.layer=CMosB.wndif
THEN {
ob.class ← wellTransClass;
wellSurr ← wellSurround;
innerX ← wellSurround-pExt;
IF ob.layer=CMosB.wpdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
ob.size.x ← ob.size.x + 2*wellSurround-2*pExt;
ob.size.y ← ob.size.y + 2*wellSurround;
}
ELSE {
IF ob.layer=CMosB.pdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
};
IF wellSurr#0
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: innerX+pExt,
x2: ob.size.x-pExt-innerX,
y1: wellSurr,
y2: ob.size.y-wellSurr],
lev: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: innerX,
x2: ob.size.x-innerX,
y1: wellSurr+dExt,
y2: ob.size.y-wellSurr-dExt],
lev: CMosB.pol
];
END;
DescribeT:
PROC[me:
CD.Object]
RETURNS [Rope.
ROPE] =
BEGIN
dExt: CD.Number = 3*lambda;
pExt: CD.Number = 2*lambda;
sz: CD.Position = CD.InterestSize[me];
RETURN [
Rope.Cat[
"transistor ",
CDOps.LayerName[me.layer],
Rope.Cat[
" [",
CDExtras.ToLambda[sz.x-2*pExt],
CDExtras.ToLambda[sz.y-2*dExt],
"]"
]
]
]
END;
-- L transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
lTransClass: REF CD.ObjectClass;
wellLTransClass: REF CD.ObjectClass;
oldBadWellLTransClass: REF CD.ObjectClass;
OldBadFillLTransistor:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] = {
ob.class ← lTransClass;
RETURN [FillLTransistor[ob]]
};
FillLTransistor:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
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;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
dif: CD.Layer;
ob.size ← CDBasics.MaxPoint[ob.size, [minSz, minSz]];
IF ob.layer=CMosB.wpdif
OR ob.layer=CMosB.wndif
THEN {
ob.class ← wellLTransClass;
wellSurr ← wellSurround;
innerX ← wellSurround-pExt;
ob.size.x ← ob.size.x + 2*wellSurround-pExt;
ob.size.y ← ob.size.y + 2*wellSurround-pExt;
IF ob.layer=CMosB.wpdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
}
ELSE {
IF ob.layer=CMosB.pdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
};
IF wellSurr#0
THEN {
wR: CD.Rect;
--horizontal piece of nwell
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: 2*wellSurr+dW+2*dExt],
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
--vertical piece of nwell if ~empty
wR ← [x1: ob.size.x-(2*wellSurr+dW+2*dExt), x2: ob.size.x, y1: 2*wellSurr+dW+2*dExt, y2: ob.size.y];
IF CDBasics.NonEmpty[wR]
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: wR,
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
};
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: innerX+pExt,
x2: ob.size.x-wellSurr,
y1: wellSurr,
y2: wellSurr+2*dExt+dW],
lev: dif
];
IF wellSurr+2*dExt+dW < ob.size.y-innerX-pExt
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: ob.size.x-wellSurr-2*dExt-dW,
x2: ob.size.x-wellSurr,
y1: wellSurr+2*dExt+dW,
y2: ob.size.y-innerX-pExt ],
lev: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: innerX,
x2: ob.size.x-wellSurr-dExt,
y1: wellSurr+dExt,
y2: wellSurr+dExt+pW],
lev: CMosB.pol
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: ob.size.x-wellSurr-pW-dExt,
x2: ob.size.x-wellSurr-dExt,
y1: wellSurr+pW+dExt,
y2: ob.size.y-innerX],
lev: CMosB.pol
];
END;
-- simple contacts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
simpleContactClass: REF CD.ObjectClass;
wellSimpleContactClass: REF CD.ObjectClass;
largeContactClass: REF CD.ObjectClass;
wellLargeContactClass: REF CD.ObjectClass;
FillSimpleCon:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
rimW: CD.Number = lambda; -- therefore NOT large
wellSurr: CD.Number ← 0;
dif: CD.Layer;
IF ob.layer=CMosB.wpdif
OR ob.layer=CMosB.wndif
THEN {
ob.class ← wellSimpleContactClass;
wellSurr ← wellSurround;
dif ← (IF ob.layer=CMosB.wpdif THEN CMosB.pdif ELSE CMosB.ndif);
}
ob.size ← [2*lambda+2*rimW+2*wellSurr, 2*lambda+2*rimW+2*wellSurr];
IF wellSurr#0
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr,
x2: ob.size.x-wellSurr,
y1: wellSurr,
y2: ob.size.y-wellSurr],
lev: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr,
x2: ob.size.x-wellSurr,
y1: wellSurr,
y2: ob.size.y-wellSurr],
lev: CMosB.met
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr+rimW,
x2: ob.size.x-rimW-wellSurr,
y1: wellSurr+rimW,
y2: ob.size.y-rimW-wellSurr],
lev: CMosB.cut
];
END;
FillLargeSimpleCon:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
rimW: CD.Number = 2*lambda; -- therefore large
wellSurr: CD.Number ← 0;
dif: CD.Layer;
IF ob.layer=CMosB.wpdif
OR ob.layer=CMosB.wndif
THEN {
ob.class ← wellLargeContactClass;
wellSurr ← wellSurround;
dif ← (IF ob.layer=CMosB.wpdif THEN CMosB.pdif ELSE CMosB.ndif);
}
ob.size.x ← MAX[ob.size.x, 2*lambda+2*rimW+2*wellSurr];
ob.size.y ← MAX[ob.size.y, 2*lambda+2*rimW+2*wellSurr];
IF wellSurr#0
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr,
x2: ob.size.x-wellSurr,
y1: wellSurr,
y2: ob.size.y-wellSurr],
lev: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr,
x2: ob.size.x-wellSurr,
y1: wellSurr,
y2: ob.size.y-wellSurr],
lev: CMosB.met
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: wellSurr+rimW,
x2: ob.size.x-rimW-wellSurr,
y1: wellSurr+rimW,
y2: ob.size.y-rimW-wellSurr],
lev: CMosB.cut
];
END;
DescribeC:
PROC[me:
CD.Object]
RETURNS [Rope.
ROPE] =
BEGIN
RETURN [Rope.Cat["contact ", CDOps.LayerName[me.layer]]]
END;
DescribeLargeC:
PROC[me:
CD.Object]
RETURNS [Rope.
ROPE] =
BEGIN
RETURN [Rope.Cat["large contact ", CDOps.LayerName[me.layer]]]
END;
-- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
wellDifShortContactClass: REF CD.ObjectClass;
FillDifShortCon:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
dif: CD.Layer;
wellSurr: CD.Number ← 0;
inr: CD.Rect;
innerW: CD.Number = 4*lambda;
innerH: CD.Number = 8*lambda;
h: CD.Number = innerH/2;
IF ob.layer=CMosB.wpdif
OR ob.layer=CMosB.wndif
THEN {
ob.class ← wellDifShortContactClass;
wellSurr ← wellSurround;
IF ob.layer=CMosB.wpdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
inr ← [x1: wellSurr, y1: wellSurr, x2: wellSurr+innerW, y2: wellSurr+innerH];
ob.size ← [innerW+2*wellSurr, innerH+2*wellSurr-h];
}
ELSE {
IF ob.layer=CMosB.pdif THEN dif ← CMosB.pdif ELSE dif ← CMosB.ndif;
inr ← [x1: 0, y1: 0, x2: innerW, y2: innerH];
ob.size ← [innerW, innerH];
};
IF wellSurr#0
THEN
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: (IF dif=CMosB.pdif THEN CMosB.nwell ELSE CMosB.pwell),
inside: FALSE
];
CDAtomicObjects.Incorporate[ob: ob, r: inr, lev: CMosB.met];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1,
x2: inr.x2,
y1: inr.y1,
y2: inr.y1+h],
lev: dif
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1,
x2: inr.x2,
y1: inr.y1+h,
y2: inr.y2],
lev: (IF dif=CMosB.pdif THEN CMosB.nwellCont ELSE CMosB.pwellCont)
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: inr.x1+lambda,
x2: inr.x2-lambda,
y1: inr.y1+lambda,
y2: inr.y2-lambda],
lev: CMosB.cut
];
END;
--via -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FillVia:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
viaRimWidth: CD.Number = lambda;
cut2min: CD.Number = 2*lambda;
ob.size ← [cut2min+2*viaRimWidth, cut2min+2*viaRimWidth];
ob.layer ← CMosB.met2;
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: CMosB.met2
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: CMosB.met
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: viaRimWidth,
x2: ob.size.x-viaRimWidth,
y1: viaRimWidth,
y2: ob.size.y-viaRimWidth],
lev: CMosB.cut2
];
END;
FillLargeVia:
PROC [ob:
CD.Object]
RETURNS [mustFail:
BOOL←
FALSE] =
BEGIN
viaRimWidth: CD.Number = 2*lambda;
cut2min: CD.Number = 2*lambda;
ob.size.x ← MAX[ob.size.x, cut2min+2*viaRimWidth];
ob.size.y ← MAX[ob.size.y, cut2min+2*viaRimWidth];
ob.layer ← CMosB.met2;
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: CMosB.met2
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: 0, x2: ob.size.x, y1: 0, y2: ob.size.y],
lev: CMosB.met
];
CDAtomicObjects.Incorporate[ob: ob,
r: [x1: viaRimWidth,
x2: ob.size.x-viaRimWidth,
y1: viaRimWidth,
y2: ob.size.y-viaRimWidth],
lev: CMosB.cut2
];
END;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MatchSimpleCon:
PROC [me:
CD.Object, r:
CD.Rect, layer:
CD.Layer, prim:
BOOL, horz:
BOOL]
RETURNS [
BOOL] =
--poly, dif, welldif, via
BEGIN
-- Don't care about different diffusions and such
RETURN [layer=me.layer OR layer=CMosB.met]
END;
Init:
PROC [] =
BEGIN
Register:
PROC [key:
ATOM, creator: CDAtomicObjects.FillObjectProc, desc: Rope.
ROPE, match: CDStretchyExtras.MatchProc←
NIL]
RETURNS [p:
REF
CD.ObjectClass] =
BEGIN
p ← CDAtomicObjects.RegisterAtomicObClass[key, creator, desc, CMosB.cmosB];
IF p=NIL THEN ERROR;
IF match=NIL THEN match ← MatchSimpleCon;
CDStretchyExtras.InstallMatch[p, match];
END;
--transistors
transClass ← Register[$C2Trans, FillTransistor, "transistor", MatchTrans];
transClass.describe ← DescribeT;
wellTransClass ← Register[$C2WellTrans, FillTransistor, "transistor", MatchTrans];
wellTransClass.describe ← 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"];
simpleContactClass.describe ← DescribeC;
wellSimpleContactClass ← Register[$C2WellSimpleCon, FillSimpleCon, "contact"];
wellSimpleContactClass.describe ← DescribeC;
largeContactClass ← Register[$C2LargeSimpleCon, FillLargeSimpleCon, "large contact"];
largeContactClass.describe ← DescribeLargeC;
wellLargeContactClass ← Register[$C2LargeWellSimpleCon, FillLargeSimpleCon, "large contact"];
wellLargeContactClass.describe ← DescribeLargeC;
[] ← Register[$C2DifShortCon, FillDifShortCon, "dif short contact"];
wellDifShortContactClass ← Register[$C2WellDifShortCon, FillDifShortCon, "dif short contact"];
[] ← Register[$C2Via, FillVia, "via"];
[] ← Register[$C2LargeVia, FillLargeVia, "large via"];
END;
Init[];
END.