DIRECTORY CMosCMContacts, CMosObjects, CD, CDBasics, CDIO, CDLRUCache, CDOps, CDRects USING [CreateRect], CDStretchyBackdoor, CMos, Rope, TokenIO; CMosCMContactsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDIO, CDLRUCache, CDOps, CDStretchyBackdoor, CDRects, CMos, Rope, TokenIO, CMosObjects EXPORTS CMosCMContacts = BEGIN OPEN CMos; lambda: CD.Number = CMos.lambda; ContactType: TYPE = CMosCMContacts.ContactType; ContactPtr: TYPE = CMosCMContacts.ContactPtr; ContactRec: TYPE = CMosCMContacts.ContactRec; undef: CD.Layer = CD.undefLayer; wellSurround: CD.Number = CMos.wellSurround; difCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; polyCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; dsCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; butCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; burCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; mmCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; Aequivalent: PROC[mySpecific, other: REF ANY] RETURNS [BOOL] = { WITH other SELECT FROM p2: ContactPtr => RETURN [NARROW[mySpecific, ContactPtr]^=p2^]; ENDCASE => RETURN [FALSE] }; NewCont: PROC [] RETURNS [CD.Object] = { ob: CD.Object _ NEW[CD.ObjectRep]; ob.specific _ NEW[ContactRec]; RETURN [ob] }; InsideRectWithSurround: PROC [ob: CD.Object] RETURNS [CD.Rect] = { RETURN [CDBasics.Extend[ob.bbox, -wellSurround]] }; ShowSelectedWithSurround: CD.DrawProc = { pr.drawOutLine[pr, CDBasics.Extend[CDBasics.MapRect[ob.bbox, trans], -(wellSurround)], CD.selectionLayer] }; MatchContact: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN IF layer=me.layer THEN RETURN [TRUE] ELSE { cp: ContactPtr = NARROW[me.specific]; RETURN [ SELECT cp.typ FROM burr => (layer=CMos.pol), mDif => (layer=CMos.met), difShort => FALSE, butt => (layer=CMos.met OR layer=CMos.pol), mPol => (layer=CMos.met), mm2 => (layer=CMos.met2), ENDCASE => FALSE ] } END; pForDifPolCon: CD.ObjectClass = RegisterObjectClass[$CMosContactDifAndPol]; pForWellDifPolCon: CD.ObjectClass = RegisterObjectClass[$CMosContactWellDifAndPol]; difpolRimWidth: CD.Number = lambda; CreateDifCon: PUBLIC PROC [l: CD.Number, difLev: CD.Layer] RETURNS [CD.Object] = BEGIN cob: CD.Object ~ difCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specific]; IF difLev=undef THEN difLev_ndif; IF l=butConSX THEN { IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; IF difLev=CMos.pol THEN RETURN [CMosObjects.CreatePolyCon[]] ELSE RETURN [CMosObjects.CreateDifCon[difLev]] }; l _ MAX[l, butConSX]; cp.typ _ mDif; cob.layer _ difLev; IF difLev=CMos.pdif THEN { cob.class _ pForWellDifPolCon; cob.bbox _ [-wellSurround, -wellSurround, butConSX+wellSurround, l+wellSurround]; } ELSE { cob.class _ pForDifPolCon; cob.bbox _ [0, 0, butConSX, l]; }; RETURN [difCache.ReplaceByAequivalent[cob]] END; CreatePolyCon: PUBLIC PROC [l: CD.Number] RETURNS [CD.Object] = BEGIN cob: CD.Object ~ polyCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specific]; IF l=butConSX THEN { RETURN [CMosObjects.CreatePolyCon[]] }; l _ MAX[l, butConSX]; cp.typ _ mPol; cob.class _ pForDifPolCon; cob.bbox _ [0, 0, butConSX, l]; cob.layer _ pol; RETURN [polyCache.ReplaceByAequivalent[cob]] END; ReadDifPolCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN lev: CD.Layer = CDIO.ReadLayer[h]; IF lev=pol THEN RETURN [ CreatePolyCon[TokenIO.ReadInt[h]] ] ELSE RETURN [ CreateDifCon[TokenIO.ReadInt[h], lev] ] END; WriteDifPolCon: CD.InternalWriteProc -- PROC [ob: Object] -- = BEGIN CDIO.WriteLayer[h, ob.layer]; TokenIO.WriteInt[h, CD.InterestSize[ob].y]; END; DrawDifPolCon: CD.DrawProc = BEGIN r: CD.Rect = CDBasics.MapRect[ob.bbox, trans]; pr.drawRect[pr, r, met]; pr.drawRect[pr, r, ob.layer]; pr.drawRect[pr, CDBasics.Extend[r, -difpolRimWidth], cut]; END; DrawWellDifPolCon: CD.DrawProc = BEGIN r: CD.Rect = CDBasics.MapRect[ob.bbox, trans]; inr: CD.Rect = CDBasics.Extend[r, -wellSurround]; pr.drawRect[pr, inr, met]; pr.drawRect[pr, inr, ob.layer]; pr.drawRect[pr, CDBasics.Extend[inr, -difpolRimWidth], cut]; pr.drawRect[pr, r, nwell]; END; pForDifShorts: CD.ObjectClass = RegisterObjectClass[$CMosContactDifShort]; pForWellDifShorts: CD.ObjectClass = RegisterObjectClass[$CMosContactWellDifShort]; difShortRimWidth: CD.Number = lambda; CreateDifShortCon: PUBLIC PROC [difLev: CD.Layer] RETURNS [CD.Object] = BEGIN IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; RETURN [CMosObjects.CreateDifShortCon[difLev]] END; ReadDifShortCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN RETURN [ CreateDifShortCon[CDIO.ReadLayer[h]] ] END; -- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pForButContact: CD.ObjectClass = RegisterObjectClass[$CMosContactBut]; pForWellButContact: CD.ObjectClass = RegisterObjectClass[$CMosContactWellBut]; butConSX: CD.Number = 4*lambda; CreateButCon: PUBLIC PROC [difLev: CD.Layer] RETURNS [CD.Object] = BEGIN IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; RETURN [CMosObjects.CreateButCon[difLev]] END; ReadButCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN RETURN [ CreateButCon[CDIO.ReadLayer[h]] ] END; pForBurCon: CD.ObjectClass = RegisterObjectClass[$CMosBurContact]; pForWellBurCon: CD.ObjectClass = RegisterObjectClass[$CMosWellBurContact]; CreateBurCon: PUBLIC PROC [w, l: CD.Number, wex: CD.Number, lex: CD.Number, difLev: CD.Layer] RETURNS [CD.Object] = BEGIN burAct: CD.Number = 2*lambda; actWidth, xMargins: CD.Number; cob: CD.Object ~ burCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specific]; IF difLev=undef THEN difLev_ndif; wex _ MAX[0, wex]; lex _ MAX[0, lex]; xMargins _ burAct + (IF wex< burAct THEN MAX[wex+lambda, burAct] ELSE wex); actWidth _ MAX[2*lambda, w-xMargins]; w _ actWidth+xMargins; l _ MAX[l, (IF lexmins THEN --old technology-- pr.drawRect[pr, CDBasics.Extend[r, -2*lambda --oldmmRimWidth-- ], cut2] ELSE --new technology-- pr.drawRect[pr, CDBasics.Extend[r, -mmRimWidth], cut2]; END; Describe: CD.DescribeProc = BEGIN cp: ContactPtr = NARROW[ob.specific]; RETURN [ SELECT cp.typ FROM burr => Rope.Concat["buried contact ", CDOps.LayerRope[ob.layer]], mDif => Rope.Concat[CDOps.LayerRope[ob.layer], " contact"], difShort => Rope.Concat["dif - short contact ", CDOps.LayerRope[ob.layer]], butt => Rope.Concat["butting contact ", CDOps.LayerRope[ob.layer]], mPol => "contact poly", mm2 => "via", ENDCASE => "unknown contact" ] END; Init: PROC [] = BEGIN pForDifPolCon.drawMe _ pForDifPolCon.quickDrawMe _ DrawDifPolCon; pForDifPolCon.internalRead _ ReadDifPolCon; pForDifPolCon.internalWrite _ WriteDifPolCon; pForDifPolCon.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForDifPolCon, MatchContact]; pForWellDifPolCon.drawMe _ pForWellDifPolCon.quickDrawMe _ DrawWellDifPolCon; pForWellDifPolCon.interestRect _ InsideRectWithSurround; pForWellDifPolCon.showMeSelected _ ShowSelectedWithSurround; pForWellDifPolCon.internalRead _ ReadDifPolCon; pForWellDifPolCon.internalWrite _ WriteDifPolCon; pForWellDifPolCon.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForWellDifPolCon, MatchContact]; pForButContact.internalRead _ ReadButCon; pForWellButContact.internalRead _ ReadButCon; pForBurCon.drawMe _ pForBurCon.quickDrawMe _ DrawBurrCon; pForBurCon.internalRead _ ReadBurCon; pForBurCon.internalWrite _ WriteBurCon; pForBurCon.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForBurCon, MatchContact]; pForWellBurCon.interestRect _ InsideRectWithSurround; pForWellBurCon.internalRead _ ReadBurCon; pForWellBurCon.internalWrite _ WriteBurCon; pForWellBurCon.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForWellBurCon, MatchContact]; pForVia.drawMe _ pForVia.quickDrawMe _ DrawVia; pForVia.internalRead _ ReadVia; pForVia.internalWrite _ WriteVia; pForVia.describe _ Describe; CDStretchyBackdoor.InstallMatchProc[pForVia, MatchContact]; pForDifShorts.internalRead _ ReadDifShortCon; pForWellDifShorts.internalRead _ ReadDifShortCon; END; Init[]; END. δCMosCMContactsImpl.mesa (part of ChipNDale) Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. Christian Jacobi, June 24, 1983 5:03 pm Last edited by: Christian Jacobi, October 31, 1986 4:21:10 pm PST -- Don't care about different diffusions and such -- Dif and Pol -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --connect diffusion with metal --connect poly with metal -- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --connects metal with poly and diffusion -- Bur -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Buried contacts come in three flavours, Pol-Surround, Dif-Surround and Crossing. The buried contacts in chipndale are parameterized by lExt and wExt, their interpretation is as follows: Diff always extends 1l to the left, material above/below and to the right is determined by lExt and wExt respectively. 2l is the pivotal value, below 2l the material is Pol, at 2l or above the material is Diff. (Note: some combinations give Diff on all four sides, it is assumed that such combinations will not be created.) -- connects diffusion with poly without accessing metal -- copied from chipmonk without understanding --can not be produced --uses outer stuff!! --copied from chipmonk without understanding --Mm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --ignores wex and lex in chipmonk, why??? --connects two layers of metal --cp.wExt _ ; --cp.wExt _ ; --does not read specific !!!!!! -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pForWellBurCon.drawMe _ pForWellBurCon.quickDrawMe _ DrawWellBurrCon; Κ˜codešœ,™,Kšœ Οmœ7™BKšœ)™)K™AK˜—šΟk ˜ Kšœ˜Kšœ ž˜ Kšžœ˜Kšœ ˜ K˜K˜ Kšœ˜Kšœžœ˜Kšœ˜K˜Kšœ˜Kšœ˜K˜—šΟbœžœžœ˜"Kšžœe˜lKšžœ˜—Kšžœžœ˜K˜Kšœžœ˜ Kšœ žœ˜/Kšœ žœ˜-Kšœ žœ˜-Kšœžœ˜ K˜Kšœžœ˜,K˜šœ ˜ KšœL˜L—šœ!˜!KšœL˜L—šœ˜KšœL˜L—šœ ˜ KšœL˜L—šœ ˜ KšœL˜L—šœ˜KšœL˜L—K˜š Οn œžœžœžœžœžœ˜@šžœžœž˜Kšœžœžœ˜?Kšžœžœžœ˜—K˜—K˜š œžœžœžœ ˜(Kšœžœ žœžœ ˜"Kšœžœ ˜Kšžœ˜ K˜—K˜š  œžœžœ žœžœ ˜BKšžœ+˜1Kšœ˜K˜—š œžœ ˜)KšœWžœ˜iKšœ˜K˜—š Πbn Ÿžœ4žœžœžœžœ˜hKšž˜Kšœ1™1Kšžœžœžœžœ˜$šžœ˜Kšœžœ˜%šžœ˜šžœž˜Kšœ˜Kšœ˜Kšœ žœ˜Kšœžœ˜+Kšœ˜Kšœ˜Kšžœž˜—K˜—K˜—Kšžœ˜—K˜Kšœc™cK˜Kšœžœ:˜KKšœžœ>˜SKšœžœ˜#K˜š  œžœžœžœžœžœžœ ˜PKšœ™Kšž˜Kšœžœ!˜(Kšœžœ˜&Kšžœžœ˜"šžœ žœ˜Kšžœžœ˜-Kšžœžœžœ˜Kšž˜Kšžœ˜Jšœ+˜+Kšžœ˜—K˜š  œžœ ˜Kšž˜Jšœžœ/˜4Kšœ˜Kšœ˜Kšœ:˜:Kšžœ˜K˜—š œžœ ˜ Kšž˜Jšœžœ/˜4Kšœžœ+˜2Kšœ˜Kšœ˜Kšœ<˜Kšž˜Kšžœ$˜*Kšžœ˜—K˜K™Kšœa™aK˜Kšœ žœ4˜BKšœžœ8˜JK˜K™šœ„™„K™—š  œžœžœžœ˜+Kšœžœ˜Kšœžœ˜Kšœžœžœžœ ˜'Kšœ7™7Kšžœ˜Kšœ-™-Kšœžœ˜Kšœžœ˜Kšœžœ!˜(Kšœžœ˜&Kšžœžœ˜"Kšœžœ ˜Kšœžœ ˜šœ˜Kš œžœ žœžœžœ˜7—Kšœ žœ˜%Kšœ˜šœžœ˜ Kš œžœ žœžœžœžœ˜XKšœ˜—K˜K˜K˜šžœžœ˜Kšœ™Kšžœžœ˜2K˜—šžœ˜Kšœ˜J˜K˜—K˜Kšžœ%˜+Kšžœ˜K˜—šŸ œžœ’œ˜>Kšž˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ%˜%Kšžœ)˜/Kšžœ˜—K˜š‘ œžœ˜#Kšž˜Kšœžœ˜%Jšžœ žœ˜&Kšœ˜Kšœ˜Kšžœ˜Kšžœ˜—K˜š  œžœ ˜Kšž˜K˜š  œžœžœ žœ žœ˜.Kš’™Kšœ/˜/Kšœ˜K˜—Kš’,™,Jšœžœ˜(Jšœžœ˜Jšœžœ˜šœ žœ ˜Jš œžœžœžœžœ˜SJš œžœžœžœžœ˜RJ˜—Jšœ:˜:JšœN˜NJšœP˜PKšžœ˜K˜—Kšœ_™_K˜Kšœ žœ3˜>Kšœ žœ˜Kšœ žœ˜K˜š  œžœžœžœ˜'Kšœžœ˜Kšœžœ žœžœ ˜%Kšœ)™)Kšœ™Kšžœ˜Kšœžœ ˜'Kšœžœ˜&Kšœžœ˜'Kšœ žœ+˜6Kšœžœ ˜Kšžœžœžœ˜2K˜ Kšœ ™ Kšœ ™ K˜šžœ žœ’>œ˜QJšœ˜—šžœ’œ˜Jšœ˜—K˜Kšžœ$˜*Kšžœ˜K˜—š œžœ’œ˜;Kšž˜Kšžœ*˜0Kšžœ˜—K˜š œžœ’œ˜8Kšž˜Jšœ+˜+Kšžœ˜—K˜š œžœ ˜Kš’™Kšž˜Jšœžœ˜'Jšœžœ/˜4J˜J˜šžœžœ’œ˜+Jšœ-’œ ˜G—šžœ’œ˜Jšœ7˜7—Kšžœ˜K˜—KšœZ™ZK˜š œžœ˜Kšž˜Kšœžœ˜%šžœ˜šžœž˜KšœB˜BKšœ;˜;KšœK˜KKšœC˜CKšœ˜Kšœ ˜ Kšžœ˜—K˜—Kšžœ˜—K˜š œžœ˜Kšž˜KšœA˜AKšœ+˜+Kšœ-˜-Kšœ"˜"KšœA˜AK˜KšœM˜MKšœ8˜8Kšœ<˜˜>K˜KšœE™EKšœ5˜5Kšœ)˜)Kšœ+˜+Kšœ#˜#KšœB˜BK™Kšœ/˜/Kšœ˜Kšœ!˜!Kšœ˜Kšœ;˜;K˜Kšœ-˜-Kšœ1˜1K˜Kšžœ˜K˜—K˜Kšžœ˜K˜—…—*θ?Ϊ