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], Rope USING [ROPE], Saguaro; SaguaroImpl: CEDAR PROGRAM IMPORTS CD, CDColors, CDProperties, ImagerColor EXPORTS Saguaro ~ BEGIN OPEN Saguaro; gate: PUBLIC CD.Layer ~ CD.NewLayer [NIL, $gate]; invalidTransistor: PUBLIC SIGNAL [msg: Rope.ROPE] ~ CODE; 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"]; 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"]; 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; 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) - 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 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 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. π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 Giordano Beretta December 18, 1987 12:17:41 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. Real USING [Float, InlineRound], Types 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 Get the geometry. Streching information has already been procesed by ChipNDale. Determine l. FetchTechnology returns nil if the layer is technology independent. Process the geometry according to the transistor class. The ChipNDale transistors are fully supported for p substrate. et.width _ ((polSE.x - polHor.x1) - extW) + ((polVert.y2 - polSE.y) - extW) - InlineRound [0.45 * Float [et.length*et.length]]; Process well. Initialisation Set RGB value for gate layer Κ˜codešœ™Kšœ<™˜>Kšœ>˜>Kšœ?˜?KšœD˜DIcode1šœ/˜/Ošœ8˜8Ošœ,˜,Ošœ:˜:Nšœœ:˜OKšœœ˜/Kšœœ˜/Kš œœœ œœœ7˜ŽKšœ ˜—šœ4œ ˜NKš œœ œœ œœ ˜;Kš œœ œœ œœ ˜GKšœBœ˜JKšœœ˜ KšœVœ7˜”Kšœ8˜<š œœœœœœ˜<šœœ˜?Kšœ$˜$—šœœ˜?Kšœ$˜$—Jšœ˜—Kšœ@˜@Kšœ5˜5Kšœ"˜"Kšœ™KšœX˜XKšœ=˜=OšœO ˜UOšœM˜MOšœM˜MOšœV˜VOšœ&˜&Nšœ5˜5KšœM˜MKšœ1˜1Kšœ˜Kšœ7˜7KšœœM˜bNšœ˜KšœE˜Ešœœ˜)Kšœ$œ ˜?Kš˜—šœ˜ Kšœœ ˜,šœœ˜"KšœJ˜JKšœœ ˜:Kš˜—Kšœ˜—Kšœ?˜?Kšœœ ˜-KšœD˜DKšœœ  ˜;N™ Kš œœœ œœœ7˜Kšœ  ˜%—Nšœœ>˜O—Nšœ2˜2Jšœ6˜6Jšœ2˜2Jšœ6˜6Jšœ4˜4Jšœ8˜8JšœG˜Gš œœœœœœ˜:Jšœœ"˜7Jšœ˜—Kšœ ˜——šœ™N™Kšœ*œ<˜jKšœ*œI˜wKšœd˜dKšœ0˜0—Lšœ˜—…—φ'φ