<> <> <> DIRECTORY Atom, CMosContacts, CD, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDInline, CDApplications, CMos, Rope, TokenIO; CMosContactsImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDInline, CDApplications, CMos, Rope, TokenIO EXPORTS CMosContacts = BEGIN OPEN CMos; lambda: CD.DesignNumber = CD.lambda; ContactType: TYPE = CMosContacts.ContactType; ContactPtr: TYPE = CMosContacts.ContactPtr; ContactRec: TYPE = CMosContacts.ContactRec; undef: CD.Level = CMosContacts.undef; wellSurround: CD.DesignNumber = CMos.wellSurround; butConSX: CD.DesignNumber = 4*lambda; butConSY: CD.DesignNumber = 6*lambda; 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]; ToPosition: PROC [x: REF] RETURNS [p: CD.DesignPosition] = <<--y field defaults to lambda, x field defaults to 0>> <<--[0, 0] if not done>> BEGIN IF x=NIL THEN p _ [0, lambda] ELSE WITH x SELECT FROM rp: REF CD.DesignPosition => p _ rp^; rn: REF CD.DesignNumber => p _ [0, rn^]; ENDCASE => p _ [0, 0]; END; 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.ObPtr] = { ob: CD.ObPtr _ NEW[CD.ObjectDefinition]; ob.specificRef _ NEW[ContactRec]; RETURN [ob] }; InsideRectWithSurround: PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] = BEGIN RETURN [CDInline.Extend[CDInline.RectAt[[0, 0], ob.size], -wellSurround]] END; ShowSelectedWithSurround: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.outLineProc[CDInline.Extend[CDOrient.RectAt[pos, aptr.ob.size, orient], -wellSurround], pr] END; HitInsideWithSurround: PROC [aptr: CD.ApplicationPtr, hitRect: CD.DesignRect] RETURNS [BOOL] = BEGIN RETURN [CDInline.Intersect[ CDInline.Extend[ CDApplications.ApplicationRect[aptr], -wellSurround], hitRect]] END; MatchContact: PROC [me: CD.ObPtr, r: CD.DesignRect, level: CD.Level, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN <<-- Don't care about different diffusions and such>> IF level=me.level THEN RETURN [TRUE] ELSE { cp: ContactPtr = NARROW[me.specificRef]; RETURN [ SELECT cp.typ FROM burr => (level=CMos.pol), mDif => (level=CMos.met), difShort => FALSE, butt => (level=CMos.met OR level=CMos.pol), mPol => (level=CMos.met), mm2 => (level=CMos.met2), ENDCASE => FALSE ] } END; <<-- Dif and Pol -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- >> pForDifPolCon: REF CD.ObjectProcs = RegisterObjectType[$CMosContactDifAndPol]; pForWellDifPolCon: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellDifAndPol]; difpolRimWidth: CD.DesignNumber = lambda; CreateDifCon: PUBLIC PROC [l: CD.DesignNumber, difLev: CD.Level] RETURNS [CD.ObPtr] = <<--connect diffusion with metal>> BEGIN cob: CD.ObPtr ~ difCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev_ndif; l _ MAX[l, butConSX]; cp.typ _ mDif; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellDifPolCon; cob.size _ [butConSX+2*wellSurround, l+2*wellSurround]; } ELSE { cob.p _ pForDifPolCon; cob.size _ [butConSX, l]; }; RETURN [difCache.ReplaceByAequivalent[cob]] END; CreatePolyCon: PUBLIC PROC [l: CD.DesignNumber] RETURNS [CD.ObPtr] = <<--connect poly with metal>> BEGIN cob: CD.ObPtr ~ polyCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; l _ MAX[l, butConSX]; cp.typ _ mPol; cob.p _ pForDifPolCon; cob.size _ [butConSX, l]; cob.level _ pol; RETURN [polyCache.ReplaceByAequivalent[cob]] END; LengthenPolyDif: CDCallSpecific.CallProc = BEGIN amount: CD.DesignPosition = ToPosition[x]; IF amount.y=0 OR amount.x#0 THEN done _ FALSE ELSE { sur: INT = IF aptr.ob.level=CMos.pdif THEN 2*wellSurround ELSE 0; cp: ContactPtr _ NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr _ NEW[CD.Application _ aptr^]; sz: CD.DesignPosition _ CDInline.SubPoints[CDInline.AddPoints[aptr.ob.size, amount], [sur, sur]]; IF sz.x<=0 OR sz.y<=0 THEN {done _ FALSE; RETURN}; IF aptr.ob.level=pol THEN ap.ob _ CreatePolyCon[sz.y] ELSE ap.ob _ CreateDifCon[sz.y, aptr.ob.level]; include _ LIST[ap]; removeMe _ TRUE; repaintMe _ amount.y<0; repaintInclude _ amount.y>0; } END; DefaultenPolyDif: CDCallSpecific.CallProc = BEGIN cp: ContactPtr _ NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr _ NEW[CD.Application_aptr^]; IF aptr.ob.level=pol THEN ap.ob _ CreatePolyCon[4*lambda] ELSE ap.ob _ CreateDifCon[4*lambda, aptr.ob.level]; include _ LIST[ap]; removeMe _ TRUE; repaintMe _ TRUE; repaintInclude _ TRUE; END; ReadDifPolCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN lev: CD.Level = CDIO.ReadLevel[]; IF lev=pol THEN RETURN [ CreatePolyCon[TokenIO.ReadInt[]] ] ELSE RETURN [ CreateDifCon[TokenIO.ReadInt[], lev] ] END; WriteDifPolCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN sur: INT = IF me.level=CMos.pdif THEN 2*wellSurround ELSE 0; CDIO.WriteLevel[me.level]; TokenIO.WriteInt[me.size.y-sur]; END; DrawDifPolCon: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient]; pr.drawRect[r, met, pr]; pr.drawRect[r, aptr.ob.level, pr]; pr.saveRect[CDInline.Extend[r, -difpolRimWidth], cut, pr]; END; DrawWellDifPolCon: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; pr.drawRect[inr, met, pr]; pr.drawRect[inr, aptr.ob.level, pr]; pr.saveRect[CDInline.Extend[inr, -difpolRimWidth], cut, pr]; pr.drawRect[r, nwel, pr]; END; <<-- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- >> pForDifShorts: REF CD.ObjectProcs = RegisterObjectType[$CMosContactDifShort]; pForWellDifShorts: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellDifShort]; difShortRimWidth: CD.DesignNumber = lambda; CreateDifShortCon: PUBLIC PROC [difLev: CD.Level] RETURNS [CD.ObPtr] = BEGIN cob: CD.ObPtr ~ dsCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev _ ndif; cp.typ _ difShort; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellDifShorts; cob.size _ [butConSX+2*wellSurround, 8*lambda+2*wellSurround] } ELSE IF difLev=CMos.ndif THEN { cob.p _ pForDifShorts; cob.size _ [butConSX, 8*lambda] } ELSE ERROR; RETURN [dsCache.ReplaceByAequivalent[cob]] END; ReadDifShortCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN RETURN [ CreateDifShortCon[CDIO.ReadLevel[]] ] END; WriteDifShortCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN CDIO.WriteLevel[me.level]; END; DrawDifShortContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; mr: CD.DesignRect = CDInline.Extend[r, -difShortRimWidth]; h: CD.DesignNumber = (r.y2-r.y1)/2; Draw[r, met]; Draw[[x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y1+h], CMos.ndif]; Draw[[x1: r.x1, y1: r.y1+h, x2: r.x2, y2: r.y2], CMos.pwelCont]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut]; END; DrawWellDifShortContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; mr: CD.DesignRect = CDInline.Extend[inr, -difShortRimWidth]; h: CD.DesignNumber = (inr.y2-inr.y1)/2; Draw[inr, met]; Draw[[x1: inr.x1, y1: inr.y1, x2: inr.x2, y2: inr.y1+h], CMos.pdif]; Draw[[x1: inr.x1, y1: inr.y1+h, x2: inr.x2, y2: inr.y2], CMos.nwelCont]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut]; Draw[[x1: r.x1, x2: r.x2, y1: r.y1, y2: r.y2-h], nwel]; END; -- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pForButContact: REF CD.ObjectProcs = RegisterObjectType[$CMosContactBut]; pForWellButContact: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellBut]; CreateButCon: PUBLIC PROC [difLev: CD.Level] RETURNS [CD.ObPtr] = <<--connects metal with poly and diffusion>> BEGIN cob: CD.ObPtr ~ butCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; cp.typ _ butt; IF difLev=undef THEN difLev_ndif; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellButContact; cob.size _ [butConSX+2*wellSurround, butConSY+2*wellSurround]; } ELSE { cob.p _ pForButContact; cob.size _ [butConSX, butConSY]; }; RETURN [butCache.ReplaceByAequivalent[cob]] END; ReadButCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN RETURN [ CreateButCon[CDIO.ReadLevel[]] ] END; WriteButCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN CDIO.WriteLevel[me.level]; END; DrawButContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; rimWidth: CD.DesignNumber = lambda; polySize: CD.DesignNumber = aptr.ob.size.y/2; Draw[[0, 0, aptr.ob.size.x, aptr.ob.size.y], met]; Draw[[0, 0, aptr.ob.size.x, polySize], pol]; Draw[[0, polySize-lambda, aptr.ob.size.x, aptr.ob.size.y], aptr.ob.level]; Save[[rimWidth, rimWidth, aptr.ob.size.x-rimWidth, aptr.ob.size.y-rimWidth], cut]; END; DrawWellButContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; rimWidth: CD.DesignNumber = lambda; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; polySize: CD.DesignNumber = (inr.y2-inr.y1)/2; Draw[inr, met]; Draw[[x1: inr.x1, y1: inr.y1, x2: inr.x2, y2: inr.y1+polySize], pol]; Draw[[x1: inr.x1, y1: inr.y1+polySize-lambda, x2: inr.x2, y2: inr.y2], aptr.ob.level]; Save[CDInline.Extend[inr, -rimWidth], cut]; Draw[r, nwel]; END; <<-- Bur -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- >> pForBurCon: REF CD.ObjectProcs = RegisterObjectType[$CMosBurContact]; pForWellBurCon: REF CD.ObjectProcs = RegisterObjectType[$CMosWellBurContact]; <<>> CreateBurCon: PUBLIC PROC [w, l: CD.DesignNumber, wex: CD.DesignNumber, lex: CD.DesignNumber, difLev: CD.Level] RETURNS [CD.ObPtr] = <<-- connects diffusion with poly without accessing metal>> BEGIN <<-- copied from chipmonk without understanding>> burAct: CD.DesignNumber = 2*lambda; actWidth, xMargins: CD.DesignNumber; cob: CD.ObPtr ~ burCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; 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 lex> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; <<--copied from chipmonk without understanding>> p: ContactPtr = NARROW[aptr.ob.specificRef]; dBur: CD.DesignNumber = lambda/2; burAct: CD.DesignNumber = lambda*2; diffBur: CD.DesignPosition = [ x: IF p.wExt> BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE <<--uses outer stuff!!>> BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; dBur: CD.DesignNumber = lambda/2; burAct: CD.DesignNumber = lambda*2; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; p: ContactPtr = NARROW[aptr.ob.specificRef]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; diffBur: CD.DesignPosition = [ x: IF p.wExt0 OR amount.y>0; }; END; ChangeExtensionBur: CDCallSpecific.CallProc = BEGIN amount: CD.DesignPosition = ToPosition[x]; IF amount.y=0 AND amount.x=0 THEN done _ FALSE ELSE { sur: INT = (IF aptr.ob.level=CMos.pdif THEN 2*wellSurround ELSE 0); cp: ContactPtr = NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr = NEW[CD.Application_aptr^]; ap.ob _ CreateBurCon[ w: aptr.ob.size.x-sur+amount.x, l: aptr.ob.size.y-sur+amount.y, wex: cp.wExt+amount.x, lex: cp.lExt+amount.y, difLev: aptr.ob.level ]; include _ LIST[ap]; removeMe _ TRUE; repaintMe _ amount.x<0 OR amount.y<0; repaintInclude _ amount.x>0 OR amount.y>0; } END; DefaultenBur: CDCallSpecific.CallProc = BEGIN sur: INT = IF aptr.ob.level=CMos.pdif THEN 2*wellSurround ELSE 0; cp: ContactPtr _ NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr _ NEW[CD.Application_aptr^]; ap.ob _ CreateBurCon[w: aptr.ob.size.x-sur, l: 4*lambda, wex: cp.wExt, lex: cp.lExt, difLev: aptr.ob.level]; include _ LIST[ap]; removeMe _ TRUE; repaintMe _ TRUE; repaintInclude _ TRUE; END; <<--Mm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- >> pForVia: REF CD.ObjectProcs = RegisterObjectType[$CMosMmContact]; mmRimWidth: CD.DesignNumber = 2*lambda; cut2min: CD.DesignNumber = 3*lambda; CreateMmCon: PUBLIC PROC [l: CD.DesignNumber, wex: CD.DesignNumber, lex: CD.DesignNumber] RETURNS [CD.ObPtr] = <<--ignores wex and lex in chipmonk, why???>> <<--connects two layers of metal>> BEGIN cob: CD.ObPtr ~ mmCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; mins: CD.DesignNumber = cut2min+2*mmRimWidth; l _ MAX[l, mins]; cp.typ _ mm2; <<--cp.wExt _ ;>> <<--cp.wExt _ ;>> cob.p _ pForVia; cob.size _ [mins, l]; cob.level _ CMos.met; RETURN [mmCache.ReplaceByAequivalent[cob]] END; LengthenVia: CDCallSpecific.CallProc = BEGIN amount: CD.DesignPosition = ToPosition[x]; IF amount.y=0 OR amount.x#0 THEN done _ FALSE ELSE { cp: ContactPtr _ NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr _ NEW[CD.Application_aptr^]; sz: CD.DesignPosition _ CDInline.AddPoints[aptr.ob.size, amount]; IF sz.x<=0 OR sz.y<=0 THEN {done_FALSE; RETURN}; ap.ob _ CreateMmCon[l: sz.y, wex: cp.wExt, lex: cp.lExt]; include _ LIST[ap]; removeMe _ TRUE; repaintMe _ amount.y<0; repaintInclude _ amount.y>0; } END; DefaultenVia: CDCallSpecific.CallProc = BEGIN cp: ContactPtr _ NARROW[aptr.ob.specificRef]; ap: CD.ApplicationPtr _ NEW[CD.Application_aptr^]; ap.ob _ CreateMmCon[l: 4*lambda, wex: cp.wExt, lex: cp.lExt]; include_LIST[ap]; removeMe _ TRUE; repaintMe _ TRUE; repaintInclude _ TRUE; END; ReadVia: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN RETURN [ CreateMmCon[TokenIO.ReadInt[], 0, 0] ] END; WriteVia: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN TokenIO.WriteInt[me.size.y]; END; DrawVia: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = <<--does not read specificRef !!!!!!>> BEGIN r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient]; pr.drawRect[r, met, pr]; pr.drawRect[r, met2, pr]; pr.saveRect[CDInline.Extend[r, -mmRimWidth], cut2, pr]; END; <<-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- >> DescribeLevel: PROC[l: CD.Level] RETURNS [Rope.ROPE] = {RETURN [Atom.GetPName[CD.LevelKey[l]]]}; Describe: PROC[me: CD.ObPtr] RETURNS [Rope.ROPE] = BEGIN cp: ContactPtr = NARROW[me.specificRef]; RETURN [ SELECT cp.typ FROM burr => Rope.Concat["buried contact ", DescribeLevel[me.level]], mDif => Rope.Concat[DescribeLevel[me.level], " contact"], difShort => Rope.Concat["dif - short contact", DescribeLevel[me.level]], butt => Rope.Concat["butting contact ", DescribeLevel[me.level]], mPol => "contact poly", mm2 => "via", ENDCASE => "unknown contact" ] END; Init: PROC [] = BEGIN pForDifPolCon.drawMe _ DrawDifPolCon; pForDifPolCon.internalRead _ ReadDifPolCon; pForDifPolCon.internalWrite _ WriteDifPolCon; pForDifPolCon.describe _ Describe; pForDifPolCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForDifPolCon, DefaultenPolyDif]; pForWellDifPolCon.drawMe _ DrawWellDifPolCon; pForWellDifPolCon.insideRect _ InsideRectWithSurround; pForWellDifPolCon.showMeSelected _ ShowSelectedWithSurround; pForWellDifPolCon.hitInside _ HitInsideWithSurround; pForWellDifPolCon.internalRead _ ReadDifPolCon; pForWellDifPolCon.internalWrite _ WriteDifPolCon; pForWellDifPolCon.describe _ Describe; pForWellDifPolCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForWellDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForWellDifPolCon, DefaultenPolyDif]; pForButContact.drawMe _ DrawButContact; pForButContact.internalRead _ ReadButCon; pForButContact.internalWrite _ WriteButCon; pForButContact.describe _ Describe; pForButContact.match _ MatchContact; pForWellButContact.drawMe _ DrawWellButContact; pForWellButContact.insideRect _ InsideRectWithSurround; pForWellButContact.hitInside _ HitInsideWithSurround; pForWellButContact.internalRead _ ReadButCon; pForWellButContact.internalWrite _ WriteButCon; pForWellButContact.describe _ Describe; pForWellButContact.match _ MatchContact; pForBurCon.drawMe _ DrawBurrCon; pForBurCon.internalRead _ ReadBurCon; pForBurCon.internalWrite _ WriteBurCon; pForBurCon.describe _ Describe; pForBurCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForBurCon, DefaultenBur]; pForWellBurCon.drawMe _ DrawWellBurrCon; pForWellBurCon.insideRect _ InsideRectWithSurround; pForWellBurCon.hitInside _ HitInsideWithSurround; pForWellBurCon.internalRead _ ReadBurCon; pForWellBurCon.internalWrite _ WriteBurCon; pForWellBurCon.describe _ Describe; pForWellBurCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForWellBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForWellBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForWellBurCon, DefaultenBur]; pForVia.drawMe _ DrawVia; pForVia.internalRead _ ReadVia; pForVia.internalWrite _ WriteVia; pForVia.describe _ Describe; pForVia.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForVia, LengthenVia]; CDCallSpecific.Register[$Default, pForVia, DefaultenVia]; pForDifShorts.drawMe _ DrawDifShortContact; pForDifShorts.internalRead _ ReadDifShortCon; pForDifShorts.internalWrite _ WriteDifShortCon; pForDifShorts.describe _ Describe; pForDifShorts.match _ MatchContact; pForWellDifShorts.drawMe _ DrawWellDifShortContact; pForWellDifShorts.insideRect _ InsideRectWithSurround; pForWellDifShorts.hitInside _ HitInsideWithSurround; pForWellDifShorts.internalRead _ ReadDifShortCon; pForWellDifShorts.internalWrite _ WriteDifShortCon; pForWellDifShorts.describe _ Describe; pForWellDifShorts.match _ MatchContact; END; Init[]; END.