CMosContactsImpl.mesa (part of Chipndale)
by Christian Jacobi June 24, 1983 5:03 pm
last edited Christian Jacobi December 14, 1983 3:08 pm
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𡤊ptr^];
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<burAct THEN MAX[lex+lambda, burAct] ELSE lex)*2+lambda*MAX[6*lambda/actWidth, 2]
];
cp.typ ← burr;
cp.wExt ← wex;
cp.lExt ← lex;
IF difLev=CMos.pdif THEN {
cob.p ← pForWellBurCon;
cob.size ← [w+2*wellSurround, l+2*wellSurround];
}
ELSE {
cob.p ← pForBurCon;
cob.size ← [w, l];
};
cob.level ← difLev;
RETURN [burCache.ReplaceByAequivalent[cob]]
END;
ReadBurCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- =
BEGIN
w: INT = TokenIO.ReadInt[];
l: INT = TokenIO.ReadInt[];
wex: INT = TokenIO.ReadInt[];
lex: INT = TokenIO.ReadInt[];
difLev: CD.Level = CDIO.ReadLevel[];
RETURN [ CreateBurCon[w, l, wex, lex, difLev] ]
END;
WriteBurCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- =
BEGIN
cp: ContactPtr = NARROW[me.specificRef];
IF me.level = CMos.pdif THEN {
TokenIO.WriteInt[me.size.x-2*wellSurround];
TokenIO.WriteInt[me.size.y-2*wellSurround];
}
ELSE {
TokenIO.WriteInt[me.size.x];
TokenIO.WriteInt[me.size.y];
};
TokenIO.WriteInt[cp.wExt];
TokenIO.WriteInt[cp.lExt];
CDIO.WriteLevel[me.level];
END;
DrawBurrCon: 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;
--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<burAct THEN MAX[p.wExt+lambda, burAct] ELSE p.wExt-lambda,
y: IF p.lExt<burAct THEN MAX[p.lExt+lambda, burAct] ELSE p.lExt-lambda
];
Save[[dBur, dBur, aptr.ob.size.x-dBur, aptr.ob.size.y-dBur], bur];
Draw[[burAct, p.lExt, aptr.ob.size.x-p.wExt, aptr.ob.size.y-p.lExt], pol];
Draw[[lambda, diffBur.y, aptr.ob.size.x-diffBur.x, aptr.ob.size.y-diffBur.y], aptr.ob.level];
END;
DrawWellBurrCon: 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;
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.wExt<burAct THEN MAX[p.wExt+lambda, burAct] ELSE p.wExt-lambda,
y: IF p.lExt<burAct THEN MAX[p.lExt+lambda, burAct] ELSE p.lExt-lambda
];
Save[CDInline.Extend[inr, -dBur], bur];
Draw[[inr.x1+burAct, inr.y1+p.lExt, inr.x2-p.wExt, inr.y2-p.lExt], pol];
Draw[[inr.x1+lambda, inr.y1+diffBur.y, inr.x2-diffBur.x, inr.y2-diffBur.y], aptr.ob.level];
Draw[r, nwel];
END;
LengthenBur: 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^];
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};
ap.ob ← CreateBurCon[w: sz.x, l: sz.y, wex: cp.wExt, lex: cp.lExt, 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;
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𡤊ptr^];
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𡤊ptr^];
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𡤊ptr^];
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𡤊ptr^];
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.