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.