CMosSpinifexInitImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Written by Shand, September 12, 1983 11:40 pm
Last Edited by: Shand, September 7, 1984 1:36:34 pm PDT
DIRECTORY
CD USING [lambda, DesignNumber, DesignPosition, Level, ObjectProcs, FetchObjectProcs, ApplicationPtr, highLightError, Error],
CDObjectProcs USING [RegisterFurther, StoreFurther],
CDProperties USING [PutPropOnTechnology],
TerminalIO USING [WriteRope],
CMos USING [cmos, ndif, pdif, pol, met, met2, nwel, nwelCont, pwelCont],
Rope USING [ROPE],
SpinifexAtoms USING [ spinifex, thymePrint, rosePrint],
SpinifexCircuit USING [CellPostProcessProc, Circuit, CircuitConstraint, CircuitNode, CombineNodePropertyProc, ConstraintResolution, ConversionProc, GeometricRule, MapRec, nodeIndex, NodeLinkage, spaceIndex, SpinifexConstraintIndex, SpinifexLayerIndex, TechHandle, BoxMapProc],
SpinifexOutput USING [LinkagePrintProc],
CMosSpinifex
;
CMosSpinifexInitImpl: CEDAR PROGRAM
IMPORTS CMos, CD, CDObjectProcs, CDProperties, TerminalIO, SpinifexAtoms, CMosSpinifex
EXPORTS CMosSpinifex
~ BEGIN
OPEN CMosSpinifex;
l: CD.DesignNumber ~ CD.lambda;
-- Constraints used in object converters.
excludePolByNDif: PUBLIC REF CircuitConstraint;
excludePolByPDif: PUBLIC REF CircuitConstraint;
polXorDif: PUBLIC REF CircuitConstraint;
polAndDif: PUBLIC REF CircuitConstraint;
channelEdge: PUBLIC REF CircuitConstraint;
polDifError: REF CircuitConstraint;
nDifChannel: PUBLIC REF CircuitConstraint;
nDifInWellError: REF CircuitConstraint;
excludeNDifByWell: REF CircuitConstraint;
contactNDif: REF CircuitConstraint;
excludeNDifByPWellCont: REF CircuitConstraint;
nDifAndPDifError: REF CircuitConstraint;
buriedNDifPol: PUBLIC REF CircuitConstraint;
pDifChannel: PUBLIC REF CircuitConstraint;
pDifAndNDifError: REF CircuitConstraint;
contactPDif: REF CircuitConstraint;
excludePDifByNWellCont: REF CircuitConstraint;
ConfResSetup: PROCEDURE [result, champ: REF CircuitConstraint, p1, p2, p3, p4, p5, p6: REF CircuitConstraint ← NIL] ~ {
IF p1 # NIL THEN
champ.withConstraint ← CONS[ [p1, result], champ.withConstraint];
IF p2 # NIL THEN
champ.withConstraint ← CONS[ [p2, result], champ.withConstraint];
IF p3 # NIL THEN
champ.withConstraint ← CONS[ [p3, result], champ.withConstraint];
IF p4 # NIL THEN
champ.withConstraint ← CONS[ [p4, result], champ.withConstraint];
IF p5 # NIL THEN
champ.withConstraint ← CONS[ [p5, result], champ.withConstraint];
IF p6 # NIL THEN
champ.withConstraint ← CONS[ [p6, result], champ.withConstraint];
};
InitRules: PROCEDURE [cMosHandle: REF SpinifexCircuit.TechHandle] ~ {
Rule: TYPE ~ SpinifexCircuit.GeometricRule;
TrigMap: TYPE ~ PACKED ARRAY SpinifexCircuit.SpinifexConstraintIndex OF BOOLEANALL[FALSE];
spaceRuleTrig, widthRuleTrig, polOverDifTrig1, polDifSepTrig1, polDifSepTrig2, nDifSpaceTrig1A, nDifSpaceTrig1B, nDifSpaceTrig2, pDifSpaceTrig1A, pDifSpaceTrig1B, pDifSpaceTrig2, polWidTrig, nDifSepNWellTrig1, nDifSepNWellTrig2, nDifInWellDifTrig1, nDifAndPDifTrig1, pDifAndNDifTrig1, alwaysErrorTrig2, buriedTrig, nDifChannelTrig: TrigMap;
-- Geometric rule triggers.
spaceRuleTrig[SpinifexCircuit.nodeIndex] ← TRUE;
widthRuleTrig[SpinifexCircuit.spaceIndex] ← TRUE;
Corners are defined by union of dif and gate, but checking only looks at dif
nDifSpaceTrig1A[SpinifexCircuit.nodeIndex] ← TRUE;
nDifSpaceTrig1A[nDifChannel.index] ← TRUE;
nDifSpaceTrig1A[contactNDif.index] ← TRUE;
nDifSpaceTrig1B[excludeNDifByPWellCont.index] ← TRUE;
nDifSpaceTrig2[SpinifexCircuit.nodeIndex] ← TRUE;
nDifSpaceTrig2[contactNDif.index] ← TRUE;
nDifSpaceTrig2[excludeNDifByPWellCont.index] ← TRUE;
buriedTrig[buriedNDifPol.index] ← TRUE;
nDifChannelTrig[nDifChannel.index] ← TRUE;
Corners are defined by union of dif and gate, but checking only looks at dif
pDifSpaceTrig1A[SpinifexCircuit.nodeIndex] ← TRUE;
pDifSpaceTrig1A[pDifChannel.index] ← TRUE;
pDifSpaceTrig1A[contactPDif.index] ← TRUE;
pDifSpaceTrig1B[excludePDifByNWellCont.index] ← TRUE;
pDifSpaceTrig2[SpinifexCircuit.nodeIndex] ← TRUE;
pDifSpaceTrig2[contactPDif.index] ← TRUE;
pDifSpaceTrig2[excludePDifByNWellCont.index] ← TRUE;
nDifSepNWellTrig1[SpinifexCircuit.nodeIndex] ← TRUE;
nDifSepNWellTrig2[excludeNDifByWell.index] ← TRUE;
polWidTrig[SpinifexCircuit.spaceIndex] ← TRUE;
polWidTrig[2] ← TRUE;
polDifSepTrig1[ SpinifexCircuit.nodeIndex] ← TRUE;
polDifSepTrig2[ excludePolByNDif.index] ← TRUE;
Purely local errors are not handled in a natural manner by my scheme, so for every corner we find in polDifError we generate an error if there is anything on any layer nearby, of course there is always something so we get our error.
polOverDifTrig1[ polDifError.index] ← TRUE;
nDifInWellDifTrig1[ nDifInWellError.index] ← TRUE;
nDifAndPDifTrig1[ nDifAndPDifError.index] ← TRUE;
pDifAndNDifTrig1[ pDifAndNDifError.index] ← TRUE;
alwaysErrorTrig2 ← ALL[TRUE];
-- The geometric rules.
cMosHandle.rules[ ndifSpinifex] ← LIST[
NEW[ Rule ← [message~"n-Diffusion spacing", extent~3*l, okIfConnected~TRUE, trigger1~nDifSpaceTrig1A, trigger2~nDifSpaceTrig2]],
NEW[ Rule ← [message~"n-Diffusion/p-substrate-contact spacing", extent~3*l, okIfConnected~TRUE, trigger1~nDifSpaceTrig1B, trigger2~nDifSpaceTrig2]],
NEW[ Rule ← [message~"n-Diffusion width", extent~2*l, trigger1~widthRuleTrig, trigger2~widthRuleTrig]],
NEW[ Rule ← [message~"n-Diffusion/n-Well spacing", extent~nDifToWell, trigger1~nDifSepNWellTrig1, trigger2~nDifSepNWellTrig2]],
NEW[ Rule ← [message~"n-Well/n-Diffusion spacing", extent~nDifToWell, trigger1~nDifSepNWellTrig2, trigger2~nDifSepNWellTrig1]],
NEW[ Rule ← [message~"n-Diffusion in n-Well", extent~l, trigger1~nDifInWellDifTrig1, trigger2~alwaysErrorTrig2]],
NEW[ Rule ← [message~"n-Diffusion and p-substrate-contact", extent~l, trigger1~nDifAndPDifTrig1, trigger2~alwaysErrorTrig2]],
NEW[ Rule ← [message~"channel/buried-contact spacing", extent~3*l, trigger1~buriedTrig, trigger2~nDifChannelTrig]],
NEW[ Rule ← [message~"buried-contact/channel spacing", extent~3*l, trigger1~nDifChannelTrig, trigger2~buriedTrig]]
];
cMosHandle.rules[ pdifSpinifex] ← LIST[
NEW[ Rule ← [message~"p-Diffusion spacing", extent~3*l, okIfConnected~TRUE, trigger1~pDifSpaceTrig1A, trigger2~pDifSpaceTrig2]],
NEW[ Rule ← [message~"p-Diffusion/n-Well-contact spacing", extent~3*l, okIfConnected~TRUE, trigger1~pDifSpaceTrig1B, trigger2~pDifSpaceTrig2]],
NEW[ Rule ← [message~"p-Diffusion width", extent~2*l, trigger1~widthRuleTrig, trigger2~widthRuleTrig]],
NEW[ Rule ← [message~"p-Diffusion and n-Well-contact", extent~l, trigger1~pDifAndNDifTrig1, trigger2~alwaysErrorTrig2]]
];
cMosHandle.rules[ polSpinifex] ← LIST[
NEW[ Rule ← [message~"Poly spacing", extent~2*l, okIfConnected~TRUE, trigger1~spaceRuleTrig, trigger2~spaceRuleTrig]],
NEW[ Rule ← [message~"Poly width", extent~2*l, trigger1~polWidTrig, trigger2~polWidTrig]],
NEW[ Rule ← [message~"Poly/Diffusion spacing", extent~l, okIfConnected~TRUE, trigger1~polDifSepTrig1, trigger2~polDifSepTrig2]],
NEW[ Rule ← [message~"Diffusion/Poly spacing", extent~l, okIfConnected~TRUE, trigger1~polDifSepTrig2, trigger2~polDifSepTrig1]],
NEW[ Rule ← [message~"Poly over Diffusion", extent~l, trigger1~polOverDifTrig1, trigger2~alwaysErrorTrig2]]
];
cMosHandle.rules[ metSpinifex] ← LIST[
NEW[ Rule ← [message~"Metal spacing", extent~3*l, okIfConnected~TRUE, trigger1~spaceRuleTrig, trigger2~spaceRuleTrig]],
NEW[ Rule ← [message~"Metal width", extent~3*l, trigger1~widthRuleTrig, trigger2~widthRuleTrig]]
];
cMosHandle.rules[ m2Spinifex] ← LIST[
NEW[ Rule ← [message~"Metal 2 spacing", extent~4*l, okIfConnected~TRUE, trigger1~spaceRuleTrig, trigger2~spaceRuleTrig]],
NEW[ Rule ← [message~"Metal 2 width", extent~4*l, trigger1~widthRuleTrig, trigger2~widthRuleTrig]]
];
};
Init: PROCEDURE ~ {
ObjInit: PROCEDURE [objectType: ATOM, conv: SpinifexCircuit.ConversionProc, thyme: SpinifexOutput.LinkagePrintProc ← NIL, rose: SpinifexOutput.LinkagePrintProc ← NIL] ~ {
op: REF CD.ObjectProcs;
IF (op←CD.FetchObjectProcs[ objectType~objectType, technology~CMos.cmos]) = NIL THEN ERROR;
CDObjectProcs.StoreFurther[ p~op, key~SpinifexAtoms.spinifex, value~ NEW[SpinifexCircuit.ConversionProc𡤌onv]];
IF thyme # NIL THEN
CDObjectProcs.StoreFurther[ p~op, key~SpinifexAtoms.thymePrint, value~ NEW[SpinifexOutput.LinkagePrintProc←thyme]];
IF rose # NIL THEN
CDObjectProcs.StoreFurther[ p~op, key~SpinifexAtoms.rosePrint, value~ NEW[SpinifexOutput.LinkagePrintProc←rose]];
};
cMosHandle: REF SpinifexCircuit.TechHandle;
-- Layer Constraints.
nDifChannel ← NEW[ CircuitConstraint ← [ $NDifChannel, 2,,,TRUE, polSpinifex]];
nDifInWellError ← NEW[ CircuitConstraint ← [ $NDifInWellError, 3]];
excludeNDifByWell ← NEW[ CircuitConstraint ← [ $ExcludeNDifByWell, 4]];
contactNDif ← NEW[ CircuitConstraint ← [ $ContactNDif, 5,,,TRUE, ndifSpinifex]];
excludeNDifByPWellCont ← NEW[ CircuitConstraint ← [ $ExcludeNDifByPWellCont, 6,,,TRUE, pdifSpinifex]];
nDifAndPDifError ← NEW[ CircuitConstraint ← [ $NDifAndPDifError, 7]];
buriedNDifPol ← NEW[ CircuitConstraint ← [ $NDifAndPDifError, 8]];
excludeNDifByPWellCont.withNode ← nDifAndPDifError.withNode ← nDifAndPDifError;
excludeNDifByWell.withNode ← nDifInWellError.withNode ← nDifInWellError;
contactNDif.withNode ← contactNDif;
ConfResSetup[ nDifAndPDifError, nDifAndPDifError,
nDifChannel, nDifInWellError, excludeNDifByWell, contactNDif, excludeNDifByPWellCont, buriedNDifPol];
ConfResSetup[ nDifAndPDifError, excludeNDifByPWellCont,
nDifChannel, nDifInWellError, contactNDif, buriedNDifPol];
excludeNDifByPWellCont.withConstraint ← CONS[ [excludeNDifByWell, excludeNDifByPWellCont], excludeNDifByPWellCont.withConstraint];
ConfResSetup[ contactNDif, contactNDif, nDifChannel,
nDifInWellError, excludeNDifByWell];
ConfResSetup[ nDifInWellError, nDifChannel,
nDifInWellError, excludeNDifByWell];
ConfResSetup[ nDifInWellError, nDifInWellError,
excludeNDifByWell, buriedNDifPol];
buriedNDifPol.withNode ← buriedNDifPol;
buriedNDifPol.withConstraint ← CONS[ [excludeNDifByWell, nDifInWellError], buriedNDifPol.withConstraint];
ConfResSetup[ buriedNDifPol, buriedNDifPol, contactNDif, nDifChannel];
pDifChannel ← NEW[ CircuitConstraint ← [ $PDifChannel, 2,,,TRUE, polSpinifex]];
contactPDif ← NEW[ CircuitConstraint ← [ $ContactPDif, 5,,,TRUE, pdifSpinifex]];
pDifAndNDifError ← NEW[ CircuitConstraint ← [ $PDifAndNDifError, 3]];
excludePDifByNWellCont ← NEW[ CircuitConstraint ← [ $ExcludePDifByNWellCont, 4,,,TRUE, ndifSpinifex]];
contactPDif.withNode ← contactPDif;
excludePDifByNWellCont.withNode ← pDifAndNDifError.withNode ← pDifAndNDifError;
pDifChannel.withConstraint ← LIST[ [contactPDif, pDifChannel]];
ConfResSetup[ pDifAndNDifError, pDifChannel, pDifAndNDifError, excludePDifByNWellCont];
ConfResSetup[ pDifAndNDifError, contactPDif, pDifAndNDifError, excludePDifByNWellCont];
ConfResSetup[ pDifAndNDifError, pDifAndNDifError, excludePDifByNWellCont];
channelEdge ← NEW[ CircuitConstraint ← [ $ChannelEdge, SpinifexCircuit.spaceIndex]];
polXorDif ← NEW[ CircuitConstraint ← [ $PolXorDif, SpinifexCircuit.spaceIndex]];
polAndDif ← NEW[ CircuitConstraint ← [ $polAndDif, SpinifexCircuit.nodeIndex]];
excludePolByNDif ← NEW[ CircuitConstraint ← [ $ExcludePolByNDif, 2,,,TRUE, ndifSpinifex]];
excludePolByPDif ← NEW[ CircuitConstraint ← [ $ExcludePolByPDif, 2,,,TRUE, pdifSpinifex]];
polDifError ← NEW[ CircuitConstraint ← [ $PolDifError, 3]];
excludePolByNDif.withNode ← channelEdge.withNode ← polDifError.withNode ← polDifError;
excludePolByPDif.withNode ← channelEdge.withNode ← polDifError.withNode ← polDifError;
ConfResSetup[ channelEdge, channelEdge,
excludePolByNDif, excludePolByPDif, polXorDif];
ConfResSetup[ polDifError, polDifError,
excludePolByNDif, excludePolByPDif, channelEdge];
ConfResSetup[ channelEdge, polXorDif,
excludePolByNDif, excludePolByPDif];
polAndDif.withNode ← polAndDif;
ConfResSetup[ polAndDif, polAndDif,
excludePolByNDif, excludePolByPDif, polXorDif, polDifError, channelEdge];
excludePolByNDif.withConstraint ← LIST[ [excludePolByPDif, excludePolByNDif]]; -- This is always an error, but the handling for it is on the pDifLayer & nDifLayer.
-- Basic cMosHandle & cdLayerMappings.
cMosHandle ← NEW[SpinifexCircuit.TechHandle ← [
errorLevel~CD.highLightError,
numSpinifexLayers~6,
layerInterestBloat~[nDifLayerSep, difSep, polSep, metSep, m2Sep, l,,],
CombineNodeProperties~CopyWellConnections,
CellPostProcess~CheckWellConnections]
];
cMosHandle.illegalLevel[CMos.nwelCont] ← FALSE;
cMosHandle.illegalLevel[CMos.pwelCont] ← FALSE;
cMosHandle.illegalLevel[CMos.ndif] ← FALSE;
cMosHandle.illegalLevel[CMos.pdif] ← FALSE;
cMosHandle.illegalLevel[CMos.nwel] ← FALSE;
cMosHandle.illegalLevel[CMos.pol] ← FALSE;
cMosHandle.illegalLevel[CMos.met] ← FALSE;
cMosHandle.illegalLevel[CMos.met2] ← FALSE;
cMosHandle.cdLayerMapping[CMos.nwelCont] ← LIST[ [ndifSpinifex, difSep], [wellSpinifex, l, NEW[ SpinifexCircuit.BoxMapProc ← AttachNWellContact]], [pdifSpinifex, difSep, excludePDifByNWellCont], [ndifSpinifex, difSep, contactNDif], [polSpinifex, difToPolExtSep, excludePolByNDif]]; -- Order Important for well plugging, node is created in first mapping, and used in second.
cMosHandle.cdLayerMapping[CMos.pwelCont] ← LIST[ [pdifSpinifex, difSep], [ndifSpinifex, difSep, excludeNDifByPWellCont], [pdifSpinifex, difSep, contactPDif], [polSpinifex, difToPolExtSep, excludePolByPDif]];
cMosHandle.cdLayerMapping[CMos.ndif] ← LIST[ [ndifSpinifex, difSep], [polSpinifex, difToPolExtSep, excludePolByNDif]];
cMosHandle.cdLayerMapping[CMos.pdif] ← LIST[ [pdifSpinifex, difSep], [polSpinifex, difToPolExtSep, excludePolByPDif]];
cMosHandle.cdLayerMapping[CMos.nwel] ← LIST[ [ndifSpinifex, nDifToWell-difSep, excludeNDifByWell], [wellSpinifex, l]]; -- INTERIM
cMosHandle.cdLayerMapping[CMos.pol] ← LIST[ [polSpinifex, polSep]];
cMosHandle.cdLayerMapping[CMos.met] ← LIST[ [metSpinifex, metSep]];
cMosHandle.cdLayerMapping[CMos.met2] ← LIST[ [m2Spinifex, m2Sep]];
CDProperties.PutPropOnTechnology[onto~ CMos.cmos, prop~SpinifexAtoms.spinifex, val~cMosHandle];
-- Thyme stray capacitance layer names.
cMosHandle.spinifexLayerNames[ndifSpinifex].thymeName ← "nD";
cMosHandle.spinifexLayerNames[pdifSpinifex].thymeName ← "pD";
cMosHandle.spinifexLayerNames[polSpinifex].thymeName ← "P";
cMosHandle.spinifexLayerNames[metSpinifex].thymeName ← "M";
cMosHandle.spinifexLayerNames[m2Spinifex].thymeName ← "M2";
-- The geometric rules.
InitRules[cMosHandle];
-- Technology specific objects.
CDObjectProcs.RegisterFurther[key~SpinifexAtoms.spinifex, technology~CMos.cmos ! CD.Error => IF ec = doubleRegistration THEN CONTINUE];
CDObjectProcs.RegisterFurther[key~SpinifexAtoms.thymePrint, technology~CMos.cmos ! CD.Error => IF ec = doubleRegistration THEN CONTINUE];
CDObjectProcs.RegisterFurther[key~SpinifexAtoms.rosePrint, technology~CMos.cmos ! CD.Error => IF ec = doubleRegistration THEN CONTINUE];
ObjInit[ objectType~$CMosTransistor, conv~ConvTransistor, thyme~ThymeTransistor, rose~RoseTransistor];
ObjInit[ objectType~$CMosPTypeTransistor, conv~ConvTransistor, thyme~ThymeTransistor, rose~RoseTransistor];
ObjInit[ objectType~$CMosATransistor, conv~ConvTransistor, thyme~ThymeTransistor, rose~RoseTransistor];
ObjInit[ objectType~$CMosPTypeATransistor, conv~ConvTransistor, thyme~ThymeTransistor, rose~RoseTransistor];
ObjInit[ objectType~$CMosPDifRect, conv~ConvertPDifRect];
InitContacts[];
ObjInit[ objectType~$CMosContactDifAndPol, conv~ConvertContact];
ObjInit[ objectType~$CMosContactWellDifAndPol, conv~ConvertContact];
ObjInit[ objectType~$CMosContactBut, conv~ConvertContact];
ObjInit[ objectType~$CMosContactWellBut, conv~ConvertContact];
ObjInit[ objectType~$CMosBurContact, conv~ConvertContact];
ObjInit[ objectType~$CMosWellBurContact, conv~ConvertContact];
ObjInit[ objectType~$CMosMmContact, conv~ConvertContact];
};
Init[];
TerminalIO.WriteRope["cMos technology parameters Loaded\n"];
END.