$C2Trans, $C2WellTrans =>
BEGIN
-- straight transistors
difRect, polRect, chRect, difExtRectNorth, difExtRectSouth, polExtEast, polExtWest: CD.Rect;
difRect ← difList.first; polRect ← polList.first;
chRect ← [difRect.x1, polRect.y1, difRect.x2, polRect.y2];
difExtRectNorth ← difExtRectSouth ← difRect;
difExtRectNorth.y1 ← polRect.y2; difExtRectSouth. y2 ← polRect.y1;
polExtWest ← [polRect.x1, polRect.y1, difRect.x1, polRect.y2];
polExtEast ← [difRect.x2, polRect.y1, polRect.x2, polRect.y2];
et.length ← polRect.y2 - polRect.y1; et.width ← difRect.x2 - difRect.x1;
extL ← polRect.y1 - difRect.y1; extW ← difRect.x1 - polRect.x1;
et.gate.area ← (et.width + 2*extW) * et.length;
et.gate.perimeter ← (et.width + 2*extW + et.length) * 2;
et.ch1.area ← et.ch2.area ← extL * et.width;
et.ch1.perimeter ← et.ch2.perimeter ← 2 * extL + et.width;
IF (extL < extensionLength) THEN SIGNAL invalidTransistor ["Extension length too small"];
et.gate.layout ← LIST [[polExtEast, pol], [polExtWest, pol], [chRect, gate]];
et.ch1.layout ← LIST [[difExtRectNorth, obj.layer]];
et.ch2.layout ← LIST [[difExtRectSouth, obj.layer]];
et.length ← polRect.y2 - polRect.y1; et.width ← difRect.x2 - difRect.x1;
IF tClass = $C2WellTrans
THEN
BEGIN
l: CD.Layer ~ (IF isNWell THEN nwell ELSE pwell); -- fix
IF NOT CDBasics.NonEmpty[wellRect] THEN SIGNAL invalidTransistor ["Well transistor must have a well"];
et.bulk.layout ← LIST [[wellRect, l]]
END
END; -- case $CTrans
$C2LTrans, $C2LWellTrans =>
BEGIN
-- angle transistors
diffNE: CD.Position ← CDBasics.minposition;
diffSW, polSW: CD.Position ← CDBasics.highposition;
polHor, polVert, polExtWest, polExtNorth, chRectH, chRectV: CD.Rect;
IF ((polList.first.y2-polList.first.y1) < (polList.rest.first.y2-polList.rest.first.y1)) THEN
{polHor ← polList.first; polVert ← polList.rest.first}
ELSE {polHor ← polList.rest.first; polVert ← polList.first};
FOR diff:
LIST
OF
CD.Rect ← difList, diff.rest
WHILE diff #
NIL
DO
IF (diff.first.x1 <= diffSW.x)
AND (diff.first.y1 <= diffSW.y)
THEN
diffSW ← [diff.first.x1, diff.first.y1];
IF (diff.first.x2 >= diffNE.x)
AND (diff.first.y2 >= diffNE.y)
THEN
diffNE ← [diff.first.x2, diff.first.y2];
ENDLOOP;
polSW ← [polHor.x1, polHor.y1];
extW ← diffSW.x - polSW.x;
extL ← polSW.y - diffSW.y;
et.length ← polHor.y2 - polHor.y1;
et.width ← ((polHor.x2 - polHor.x1) - extW) + ((polVert.y2 - polVert.y1) - extW) - (et.length*3/2);
et.gate.area ← ((et.width+et.length/2) + 2*extW) * et.length;
et.gate.perimeter ← ((polHor.x2 - polHor.x1) + (polVert.y2 - polVert.y1)) * 2;
et.ch1.area ← ((diffNE.x - diffSW.x) + (diffNE.y - diffSW.y - extL)) * extL;
et.ch1.perimeter ← 2 * extL + (diffNE.x - diffSW.x) + (diffNE.y - diffSW.y);
et.ch2.perimeter ← diffNE.x + diffNE.y - diffSW.x - diffSW.y - 2 * (extL + et.length);
et.ch2.area ← et.ch2.perimeter * extL;
IF (extL < extensionLength) THEN SIGNAL invalidTransistor ["Extension length too small"];
polExtWest ← [polSW.x, polSW.y, diffSW.x, polHor.y2];
polExtNorth ← [diffNE.x-extL-et.length, diffNE.y, diffNE.x-extL, polHor.y2];
chRectH ← polHor; chRectH.x1 ← chRectH.x1 + extW;
chRectV ← polVert;
chRectV.y1 ← chRectV.y1 + et.length; chRectV.y2 ← chRectV.y2 - extW;
et.gate.layout ← LIST [[polExtWest, pol], [polExtNorth, pol], [chRectH, gate], [chRectV, gate]];
Process gate lead-in
BEGIN
-- Bogus but first approx. for a fast impl.
d: CD.Number ← extL + et.length + sep;
rect ← [x1: diffSW.x, y1: diffSW.y+extL+et.length, x2: diffNE.x-extL-et.length, y2: diffSW.y+d];
et.ch1.layout ← LIST [[rect, obj.layer]]; -- North
rect ← [x1: diffNE.x-d, y1: diffSW.y+extL+et.length, x2: diffNE.x-extL-et.length, y2: diffNE.y];
et.ch1.layout ← CONS [[rect, obj.layer], et.ch1.layout]; -- West
d ← extL - sep;
rect ← [x1: diffSW.x, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffSW.y+extL];
et.ch2.layout ← LIST [[rect, obj.layer]]; -- South
rect ← [x1: diffNE.x-extL, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffNE.y];
et.ch2.layout ← CONS [[rect, obj.layer], et.ch2.layout] -- East
END; -- gate lead-in
Process well.
IF tClass = $C2WellTrans
THEN
BEGIN
l: CD.Layer ~ (IF isNWell THEN nwell ELSE pwell); -- fix
IF NOT CDBasics.NonEmpty[wellRect] THEN SIGNAL invalidTransistor ["Well transistor must have a well"];
et.bulk.layout ← LIST [[wellRect, l]]
END
END; -- case $C2LTrans, $C2LWellTrans