$C2Trans, $C2WellTrans, $CTrans, $CWellTrans =>
BEGIN
-- straight transistors
difRect, polRect, chRect: CD.Rect;
difExtRectNorth, difExtRectSouth, polExtEast, polExtWest: CD.Rect;
IF (difList.rest #
NIL)
OR (polList.rest #
NIL)
THEN
SIGNAL invalidTransistor ["Version mismatch"];
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];
extL ← polRect.y1 - difRect.y1; extW ← difRect.x1 - polRect.x1;
et.length ← chRect.y2 - chRect.y1; et.width ← chRect.x2 - chRect.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;
et.gate.layout ← LIST [[polExtEast, poly], [polExtWest, poly], [chRect, gate]];
et.ch1.layout ← LIST [[difExtRectNorth, diff]];
et.ch2.layout ← LIST [[difExtRectSouth, diff]];
IF (((class = $C2WellTrans) OR (class = $CWellTrans)) AND (wellList = NIL)) THEN SIGNAL invalidTransistor ["Well transistor must have a well"]
END; -- case $CTrans
$C2LTrans, $C2LWellTrans, $CLTrans, $CLWellTrans =>
BEGIN
-- angle transistors
diffNE: CD.Position ← [FIRST[CD.Number], FIRST[CD.Number]];
diffSW, polSW, polSE: CD.Position ← [LAST[CD.Number], LAST[CD.Number]];
polHor, polVert, polExtWest, polExtNorth, chRectH, chRectV, rect: CD.Rect;
d: CD.Number;
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 dl:
LIST
OF
CD.Rect ← difList, dl.rest
WHILE dl #
NIL
DO
IF (dl.first.x1 <= diffSW.x)
AND (dl.first.y1 <= diffSW.y)
THEN
diffSW ← [dl.first.x1, dl.first.y1];
IF (dl.first.x2 >= diffNE.x)
AND (dl.first.y2 >= diffNE.y)
THEN
diffNE ← [dl.first.x2, dl.first.y2];
ENDLOOP;
polSW ← [polHor.x1, polHor.y1]; polSE ← [polVert.x2, polHor.y1];
extW ← diffSW.x - polSW.x; extL ← polSW.y - diffSW.y;
et.length ← polHor.y2 - polHor.y1;
et.width ← ((polSE.x - polHor.x1) - extW) + ((polVert.y2 - polSE.y) - extW) - InlineRound [0.45 * Float [et.length*et.length]];
et.gate.area ← ((et.width+et.length/2) + 2*extW) * et.length;
et.gate.perimeter ← ((polHor.x2 - polHor.x1) + (polVert.y2 - polVert.y1)) * 2; -- ok!
et.ch2.area ← ((diffNE.x - diffSW.x) + (diffNE.y - diffSW.y - extL)) * extL;
et.ch2.perimeter ← 2 * extL + (diffNE.x - diffSW.x) + (diffNE.y - diffSW.y);
et.ch1.perimeter ← diffNE.x + diffNE.y - diffSW.x - diffSW.y - 2 * (extL + et.length);
et.ch1.area ← et.ch2.perimeter * extL;
polExtWest ← [polSW.x, polSW.y, diffSW.x, polHor.y2];
polExtNorth ← [diffNE.x-extL-et.length, diffNE.y, diffNE.x-extL, polVert.y2];
chRectH ← polHor; chRectH.x1 ← chRectH.x1 + extW;
chRectV ← polVert;
chRectV.y1 ← polHor.y2; chRectV.y2 ← chRectV.y2 - extW;
et.gate.layout ← LIST [[polExtWest, poly], [polExtNorth, poly], [chRectH, gate], [chRectV, gate]];
d ← extL + et.length;
rect ← [x1: diffSW.x, y1: diffSW.y+d, x2: diffNE.x-d, y2: polSW.y+d];
IF (rect.x1 = diffNE.x-d-extL)
THEN
BEGIN
rect.y2 ← diffNE.y; et.ch1.layout ← LIST [[rect, diff]] -- Nord
END
ELSE
BEGIN
et.ch1.layout ← LIST [[rect, diff]]; -- Nord
IF (rect.y2 < diffNE.y)
THEN
BEGIN
rect ← [x1: diffNE.x-d-extL, y1: polSW.y+d, x2: diffNE.x-d, y2: diffNE.y];
et.ch1.layout ← CONS [[rect, diff], et.ch1.layout] -- West
END
END;
rect ← [x1: diffSW.x, y1: diffSW.y, x2: diffNE.x, y2: polSW.y];
et.ch2.layout ← LIST [[rect, diff]]; -- South
rect ← [x1: diffNE.x-extL, y1: polSW.y, x2: diffNE.x, y2: diffNE.y];
et.ch2.layout ← CONS [[rect, diff], et.ch2.layout]; -- East
Process well.
IF (((class = $C2LWellTrans) OR (class = $CLWellTrans)) AND (wellList = NIL)) THEN SIGNAL invalidTransistor ["Well transistor must have a well"]
END; -- case $C2LTrans, $C2LWellTrans