DIRECTORY CD USING [Layer, NewLayer, Number, Object, Position, Rect], CDAtomicObjects USING [AtomicObsSpecific, DrawList], CDBasics USING [highposition, minposition, NonEmpty], CMosB USING [lambda, ndif, nwell, pdif, pol, pwell], Rope USING [ROPE], Saguaro; SaguaroImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CMosB EXPORTS Saguaro ~ BEGIN OPEN Saguaro; gate: PUBLIC CD.Layer ~ CD.NewLayer [NIL, $gate]; pol: CD.Layer ~ CMosB.pol; ndif: CD.Layer ~ CMosB.ndif; pdif: CD.Layer ~ CMosB.pdif; nwell: CD.Layer ~ CMosB.nwell; pwell: CD.Layer ~ CMosB.pwell; lambda: CD.Number ~ CMosB.lambda; invalidTransistor: PUBLIC SIGNAL [msg: Rope.ROPE] ~ CODE; ExtractTransistor: PUBLIC PROC [obj: CD.Object] RETURNS [et: ExtractedTransistor] ~ BEGIN tClass: ATOM ~ obj.class.objectType; isNType: BOOL ~ (obj.layer = ndif); -- fix isNWell: BOOL; sep: CD.Number ~ lambda; extensionLength: CD.Number ~ 3 * lambda; -- ch1/ch2 extension [rule 6.3.18] rect, wellRect: CD.Rect; polList, difList, chList, difListSouth: LIST OF CD.Rect _ NIL; extL, extW: CD.Number; IF ISTYPE [obj.specific, CDAtomicObjects.AtomicObsSpecific] THEN FOR geom: CDAtomicObjects.DrawList _ NARROW [obj.specific, CDAtomicObjects.AtomicObsSpecific].rList, geom.rest WHILE geom # NIL DO SELECT geom.first.layer FROM pol => polList _ CONS [geom.first.r, polList]; ndif, pdif => difList _ CONS [geom.first.r, difList]; nwell, pwell => {wellRect _ geom.first.r; isNWell _ (geom.first.layer = nwell)}; ENDCASE => SIGNAL invalidTransistor ["Unknown transistor geometry"] ENDLOOP ELSE SIGNAL invalidTransistor ["Replace this old Chipmonk transistor"]; et _ NEW [ExXtr]; SELECT tClass FROM $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]]; 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 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 ENDCASE => SIGNAL invalidTransistor ["Unknown or antique transistor class"]; END; -- MakeTransistor END. ~SaguaroImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Written by gbb, March 31, 1987 5:37:59 pm PST gbb April 2, 1987 1:17:47 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. Types ExtractedTransistor: TYPE ~ REF exXtr; ExXtr: TYPE ~ RECORD [ch1, ch2, gate, bulk: Geom, 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]; Operation Interim version. Technology dependent !!! Get the geometry. Streching information has already been procesed by ChipNDale. Process the geometry according to the transistor class. The ChipNDale transistors are fully supported for p substrate. Process gate lead-in Process well. state.attributes.PutGeometry [cell.public[0], et.gate.layout]; state.attributes.PutGeometry [cell.public[1], et.ch1.layout]; state.attributes.PutGeometry [cell.public[2], et.ch2.layout] Initialisation Κ&˜codešœ™Kšœ<™Kšœ œ˜Iunit™Ošœœ3˜@š œ"œDœœ˜‚šœ˜Kšœœ˜.Kšœœ˜5KšœP˜PKšœœ2˜C—Jš˜——Kšœœ<˜GNšœv™vKšœœ ˜šœ˜šœœ ˜7KšœTœ˜\Kšœ1˜1Kšœ:˜:Kšœ,˜,KšœB˜BKšœ>˜>Kšœ>˜>KšœH˜HKšœ?˜?Icode1šœ/˜/Ošœ8˜8Ošœ,˜,Ošœ:˜:Nšœœœ2˜YKšœœ8˜MKšœœ ˜4Kšœœ ˜4KšœH˜Hšœœ˜#Kš œœ œ œœ  ‘˜8Kšœœœœ8˜fKšœœ˜%Kš˜—Kšœ ˜—šœœ ˜6Kšœœ!˜+Kšœœ"˜3Kšœ<œ˜DKšœVœ7˜”Kšœ8˜<š œœœœœœ˜Bšœœ˜CKšœ(˜(—šœœ˜CKšœ(˜(—Jšœ˜—Kšœ˜Kšœ˜Kšœ˜Kšœ"˜"Kšœc˜cKšœ=˜=OšœN˜NOšœM˜MOšœM˜MOšœV˜VOšœ&˜&Nšœœœ2˜YKšœ5˜5KšœL˜LKšœ1˜1Kšœ˜KšœD˜DKšœœK˜`Nšœ™šœ +˜1Kšœœ!˜&Kšœ`˜`Kšœœ ˜2Kšœ`˜`Kšœœ% ˜@Kšœ˜KšœI˜IKšœœ ˜2KšœI˜IKšœœ$ ˜?Kšœ ˜—N™ šœœ˜#Kš œœ œ œœ  ‘˜8Kšœœœœ8˜fKšœœ˜%Kš˜—Kšœ  ˜%—Nšœœ;˜L—Kšœ>™>Kšœ=™=Kšœ<™