SaguaroImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Written by gbb, March 31, 1987 5:37:59 pm PST
gbb December 17, 1987 2:24:49 pm PST
Saguaro is an extractor just for transistors. The code is very similar to the one now in Spinifex and much simpler than the original approach based on corner stitching.
DIRECTORY
CD USING [Layer, LayerKey, LayerTechnology, NewLayer, Number, Object, Position, Rect, Technology],
CDAtomicObjects USING [AtomicObsSpecific, DrawList],
CDColors USING [Brick, DefineColor, DefineIColor],
CDProperties USING [RegisterProperty],
ImagerColor USING [ColorFromRGB],
Real USING [Float, InlineRound],
Rope USING [ROPE],
Saguaro;
SaguaroImpl: CEDAR PROGRAM
IMPORTS CD, CDColors, CDProperties, ImagerColor, Real
EXPORTS Saguaro ~ BEGIN OPEN Real, Saguaro;
Types
gate: PUBLIC CD.Layer ~ CD.NewLayer [NIL, $gate];
invalidTransistor: PUBLIC SIGNAL [msg: Rope.ROPE] ~ CODE;
ExtractedTransistor: TYPE ~ REF exXtr;
ExXtr: TYPE ~ RECORD [ch1, ch2, gate, bulk: Geom, type: Type, width, length: CD.Number];
Geom: TYPE ~ RECORD [layout: DrawList, area, perimeter: INT];
DrawList: TYPE ~ CDAtomicObjects.DrawList;
DrawList: TYPE ~ LIST OF DrawRec;
DrawRec: TYPE ~ RECORD [r: CD.Rect, layer: CD.Layer ← CD.errorLayer];
Type: TYPE ~ {nE, pE};
Operation
ExtractTransistor: PUBLIC PROC [obj: CD.Object] RETURNS [et: ExtractedTransistor] ~ BEGIN
class: ATOM ~ obj.class.objectType;
poly, diff, well: CD.Layer;
polList, difList, chList, difListSouth, wellList: LIST OF CD.Rect ← NIL;
extL, extW: CD.Number; -- vert. diff, hor. poly
tech: CD.Technology;
IF (class = $Cell) THEN SIGNAL invalidTransistor ["Cannot extract hand-made transistors"];
IF (class = $NMosTransistor) OR (class = $NMosATransistor) OR (class = $NMosPullUp) THEN SIGNAL invalidTransistor ["N-Mos not supported"];
Get the geometry. Streching information has already been procesed by ChipNDale.
IF ISTYPE [obj.specific, CDAtomicObjects.AtomicObsSpecific] THEN
FOR geom: CDAtomicObjects.DrawList ← NARROW [obj.specific, CDAtomicObjects.AtomicObsSpecific].rList, geom.rest WHILE geom # NIL DO
SELECT CD.LayerKey [geom.first.layer] FROM
$pol => {poly ← geom.first.layer; polList ← CONS [geom.first.r, polList]};
$ndif, $ndiff, $pdif, $pdiff => {diff ← geom.first.layer; difList ← CONS [geom.first.r, difList]};
$nwel, $nwell, $pwel, $pwell => {well ← geom.first.layer; wellList ← CONS [geom.first.r, wellList]};
ENDCASE => SIGNAL invalidTransistor ["Unknown transistor geometry"]
ENDLOOP
ELSE SIGNAL invalidTransistor ["Replace this old Chipmonk transistor"];
Determine l. FetchTechnology returns nil if the layer is technology independent.
tech ← CD.LayerTechnology [obj.layer];
IF (tech = NIL) THEN tech ← CD.LayerTechnology [poly];
IF (tech = NIL) THEN tech ← CD.LayerTechnology [diff];
IF (tech = NIL) THEN ERROR;
Process the geometry according to the transistor class. The ChipNDale transistors are fully supported for p substrate.
et ← NEW [ExXtr];
SELECT CD.LayerKey [obj.layer] FROM
$ndif, $ndiff, $wndif => et.type ← nE;
$pdif, $pdiff, $wpdif => et.type ← pE;
ENDCASE => SIGNAL invalidTransistor ["Version mismatch"];
et.type ← IF (CD.LayerKey [obj.layer] = $ndif) THEN nE ELSE pE;
SELECT class FROM
$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
ENDCASE => SIGNAL invalidTransistor ["Unknown or antiquated transistor class"];
et.ch1.perimeter ← et.ch1.perimeter / tech.lambda;
et.ch1.area ← et.ch1.area / tech.lambda / tech.lambda;
et.ch2.perimeter ← et.ch2.perimeter / tech.lambda;
et.ch2.area ← et.ch2.area / tech.lambda / tech.lambda;
et.gate.perimeter ← et.gate.perimeter / tech.lambda;
et.gate.area ← et.gate.area / tech.lambda / tech.lambda;
et.length ← et.length / tech.lambda; et.width ← et.width / tech.lambda;
FOR w: LIST OF CD.Rect ← wellList, w.rest WHILE w # NIL DO
et.bulk.layout ← CONS [[w.first, well], et.bulk.layout]
ENDLOOP;
END; -- ExtractTransistor
Initialisation
Set RGB value for gate layer
CDColors.DefineColor [layer: gate, brick: NEW [CDColors.Brick ← [4369, 4369, 4369, 4369]], display: bit8];
CDColors.DefineColor [layer: gate, brick: NEW [CDColors.Brick ← [4352, 17, 4352, 17]], display: bit8, mode: pushedOut];
CDColors.DefineIColor [layer: gate, col: ImagerColor.ColorFromRGB [[1.0, 1.0, 0.0]], display: bit8];
[] ← CDProperties.RegisterProperty [$gate, $gbb]
END.