DIRECTORY CD, CDAtomicObjects, CDBasics, CDOps, CDStretchyBackdoor, CMos, Rope; CMosObsImpl: CEDAR PROGRAM IMPORTS CD, CDAtomicObjects, CDBasics, CDOps, CDStretchyBackdoor, CMos, Rope = BEGIN lambda: CD.Number = CMos.lambda; wellSurround: CD.Number = CMos.wellSurround; MatchTrans: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = { RETURN [layer=me.layer OR layer=CMos.pol] }; wellTransClass: CD.ObjectClass; transClass: CD.ObjectClass; FillTransistor: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { dExt: CD.Number = 2*lambda; pExt: CD.Number = 2*lambda; dif: CD.Layer; inr: CD.Rect _ ob.bbox; inr.x2 _ MAX[inr.x2, 2*lambda+2*pExt]; inr.y2 _ MAX[inr.y2, 2*lambda+2*dExt]; IF ob.layer=CMos.wpdif OR ob.layer=CMos.wndif THEN { ob.class _ wellTransClass; IF ob.layer=CMos.wpdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1-wellSurround+pExt, x2: inr.x2+wellSurround-pExt, y1: inr.y1-wellSurround, y2: inr.y2+wellSurround], layer: (IF dif=CMos.pdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; } ELSE { IF ob.layer=CMos.pdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; }; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1+pExt, x2: inr.x2-pExt, y1: inr.y1, y2: inr.y2], layer: dif ]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2, y1: inr.y1+dExt, y2: inr.y2-dExt], layer: CMos.pol ]; }; DescribeT: CD.DescribeProc = { dExt: CD.Number = 2*lambda; pExt: CD.Number = 2*lambda; sz: CD.Position = CD.InterestSize[ob]; RETURN [ Rope.Cat[ "transistor ", CDOps.LayerRope[ob.layer], Rope.Cat[" [", CDOps.LambdaRope[sz.x-2*pExt, lambda], CDOps.LambdaRope[sz.y-2*dExt, lambda], "]"] ] ] }; wellLTransClass: CD.ObjectClass; FillLTransistor: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { pExt: CD.Number = 2*lambda; --poly extends gate dExt: CD.Number = 2*lambda; --diffusion extends gate dW: CD.Number = 2*lambda; --witdth of diffusion in gate (not width of gate) pW: CD.Number = 2*lambda; --witdth of poly in gate (not width of gate) minSz: CD.Number = pExt+2*dExt+dW; dif: CD.Layer; inr: CD.Rect _ ob.bbox; inr.x2 _ MAX[inr.x2, minSz]; inr.y2 _ MAX[inr.y2, minSz]; ob.bbox _ inr; IF ob.layer=CMos.wpdif OR ob.layer=CMos.wndif THEN { wR: CD.Rect; ob.class _ wellLTransClass; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1-wellSurround+pExt, x2: inr.x2+wellSurround, y1: inr.y1-wellSurround , y2: inr.y1+wellSurround+dW+2*dExt], layer: (IF dif=CMos.wpdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; wR _ [x1: inr.x2-(dW+2*dExt)-wellSurround, x2: inr.x2+wellSurround, y1: inr.y1+wellSurround+dW+2*dExt, y2: inr.y2+wellSurround-pExt]; IF CDBasics.NonEmpty[wR] THEN CDAtomicObjects.Incorporate[ob: ob, r: wR, layer: (IF dif=CMos.pdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; IF ob.layer=CMos.wpdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; } ELSE { IF ob.layer=CMos.pdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; }; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1+pExt, x2: inr.x2, y1: inr.y1, y2: 2*dExt+dW], layer: dif ]; IF 2*dExt+dW < inr.y2-pExt THEN CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x2-2*dExt-dW, x2: inr.x2, y1: 2*dExt+dW, y2: inr.y2-pExt ], layer: dif ]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2-dExt, y1: dExt, y2: dExt+pW], layer: CMos.pol ]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x2-pW-dExt, x2: inr.x2-dExt, y1: inr.y1+pW+dExt, y2: inr.y2], layer: CMos.pol ]; }; simpleContactClass: CD.ObjectClass; wellSimpleContactClass: CD.ObjectClass; FillSimpleCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { rimW: CD.Number ~ lambda; -- therefore NOT large dif: CD.Layer; inr: CD.Rect _ [0, 0, 2*lambda+2*rimW, 2*lambda+2*rimW]; IF ob.layer=CMos.wpdif OR ob.layer=CMos.wndif THEN { ob.class _ wellSimpleContactClass; dif _ (IF ob.layer=CMos.wpdif THEN CMos.pdif ELSE CMos.ndif); CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, wellSurround], layer: (IF dif=CMos.pdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; } ELSE { dif _ ob.layer }; CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: dif]; CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMos.met]; CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -rimW], layer: CMos.cut]; }; DescribeC: CD.DescribeProc = { RETURN [Rope.Cat["contact ", CDOps.LayerRope[ob.layer]]] }; wellDifShortContactClass: CD.ObjectClass; FillDifShortCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { dif: CD.Layer; inr: CD.Rect; innerW: CD.Number = 4*lambda; innerH: CD.Number = 8*lambda; h: CD.Number = innerH/2; inr _ [x1: 0, y1: 0, x2: innerW, y2: innerH]; IF ob.layer=CMos.wpdif OR ob.layer=CMos.wndif THEN { ob.class _ wellDifShortContactClass; IF ob.layer=CMos.wpdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; CDAtomicObjects.Incorporate[ob: ob, r: [-wellSurround, -wellSurround, innerW+wellSurround, innerH+wellSurround-h], layer: (IF dif=CMos.pdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; } ELSE { IF ob.layer=CMos.pdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; }; CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMos.met]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2, y1: inr.y1, y2: inr.y1+h], layer: dif ]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2, y1: inr.y1+h, y2: inr.y2], layer: (IF dif=CMos.pdif THEN CMos.nwellCont ELSE CMos.pwellCont) ]; CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -lambda], layer: CMos.cut]; }; -- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- wellButContactClass: CD.ObjectClass; MatchButCon: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = { RETURN [layer=me.layer OR layer=CMos.met OR layer=CMos.pol] }; FillButCon: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { polyH: CD.Number = 3*lambda; diffOffsetY: CD.Number = polyH-lambda; inr: CD.Rect _ [x1: 0, y1: 0, x2: 4*lambda, y2: diffOffsetY+4*lambda]; dif: CD.Layer; IF ob.layer=CMos.wpdif OR ob.layer=CMos.wndif THEN { ob.class _ wellButContactClass; IF ob.layer=CMos.wpdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1-wellSurround, x2: inr.x2+wellSurround, y1: inr.x1-wellSurround+diffOffsetY, y2: inr.y2+wellSurround], layer: (IF dif=CMos.pdif THEN CMos.nwell ELSE CMos.pwell), inside: FALSE ]; } ELSE { IF ob.layer=CMos.pdif THEN dif _ CMos.pdif ELSE dif _ CMos.ndif; }; CDAtomicObjects.Incorporate[ob: ob, r: inr, layer: CMos.met]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2, y1: inr.y1+diffOffsetY, y2: inr.y2], layer: dif ]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: inr.x1, x2: inr.x2, y1: inr.y1, y2: inr.y1+polyH], layer: CMos.pol ]; CDAtomicObjects.Incorporate[ob: ob, r: CDBasics.Extend[inr, -lambda], layer: CMos.cut ]; }; FillVia: PROC [ob: CD.Object] RETURNS [mustFail: BOOL_FALSE] = { viaRimWidth: CD.Number = lambda; cut2min: CD.Number = 3*lambda; ob.bbox _ [0, 0, cut2min+2*viaRimWidth, cut2min+2*viaRimWidth]; ob.layer _ CMos.met2; CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMos.met2]; CDAtomicObjects.Incorporate[ob: ob, r: ob.bbox, layer: CMos.met]; CDAtomicObjects.Incorporate[ob: ob, r: [x1: viaRimWidth, x2: cut2min+viaRimWidth, y1: viaRimWidth, y2: cut2min+viaRimWidth], layer: CMos.cut2 ]; }; MatchSimpleCon: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = { RETURN [layer=me.layer OR layer=CMos.met] }; Init: PROC [] = BEGIN Register: PROC [key: ATOM, creator: CDAtomicObjects.FillObjectProc, desc: Rope.ROPE, match: CDStretchyBackdoor.MatchProc_NIL] RETURNS [p: CD.ObjectClass] = { p _ CDAtomicObjects.RegisterAtomicObClass[key, creator, desc, CMos.cmos]; IF p=NIL THEN ERROR; IF match=NIL THEN match _ MatchSimpleCon; CDStretchyBackdoor.InstallMatchProc[p, match]; }; transClass _ Register[$CTrans, FillTransistor, "transistor", MatchTrans]; transClass.describe _ DescribeT; wellTransClass _ Register[$CWellTrans, FillTransistor, "transistor", MatchTrans]; wellTransClass.describe _ DescribeT; [] _ Register[$CLTrans, FillLTransistor, "L-transistor", MatchTrans]; wellLTransClass _ Register[$CLWellTrans, FillLTransistor, "L-transistor", MatchTrans]; simpleContactClass _ Register[$CSimpleCon, FillSimpleCon, "contact"]; simpleContactClass.describe _ DescribeC; wellSimpleContactClass _ Register[$CWellSimpleCon, FillSimpleCon, "contact"]; wellSimpleContactClass.describe _ DescribeC; [] _ Register[$CDifShortCon, FillDifShortCon, "dif short contact"]; wellDifShortContactClass _ Register[$CWellDifShortCon, FillDifShortCon, "dif short contact"]; [] _ Register[$CButtingCont, FillButCon, "butting contact", MatchButCon]; wellButContactClass _ Register[$CWellButtingCont, FillButCon, "butting contact", MatchButCon]; [] _ Register[$CVia, FillVia, "via"]; END; Init[]; END. lCMosObsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, March 22, 1985 11:09:09 am PST Last edited by: Christian Jacobi, October 31, 1986 3:02:40 pm PST -- straight transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --poly, dif, welldif, via -- Don't care about different diffusions and such -- L transistors -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --horizontal piece of nwell --vertical piece of nwell if ~empty --horizontal piece of diff --vertical piece of diff -- simple contacts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Don't care about different diffusions and such --via -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --poly, dif, welldif, via -- Don't care about different diffusions and such --transistors --contacts Κ P˜codešœ™Kšœ Οmœ1™