DIRECTORY CD USING [Instance, InstanceRep, Layer, Number, Position, Rect], CDBasics, CDProperties USING [GetInstanceProp], CDSimpleRules USING [MinDist, MinWidth], IO USING [char, int, Put, PutF, PutRope, rope], NMos USING [lambda, nmos, dif, pol, met, ovg, cut], NMosContacts USING [ContactPtr], NMosTransistors USING [enhancement, strongDepletion, TransistorPtr, weakDepletion, zeroTresh], Rope USING [Cat, ROPE], SX USING [AddBox, AddRect, AdjustNode, AttachedNode, Circuit, CircuitNode, Constraint, ConstraintArray, ConstraintIndex, ConstraintResolution, ConversionProc, CreateLinkage, GeometricRule, IllegalConstruct, LinkageAttach, MapRec, MergeNode, nodeIndex, NodeLinkage, spaceIndex, SpinifexLayerIndex, techCIndexBase, TechHandle, violateIndex], SXOutput USING [LinkageHousekeeper, LinkagePrintProc], SXOutputPrivate USING [GetANaming, NameTransType, Naming, PrintNaming, PrintRoseInstantiationTransformation, UnNameTransType], SXQuadTree USING [RectDelta], SXTechnology USING [ESWGrow, NESGrow, PerDrawRectProc, ProcessMosTransistor, RegisterSpinifexObjectProcs, RegisterTechnologyHandle, ReportDifProc, ResolutionTable, SetUpResolution, SWNGrow, WNEGrow], TerminalIO USING [PutRope]; SXNMos: CEDAR PROGRAM IMPORTS CDBasics, CDProperties, CDSimpleRules, IO, NMos, Rope, SX, SXOutputPrivate, SXTechnology, TerminalIO = BEGIN l: CD.Number ~ NMos.lambda; polOverDif: CD.Number = NMos.lambda; difToPolExtSep: CD.Number = 0; polSep: CD.Number = NMos.lambda; difToPolSep: CD.Number = difToPolExtSep + polSep; -- not halved! contactWidth: CD.Number = 4 * NMos.lambda; ConvertNMosTransistor: SX.ConversionProc ~ { p: NMosTransistors.TransistorPtr = NARROW[ob.specific]; size: CD.Position _ CDBasics.SizeOfRect[ob.bbox]; xstr: REF SX.NodeLinkage; gateNode, sourceNode, drainNode, metNode: REF SX.CircuitNode; polExt: CD.Number ~ IF p.pullup THEN MIN[ (size.x-contactWidth)/2, p.wExt] ELSE p.wExt; IF ~ p.angle THEN { -- Oh this is easy! gateNode _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[0, p.lExt, polExt, p.lExt+p.length], trans~trans, interestBloat~SXTechnology.SWNGrow[(CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2)]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt, size.x-polExt, p.lExt+p.length], trans~trans, value~gateNode]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[size.x-polExt, p.lExt, size.x, p.lExt+p.length], trans~trans, interestBloat~SXTechnology.NESGrow[(CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2)], value~gateNode]; IF p.lExt-difToPolSep > 0 THEN { [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt+p.length+difToPolSep, size.x-polExt, size.y], trans~trans, interestBloat~SXTechnology.WNEGrow[difToPolExtSep], value~pCnstr[pExcl]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[p.wExt, 0, size.x-p.wExt, p.lExt-difToPolSep], trans~trans, interestBloat~SXTechnology.ESWGrow[difToPolExtSep], value~pCnstr[pExcl]] }; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt+p.length, size.x-polExt, p.lExt+p.length+difToPolSep], trans~trans, value~pCnstr[pChE]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[p.wExt, p.lExt-difToPolSep, size.x-p.wExt, p.lExt], trans~trans, value~pCnstr[pChE]]; [] _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[p.wExt, p.lExt, size.x-p.wExt, p.lExt+p.length], trans~trans, interestBloat~[dx1~ (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), dy1~ 0, dx2~ (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), dy2~ 0], value~dCnstr[dCh]]; IF polExt < p.wExt THEN [] _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[polExt, p.lExt+p.length-l, size.x-polExt, p.lExt+p.length], trans~trans, interestBloat~[dx1~ (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), dy1~ 0, dx2~ (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), dy2~ (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)], value~dCnstr[dCh]]; sourceNode _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[polExt, p.lExt+p.length, size.x-polExt, size.y], trans~trans, interestBloat~SXTechnology.WNEGrow[(CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)]]; drainNode _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[p.wExt, 0, size.x-p.wExt, p.lExt], trans~trans, interestBloat~SXTechnology.ESWGrow[(CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)]]; IF p.pullup THEN { metNode _ cir.AddRect [lev~NMos.met, dim~[(size.x-contactWidth)/2, size.y-6*l, (size.x+contactWidth)/2, size.y], trans~trans]; } ELSE metNode _ NIL } ELSE { -- Oh no not a bent transistor yetcchh! sourceDrainList: LIST OF REF SX.CircuitNode; sourceDrainCount: INTEGER; sourceHint: REF SX.CircuitNode _ NIL; NoteSourceHint: SXTechnology.ReportDifProc ~ { sourceHint _ difNode }; [gateNode, sourceDrainList, sourceDrainCount] _ SXTechnology.ProcessMosTransistor[ob, trans, cir, difSpinifex, polSpinifex, dCnstr[dCh], pCnstr[pChE], (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), difToPolSep, MapMaterial, cir, NoteSourceHint]; IF sourceDrainCount = 2 THEN { sourceNode _ sourceDrainList.first; drainNode _ sourceDrainList.rest.first; IF p.pullup THEN { SELECT sourceHint FROM sourceNode => NULL; drainNode => { drainNode _ sourceNode; sourceNode _ sourceHint }; ENDCASE => ERROR -- Including case when sourceHint = NIL } } ELSE { TerminalIO.PutRope[ Rope.Cat["Xstr with ", (SELECT sourceDrainCount FROM 0 => "no", 1 => "only 1", ENDCASE => "more than 2"), " sources/drains not included in circuit description\n"]]; RETURN } }; xstr _ cir.CreateLinkage[NEW[CD.InstanceRep_[ob: ob]], p.length, p.width]; SX.AdjustNode[ gateNode, polSpinifex, size.y*p.length, (size.y+p.length)*2, absolute]; SX.AdjustNode[ sourceNode, difSpinifex, (size.y-(p.lExt+p.length))*(size.x-2*polExt), (size.y-(p.lExt+p.length))*2 + size.x-2*polExt, absolute]; -- Ignore perim leading into channel. SX.AdjustNode[ drainNode, difSpinifex, p.lExt*p.width, 2*p.lExt + p.width, absolute]; -- Ignore perim leading into channel. IF p.pullup THEN { cir.MergeNode[ gateNode, sourceNode]; sourceNode _ gateNode; cir.MergeNode[ gateNode, metNode]; metNode _ gateNode; }; SX.LinkageAttach[link~xstr, attachType~$Gate, node~gateNode]; SX.LinkageAttach[link~xstr, attachType~$Source, node~sourceNode]; SX.LinkageAttach[link~xstr, attachType~$Drain, node~drainNode]; }; MapMaterial: SXTechnology.PerDrawRectProc ~ { cir: REF SX.Circuit ~ NARROW [data, REF SX.Circuit]; SELECT l FROM NMos.dif => RETURN [diffusion]; NMos.pol => RETURN [polysilicon]; NMos.met => { [] _ cir.AddRect[ lev~ NMos.met, dim~ r]; RETURN [nothing]; }; NMos.cut => { RETURN [postProcess]; }; ENDCASE => RETURN [nothing]; }; ConvertNMosContactDifAndPol: SX.ConversionProc ~ { box: CD.Rect _ ob.bbox; node: REF SX.CircuitNode; node _ cir.AddRect[ lev~NMos.met, dim~box, trans~trans]; [] _ cir.AddRect[ lev~ob.layer, dim~box, trans~trans, value~node]; IF ob.layer = NMos.dif THEN [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~box, trans~trans, value~pCnstr[pExCon]]; }; ConvertNMosMmContact: SX.ConversionProc ~ { s: CD.Position = CDBasics.SizeOfRect[ob.bbox]; [] _ cir.AddBox [ spinifexLayer: metSpinifex, dim: [l/2, l/2, s.x-l/2, s.y-l/2], -- cut bloated by 1/2 lambda trans: trans, value: mCnstr[mCutEx]]; [] _ cir.AddBox [ spinifexLayer: metSpinifex, dim: [l, l, s.x-l, s.y-l], -- cut unbloated trans: trans, value: mCnstr[mCut]];}; ConvertNMosButtingContact: SX.ConversionProc ~ { rimWidth: CD.Number ~ l; box: CD.Rect _ ob.bbox; size: CD.Position _ CDBasics.SizeOfRect[box]; polSize: CD.Number ~ size.y/2; node: REF SX.CircuitNode; node _ cir.AddRect[ lev~NMos.met, dim~box, trans~trans]; [] _ cir.AddRect[ lev~NMos.pol, dim~[0,0, size.x, polSize], trans~trans, value~node]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[-rimWidth,polSize, size.x+rimWidth, polSize+difToPolSep], trans~trans, value~pCnstr[pChE]]; [] _ cir.AddBox [spinifexLayer~polSpinifex, dim~[-rimWidth,polSize-rimWidth, 0, polSize], trans~trans, value~pCnstr[pDxorP]]; [] _ cir.AddBox [spinifexLayer~polSpinifex, dim~[size.x,polSize-rimWidth, size.x+rimWidth, polSize], trans~trans, value~pCnstr[pDxorP]]; [] _ cir.AddBox [spinifexLayer~polSpinifex, dim~[0,polSize+difToPolSep, size.x, size.y], trans~trans, interestBloat~SXTechnology.WNEGrow[difToPolExtSep], value~pCnstr[pExCon]]; [] _ cir.AddBox [spinifexLayer~difSpinifex, dim~[0,polSize, size.x, size.y], trans~trans, interestBloat~[(CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)], value~node]; }; ConvertNMosBuriedContact: SX.ConversionProc ~ { s: CD.Position ~ CDBasics.SizeOfRect[ob.bbox]; cp: NMosContacts.ContactPtr ~ NARROW[ob.specific]; node: REF SX.CircuitNode ~ cir.AddRect[ lev~NMos.pol, dim~[2*l, cp.lExt, s.x-cp.wExt, s.y-cp.lExt], trans~trans]; [] _ cir.AddBox [ spinifexLayer: metSpinifex, dim: [l/2, l/2, s.x-l/2, s.y-l/2], -- actual dimensions of cut trans: trans, value: mCnstr[mBCCut]]; [] _ cir.AddBox [ spinifexLayer: metSpinifex, dim: [-l/2, -l/2, s.x+l/2, s.y+l/2], -- cut bloated by 1 lambda trans: trans, value: mCnstr[mBCEx]]; SELECT TRUE FROM cp.lExt < 2*l AND cp.wExt < 2*l => { wex: CD.Number ~ MAX[cp.wExt+l, 2*l]; lex: CD.Number ~ MAX[cp.lExt+l, 2*l]; bcExclConstraint: SX.Constraint _ pCnstr[pBCExcl]^; bcExclConstraint.specificCorrespondingNode _ node; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [-l/2, -l/2, 0, s.y+l/2], -- buried contact poly exclude (left side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddRect [ lev: ob.layer, dim: [l, lex, 2*l, s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-difToPolSep, lex, 2*l, s.y-lex], trans: trans, value: pCnstr[pChE]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, lex, s.x-wex, s.y-lex], trans: trans, value: pCnstr[pDandP]]; [] _ cir.AddBox [ spinifexLayer: difSpinifex, dim: [2*l, lex, s.x-wex, s.y-lex], trans: trans, value: node]; }; cp.lExt < 2*l AND cp.wExt >= 2*l => { lex: CD.Number ~ MAX[cp.lExt+l, 2*l]; bcExclConstraint: SX.Constraint _ pCnstr[pBCExcl]^; bcExclConstraint.specificCorrespondingNode _ node; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [s.x, -l/2, s.x+l/2, s.y+l/2], -- buried contact poly exclude (right side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [-l/2, -l/2, 0, s.y+l/2], -- buried contact poly exclude (left side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddBox [ spinifexLayer: difSpinifex, dim: [2*l, lex, s.x-cp.wExt, s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, lex, s.x-cp.wExt, s.y-lex], trans: trans, value: pCnstr[pDandP]]; [] _ cir.AddRect [lev: ob.layer, dim: [l, lex, 2*l, s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-difToPolSep, lex, 2*l, s.y-lex], trans: trans, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: ob.layer, dim: [s.x-cp.wExt, lex, s.x-(cp.wExt-l), s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [s.x-cp.wExt, lex, s.x-(cp.wExt-difToPolSep), s.y-lex], trans: trans, value: pCnstr[pChE]]; }; cp.lExt >= 2*l AND cp.wExt < 2*l => { wex: CD.Number ~ MAX[cp.wExt+l, 2*l]; lex: CD.Number ~ cp.lExt-l; bcExclConstraint: SX.Constraint _ pCnstr[pBCExcl]^; bcExclConstraint.specificCorrespondingNode _ node; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [-l/2, -l/2, l/2, s.y+l/2], -- buried contact poly exclude (left side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [l/2, s.y, s.x+l/2, s.y+l/2], -- buried contact poly exclude (top side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [l/2, -l/2, s.x, 0], -- buried contact poly exclude (bottom side) trans: trans, value: NEW[Constraint _ bcExclConstraint]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, cp.lExt, s.x-wex, s.y-cp.lExt], trans: trans, value: pCnstr[pDandP]]; [] _ cir.AddRect [ lev: ob.layer, dim: [l, lex, s.x-wex, s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-difToPolSep, lex, 2*l, s.y-lex], trans: trans, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: ob.layer, dim: [2*l, s.y-cp.lExt, s.x-wex, s.y-lex], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, s.y-cp.lExt, s.x-wex, s.y-(cp.lExt-difToPolSep)], trans: trans, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: ob.layer, dim: [2*l, lex, s.x-wex, cp.lExt], trans: trans, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, cp.lExt-difToPolSep, s.x-wex, cp.lExt], trans: trans, value: pCnstr[pChE]]; }; cp.lExt >= 2*l AND cp.wExt >= 2*l => { ERROR SX.IllegalConstruct [ob.class.interestRect[ob], "Polysilicon surrounded by diffusion or all sides in Buried Contact"]; }; ENDCASE => ERROR; }; RoseNMosTransistor: SXOutput.LinkagePrintProc ~ { PrintAttachment: PROCEDURE [key: ATOM, portName: Rope.ROPE] ~ { cellStream.Put[ IO.rope[" (\""], IO.rope[portName], IO.rope["\" "]]; FOR attachments: LIST OF REF SX.AttachedNode _ linkage.nodes, attachments.rest WHILE attachments # NIL DO IF attachments.first.attachmentType = key THEN { PrintNode[cellStream, attachments.first.node]; cellStream.PutRope[")"]; RETURN } ENDLOOP; cellStream.PutRope[ "\"?\")"]; }; p: NMosTransistors.TransistorPtr ~ NARROW [linkage.source.ob.specific]; naming: SXOutputPrivate.Naming _ SXOutputPrivate.GetANaming [linkage.source]; cellStream.PutRope ["(CI "]; SXOutputPrivate.PrintNaming [ cellStream, naming, Rope.Cat[" \"", SXOutputPrivate.NameTransType [ desWDir: desWDir, obj: linkage.source.ob, dfStream: dfStream, type: $n, mode: IF p.pullup THEN $D ELSE SELECT p.implant FROM NMosTransistors.enhancement => $E, NMosTransistors.strongDepletion => $D, NMosTransistors.zeroTresh => $Z, NMosTransistors.weakDepletion => $W, ENDCASE => ERROR, length: p.length, width: p.width], "\""]]; SXOutputPrivate.PrintRoseInstantiationTransformation [cellStream, linkage.source]; cellStream.PutRope [" (CIC"]; PrintAttachment [$Gate, "gate"]; PrintAttachment [$Source, "in"]; PrintAttachment [$Drain, "out"]; cellStream.PutRope ["))"] }; ThymeNMosTransistor: SXOutput.LinkagePrintProc ~ { PrintAttachment: PROCEDURE [ key: ATOM] ~ { FOR attachments: LIST OF REF SX.AttachedNode _ linkage.nodes, attachments.rest WHILE attachments # NIL DO IF attachments.first.attachmentType = key THEN { PrintNode [cellStream, attachments.first.node]; RETURN } ENDLOOP; cellStream.Put[IO.char['?]]; }; p: NMosTransistors.TransistorPtr ~ NARROW [linkage.source.ob.specific]; defaultL: INTEGER ~ 2*l; propertyValue: REF; cellStream.Put [IO.rope[name], IO.rope[": "]]; cellStream.PutRope [IF ~p.pullup THEN SELECT p.implant FROM NMosTransistors.enhancement => "ETran[", NMosTransistors.strongDepletion => "DTran[", NMosTransistors.zeroTresh => "ZTran[", NMosTransistors.weakDepletion => "WTran", ENDCASE => ERROR ELSE "DTran [" ]; PrintAttachment [$Gate]; cellStream.Put [IO.char[',]]; PrintAttachment [$Source]; cellStream.Put [IO.char[',]]; PrintAttachment [$Drain]; cellStream.Put [IO.char['|]]; cellStream.PutF [" W_N*%g", IO.int[p.width/l]]; IF p.length # defaultL THEN cellStream.PutF [", L_%g", IO.int[p.length/l]]; propertyValue _ CDProperties.GetInstanceProp [from: linkage.source, prop: $Crystal]; WITH propertyValue SELECT FROM crystalHack: Rope.ROPE => IO.Put [stream: cellStream, v1: IO.rope["; "], v2: IO.rope[crystalHack]]; ENDCASE => IF propertyValue # NIL THEN TerminalIO.PutRope [" $Crystal property must be a rope. /n"]; cellStream.PutRope ["];"] }; nMosHandle: REF SX.TechHandle; difSpinifex: SX.SpinifexLayerIndex ~ SX.SpinifexLayerIndex.FIRST; polSpinifex: SX.SpinifexLayerIndex ~ difSpinifex.SUCC; metSpinifex: SX.SpinifexLayerIndex ~ polSpinifex.SUCC; Constraint: TYPE ~ SX.Constraint; dCnstr: REF SX.ConstraintArray _ NEW[SX.ConstraintArray]; -- Diffusion constraints dCh: SX.ConstraintIndex ~ SX.techCIndexBase; -- Diffusion channel pCnstr: REF SX.ConstraintArray _ NEW[SX.ConstraintArray]; -- Poly constraints pExcl: SX.ConstraintIndex ~ SX.techCIndexBase; -- Poly not allowed here. pExCon: SX.ConstraintIndex ~ pExcl.SUCC; -- Poly not allowed here because of Contact to n-Diffusion. pDPErr: SX.ConstraintIndex ~ pExCon.SUCC; -- Poly and Diffusion found together here. pChE: SX.ConstraintIndex ~ pDPErr.SUCC; -- Close to Xstr Gate, (Channel Edge). pDxorP: SX.ConstraintIndex ~ pChE.SUCC; -- Diffusion XOR Poly allowed here. pDandP: SX.ConstraintIndex ~ pDxorP.SUCC; -- Diffusion AND Poly may appear together here. pBCExcl: SX.ConstraintIndex = pDandP.SUCC; -- Buried Contact Cut Exclusion pBCErr: SX.ConstraintIndex = pBCExcl.SUCC; -- Buried Contact Cut Separation violation mCnstr: REF SX.ConstraintArray _ NEW[SX.ConstraintArray]; -- metal constraints mBCEx: SX.ConstraintIndex = SX.techCIndexBase; -- Buried Contact Cut Bloated mBCErr: SX.ConstraintIndex = mBCEx.SUCC; -- Buried Contact Cut Separation violation mBCCut: SX.ConstraintIndex = mBCErr.SUCC; -- Buried Contact Cut Unbloated mCutEx: SX.ConstraintIndex = mBCCut.SUCC; -- Metal Contact Cut Bloated mCut: SX.ConstraintIndex = mCutEx.SUCC; -- Metal Contact Cut Unbloated mBCExM: SX.ConstraintIndex = mCut.SUCC; -- Buried Contact Cut Bloated over metal mBCErrM: SX.ConstraintIndex = mBCExM.SUCC; -- Buried Contact Cut Separation violation over metal mBCCutM: SX.ConstraintIndex = mBCErrM.SUCC; -- Buried Contact Cut Unbloated over metal mCutExM: SX.ConstraintIndex = mBCCutM.SUCC; -- Metal Contact Cut Bloated over metal mCutM: SX.ConstraintIndex = mCutExM.SUCC; -- Metal Contact Cut Unbloated over metal Init: PROCEDURE ~ { GeometricRule: TYPE ~ SX.GeometricRule; difSpacingRule, difWidthRule: REF GeometricRule; polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule, polBuriedSpacingRuleA, polBuriedSpacingRuleB: REF GeometricRule; metSpacingRule, metWidthRule, bcCutSpacingRule, bcMetalCutSpacingRuleA, bcMetalCutSpacingRuleB: REF GeometricRule; detectOpaqueViolation: REF GeometricRule; TriggerMap: TYPE ~ PACKED ARRAY SX.ConstraintIndex OF BOOLEAN _ ALL[FALSE]; spaceRuleTrigger: TriggerMap; widthRuleTrigger: TriggerMap; polOverDifTrigger1, polOverDifTrigger2, polDifSepTriggerA, polDifSepTriggerB: TriggerMap; difSpaceTrigger1: TriggerMap; polWidthTrigger: TriggerMap; polBuriedSpaceTriggerA, polBuriedSpaceTriggerB, polSpaceTrigger, metSpaceTrigger, metWidthTrigger: TriggerMap; bcSpaceTrigger, bcMetalCutSpacingTriggerA, bcMetalCutSpacingTriggerB: TriggerMap; difResolution: REF SX.ConstraintResolution; polyResolution: REF SX.ConstraintResolution; metResolution: REF SX.ConstraintResolution; dCnstr[dCh] _ NEW[ Constraint _ [ $DifChannel, dCh]]; pCnstr[pExcl] _ NEW[ Constraint _ [ $ExcludePol, pExcl]]; pCnstr[pExCon] _ NEW[ Constraint _ [ $ExcludePolByContact, pExCon]]; pCnstr[pDPErr] _ NEW[ Constraint _ [ $PolDifError, pDPErr]]; pCnstr[pChE] _ NEW[ Constraint _ [ $ChannelEdge, pChE]]; pCnstr[pDxorP]_ NEW[ Constraint _ [ $PolXorDif, pDxorP]]; pCnstr[pDandP] _ NEW[ Constraint _ [ $PolAndDif, pDandP, TRUE, polSpinifex]]; pCnstr[pBCExcl] _ NEW[ Constraint _ [ $PolyBCExcl, pBCExcl, TRUE]]; pCnstr[pBCErr] _ NEW[ Constraint _ [ $PolyBCErr, pBCErr, TRUE]]; mCnstr[mBCEx] _ NEW[ Constraint _ [ $BCExclCut, mBCEx]]; mCnstr[mBCErr] _ NEW[ Constraint _ [ $BCErr, mBCErr]]; mCnstr[mBCCut] _ NEW[ Constraint _ [ $BCCut, mBCCut]]; mCnstr[mCutEx] _ NEW[ Constraint _ [ $CutExcl, mCutEx]]; mCnstr[mCut] _ NEW[ Constraint _ [ $Cut, mCut]]; mCnstr[mBCExM] _ NEW[ Constraint _ [ $BCExclCutM, mBCExM]]; mCnstr[mBCErrM] _ NEW[ Constraint _ [ $BCErrM, mBCErrM]]; mCnstr[mBCCutM] _ NEW[ Constraint _ [ $BCCutM, mBCCutM]]; mCnstr[mCutExM] _ NEW[ Constraint _ [ $CutExclM, mCutExM]]; mCnstr[mCutM] _ NEW[ Constraint _ [ $CutM, mCutM]]; { nd: SX.ConstraintIndex ~ SX.nodeIndex; sp: SX.ConstraintIndex ~ SX.spaceIndex; dResTab: SXTechnology.ResolutionTable ~ [ [ sp, nd, dCh, ,,,,,,,,,,,,], [ nd, nd, dCh, ,,,,,,,,,,,,], [ dCh, dCh, dCh, ,,,,,,,,,,,,], ,,,,,,,,,,,, ]; pResTab: SXTechnology.ResolutionTable = [ [ sp, nd, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCExcl, pBCErr, ,,,,,], [ nd, nd, pDPErr, pDPErr, pDPErr, pDPErr, nd, pDandP, pBCErr, pBCErr, ,,,,,], [ pExcl, pDPErr, pExcl, pExCon, pDPErr, pChE, pChE, pDandP, pExcl, pExcl, ,,,,,], [ pExCon, pDPErr, pExCon, pExCon, pDPErr, pExCon, pExCon, pDandP, pExCon, pExCon, ,,,,,], [ pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDandP, pDPErr, pDPErr, ,,,,,], [ pChE, pDPErr, pChE, pExCon, pDPErr, pChE, pChE, pDandP, pChE, pChE, ,,,,,], [ pDxorP, nd, pChE, pExCon, pDPErr, pChE, pDxorP, pDandP, pDxorP, pDxorP, ,,,,,], [ pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, ,,,,,], [ pBCExcl, pBCErr, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCExcl, pBCErr, ,,,,,], [ pBCErr, pBCErr, pExcl, pExCon, pDPErr, pChE, pDxorP, pDandP, pBCErr, pBCErr, ,,,,,], ,,,,, ]; mResTab: SXTechnology.ResolutionTable = [ [ sp, nd, mBCEx, mBCErr, mBCCut, mCutEx, mCut, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,], [ nd, nd, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM, mBCExM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,], [ mBCEx, mBCExM, mBCErr, mBCErr, mBCCut, mBCErr, mCut, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,], [ mBCErr, mBCErrM, mBCErr, mBCErr, mBCCut, mBCErr, mCut, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,], [ mBCCut, mBCCutM, mBCCut, mBCCut, mBCCut, mBCCut, mCut, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM,,,,], [ mCutEx, mCutExM, mBCErr, mBCErr, mBCCut, mCutEx, mCut, mBCErrM, mBCErrM, mBCCutM, mCutExM, mCutM,,,,], [ mCut, mCutM, mCut, mCut, mCut, mCut, mCut, mCutM, mCutM, mCutM, mCutM, mCutM,,,,], [ mBCExM, mBCExM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,], [ mBCErrM, mBCErrM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCErrM, mCutM,,,,], [ mBCCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM, mBCCutM, mBCCutM, mBCCutM, mBCCutM, mCutM,,,,], [ mCutExM, mCutExM, mBCErrM, mBCErrM, mBCCutM, mCutExM, mCutM, mBCErrM, mBCErrM, mBCCutM, mBCExM, mCutM,,,,], [ mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM, mCutM,,,,], ,,, ]; difResolution _ SXTechnology.SetUpResolution[ dCnstr, dResTab]; polyResolution _ SXTechnology.SetUpResolution[ pCnstr, pResTab]; metResolution _ SXTechnology.SetUpResolution[ mCnstr, mResTab]; }; nMosHandle _ NEW[SX.TechHandle _ [numSpinifexLayers~3, layerInterestBloat~[(CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2), (CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2), (CDSimpleRules.MinDist[NMos.met, NMos.met]/2), ,,,,]] ]; nMosHandle.illegalLayer[NMos.dif] _ FALSE; nMosHandle.illegalLayer[NMos.pol] _ FALSE; nMosHandle.illegalLayer[NMos.met] _ FALSE; nMosHandle.illegalLayer[NMos.ovg] _ FALSE; nMosHandle.cdLayerMapping[NMos.dif] _ LIST[ [difSpinifex, (CDSimpleRules.MinDist[NMos.dif, NMos.dif]/2)], [polSpinifex,difToPolExtSep,pCnstr[pExcl]]]; nMosHandle.cdLayerMapping[NMos.pol] _ LIST[ [polSpinifex,(CDSimpleRules.MinDist[NMos.pol, NMos.pol]/2)]]; nMosHandle.cdLayerMapping[NMos.met] _ LIST[ [metSpinifex,(CDSimpleRules.MinDist[NMos.met, NMos.met]/2)]]; nMosHandle.spinifexLayerNames[difSpinifex].layerId _ $Diffusion; nMosHandle.spinifexLayerNames[polSpinifex].layerId _ $Poly; nMosHandle.spinifexLayerNames[metSpinifex].layerId _ $Metal; nMosHandle.spinifexLayerNames[difSpinifex].thymeName _ "D"; nMosHandle.spinifexLayerNames[polSpinifex].thymeName _ "P"; nMosHandle.spinifexLayerNames[metSpinifex].thymeName _ "M"; nMosHandle.constraintResolutions[difSpinifex] _ difResolution; nMosHandle.constraintResolutions[polSpinifex] _ polyResolution; nMosHandle.constraintResolutions[metSpinifex] _ metResolution; spaceRuleTrigger[SX.nodeIndex] _ TRUE; widthRuleTrigger[SX.spaceIndex] _ TRUE; difSpaceTrigger1[SX.nodeIndex] _ TRUE; difSpaceTrigger1[dCh] _ TRUE; polWidthTrigger _ ALL[TRUE]; polWidthTrigger[ SX.nodeIndex] _ FALSE; polWidthTrigger [pDandP] _ FALSE; -- newly added by gbb polWidthTrigger[pBCErr] _ FALSE; -- added by Bowers polDifSepTriggerA[ SX.nodeIndex] _ TRUE; polDifSepTriggerB[ pExcl] _ TRUE; polDifSepTriggerB[ pExCon] _ TRUE; polOverDifTrigger1[ pDPErr] _ TRUE; polOverDifTrigger2 _ ALL[TRUE]; bcSpaceTrigger[mBCCut] _ TRUE; bcMetalCutSpacingTriggerA[mCut] _ TRUE; bcMetalCutSpacingTriggerB[mBCCut] _ TRUE; polBuriedSpaceTriggerA[pBCErr] _ TRUE; polBuriedSpaceTriggerA[pBCExcl] _ TRUE; polBuriedSpaceTriggerB[SX.nodeIndex] _ TRUE; polSpaceTrigger[SX.nodeIndex] _ TRUE; polSpaceTrigger[pBCErr] _ TRUE; metSpaceTrigger[SX.nodeIndex] _ TRUE; metSpaceTrigger[mBCExM] _ TRUE; metSpaceTrigger[mBCErrM] _ TRUE; metSpaceTrigger[mBCCutM] _ TRUE; metSpaceTrigger[mCutExM] _ TRUE; metSpaceTrigger[mCutM] _ TRUE; metWidthTrigger[SX.spaceIndex] _ TRUE; metWidthTrigger[mBCEx] _ TRUE; metWidthTrigger[mBCErr] _ TRUE; metWidthTrigger[mBCCut] _ TRUE; metWidthTrigger[mCutEx] _ TRUE; metWidthTrigger[mCut] _ TRUE; difSpacingRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinDist[NMos.dif, NMos.dif], message~"Diffusion spacing", okIfConnected~TRUE, trigger1~difSpaceTrigger1, trigger2~spaceRuleTrigger]]; difWidthRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinWidth[NMos.dif], message~"Diffusion width", trigger1~widthRuleTrigger, trigger2~widthRuleTrigger]]; polSpacingRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinDist[NMos.pol, NMos.pol], message~"Poly spacing", okIfConnected~TRUE, trigger1~polSpaceTrigger, trigger2~polSpaceTrigger]]; polWidthRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinWidth[NMos.pol], message~"Poly width", trigger1~polWidthTrigger, trigger2~polWidthTrigger]]; polDifSepRuleA _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinDist[NMos.pol, NMos.dif], message~"Poly/Diffusion spacing[debug:A]", trigger1~polDifSepTriggerA, trigger2~polDifSepTriggerB]]; polDifSepRuleB _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinDist[NMos.pol, NMos.dif], message~"Poly/Diffusion spacing[debug:B]", trigger1~polDifSepTriggerB, trigger2~polDifSepTriggerA]]; polOverDifRule _ NEW[ GeometricRule _ [extent~polOverDif, message~"Poly over Diffusion", trigger1~polOverDifTrigger1, trigger2~polOverDifTrigger2]]; metSpacingRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinDist[NMos.met, NMos.met], message~"Metal spacing", okIfConnected~TRUE, trigger1~metSpaceTrigger, trigger2~metSpaceTrigger]]; metWidthRule _ NEW[ GeometricRule _ [extent~CDSimpleRules.MinWidth[NMos.met], message~"Metal width", trigger1~metWidthTrigger, trigger2~metWidthTrigger]]; bcCutSpacingRule _ NEW[ GeometricRule _ [extent: 2*l, message: "Buried Contact Cut Spacing", okIfConnected: FALSE, trigger1~bcSpaceTrigger, trigger2~bcSpaceTrigger]]; bcMetalCutSpacingRuleA _ NEW[ GeometricRule _ [extent: 3*l/2, message: "Buried Contact Cut/Metal Cut Spacing[debug: A]", okIfConnected: FALSE, trigger1~bcMetalCutSpacingTriggerA, trigger2~bcMetalCutSpacingTriggerB]]; bcMetalCutSpacingRuleB _ NEW[ GeometricRule _ [extent: 3*l/2, message: "Buried Contact Cut/Metal Cut Separation[debug: B]", okIfConnected: FALSE, trigger1~bcMetalCutSpacingTriggerB, trigger2~bcMetalCutSpacingTriggerA]]; polBuriedSpacingRuleA _ NEW[ GeometricRule _ [extent: l/2, message: "Buried Contact Cut/Unrelated Poly Spacing[debug:A]", okIfConnected: TRUE, trigger1~polBuriedSpaceTriggerA, trigger2~polBuriedSpaceTriggerB]]; polBuriedSpacingRuleB _ NEW[ GeometricRule _ [extent: l/2, message: "Buried Contact Cut/Unrelated Poly Spacing[debug:B]", okIfConnected: TRUE, trigger1~polBuriedSpaceTriggerB, trigger2~polBuriedSpaceTriggerA]]; detectOpaqueViolation _ NEW[ GeometricRule _ [ extent~ l, message~ "Opaque cell boundary violated", trigger1~ ALL[TRUE], trigger2~ ALL[TRUE]]]; detectOpaqueViolation.trigger1[SX.violateIndex] _ FALSE; nMosHandle.rules[ difSpinifex] _ LIST[difSpacingRule, difWidthRule, detectOpaqueViolation]; nMosHandle.rules[ polSpinifex] _ LIST[polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule, polBuriedSpacingRuleA, polBuriedSpacingRuleB, detectOpaqueViolation]; nMosHandle.rules[ metSpinifex] _ LIST[metSpacingRule, metWidthRule, bcCutSpacingRule, bcMetalCutSpacingRuleA, bcMetalCutSpacingRuleB, detectOpaqueViolation]; SXTechnology.RegisterTechnologyHandle[cdTech~ NMos.nmos, technologyHandle~ nMosHandle]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosTransistor, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor, fini~SXOutputPrivate.UnNameTransType]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosATransistor, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosPullUp, conv~ConvertNMosTransistor, thyme~ThymeNMosTransistor, rose~RoseNMosTransistor]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosContactDifAndPol, conv~ConvertNMosContactDifAndPol]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosContactBut, conv~ConvertNMosButtingContact]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosBurContact, conv~ConvertNMosBuriedContact]; SXTechnology.RegisterSpinifexObjectProcs[ cdTech~ NMos.nmos, objectType~$NMosMmContact, conv~ConvertNMosMmContact]; }; Init[]; TerminalIO.PutRope["nMos technology parameters Loaded\n"]; END. tSXNMos.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Written by Shand, September 12, 1983 11:40 pm Last Edited by: Shand, March 12, 1985 4:23:50 pm PST Last Edited by: Spreitzer, January 14, 1985 10:35:35 pm PST Last Edited by: Jacobi, December 18, 1984 4:49:59 pm PST Last edited by: Christian Jacobi, November 7, 1986 4:37:26 pm PST Bowers, September 13, 1985 3:03:18 pm PDT Last edited by: gbb March 26, 1986 2:52:33 pm PST Basic rules not provided by CDSimpleRules These numbers are halved (sorry about any confusion this may cause) New Regime Transistor converters (IE the Shand unified xstr representaion) IF p.bendList = NIL THEN { -- Oh this is easy! Add poly boxes Add rects for poly exclusion At the top ... and the bottom Add rects for channel lead-in. At the top ... and the bottom Fill channel gap Add rects for diff width spacing and connection Add Linkages for transistor. We're a lot smarter than this program, so let's adjust the area and perim values its got. Material mapping [r: CD.Rect, l: CD.Layer, data: REF ANY] RETURNS [TransistorMaterial] Contact converters Attach two rectangles to the same node. [appl: CD.Instance, trans: CD.Transformation, cir: REF SX.Circuit] [appl: CD.Instance, pos: CD.Position, orient: CD.Orientation, cir: REF SX.Circuit] Add rect for poly exclusion Add rect for diff width spacing and connection [appl: CD.Instance, pos: CD.Position, orient: CD.Orientation, cir: REF SX.Circuit] 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.) Cut [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [l/2, l/2, s.x-l/2, s.y-l/2], -- actual dimensions of cut trans: trans, value: pCnstr[pBCCut]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [0, 0, s.x, s.y], --cut Bloated by 1/2 lambda (poly is bloated by lambda) trans: trans, value: pCnstr[pBCExcl]]; Polysilicon Surround Polysilicon/Diffusion Crossing. Cut Left side. Right side. Diffusion Surround Cut Left side. Top. Bottom. Diffusion Surround ! on all sides ??? Thyme and Rosemary [desWDir: ROPE, dfStream, cellStream: IO.STREAM, linkage: REF NodeLinkage, name: Rope.ROPE, PrintNode: NodePrintProc] [desWDir: ROPE, dfStream, cellStream: IO.STREAM, linkage: REF NodeLinkage, PrintNode: NodePrintProc] The following is a quick hack to allow John Ousterhout to test Crystal. In a later stage, SX.AttachedNode shall receive an additional field for this info. At the moment it is not clear yet, how the user interface should be like. Module Initialization Global constants and variables. Diffusion layer Poly layer pBCCut: SX.ConstraintIndex = pBCErr.SUCC; -- Buried Contact Cut Construction of the Layer Constraints. pCnstr[pBCCut] _ NEW[ Constraint _ [ $PolyBCCut, pBCCut]]; Basic nMosHandle & cdLayerMappings. Spinifex Layer Identification. Thyme stray capacitance layer names. Set Constraint Resolutions for each layer into the TechHandle. Geometric rule triggers. Corners are defined by union of dif and gate, but checking only looks at dif Purely local errors are not handled in a natural manner by the corner-based scheme, so for every corner we find in pCnstr[pDPErr] we generate an error if there is anything on any layer nearby, of course there is always something so we get our error. The geometric rules. We set violateIndex = FALSE, ALL else TRUE so that corner checks face inward, which should result in more logically pleasing error reports. Technology handle is attached to the ChipNDale technology. Technology specific objects. Edited on March 7, 1985 1:28:12 am PST, by Shand added interaction region around dCnstr[dCh] constraints, new parameter to SXTechnology.ProcessMosTransistor to handle channel constraint interest bloating. Also changed dCnstr[dCh].withNode so that dCnstr[dCh]+Node => $Conflict. changes to: ConvertNMosTransistor contains creation of dCnstr[dCh] constraints and call of SXTechnology.ProcessMosTransistor, Init setting of dCnstr[dCh].withNode Edited on March 7, 1985 4:25:39 pm PST, by Shand Transistor Output changes: n*W multiplier for McCreight, ZTrans for Bowers. Edited on March 9, 1985 2:01:08 pm PST, by Beretta & Shand New Constraint Representation from SX and procedures to set it up. changes to: ConvertNMosTransistor, ConvertNMosButtingContact, ConvertNMosBuriedContact, Constraint, dCnstr, pCnstr, Init, DIRECTORY Edited on March 10, 1985 10:25:58 pm PST, by Shand changes to: RoseNMosTransistor Edited on March 12, 1985 4:23:50 pm PST, by Shand Now uses registration mechanisms of SXTechnology. changes to: DIRECTORY, NMosSpinifex, Init, pCnstr, Init, ConvertNMosContactDifAndPol, ConvertNMosButtingContact, pCnstr, Init, Init Edited on March 19, 1985 12:44:28 pm PST, by Beretta Thyme output change: substituted `n' coefficient for Ed McCreight by `N' changes to: ThymeNMosTransistor Edited on March 27, 1985 6:37:12 pm PST, by Beretta Corrected bug in poly constraint resolution table changes to: Init: pResTab[3,1] _ pDPErr Edited on April 29, 1985 8:09:08 pm PDT, by Beretta Fixed bug that flagged a poly width rule violation at the attachments of buried contacts "Polysilicon Surround" and "Diffusion Surround" changes to: Init added polWidthTrigger [pDandP] _ FALSE; Edited on May 2, 1985 10:45:08 am PDT, by Beretta Added a quick hack to the Thyme output to allow John Ousterhout to test Crystal. changes to: ThymeNMosTransistor: If a transistor has a property $Crystal, then its rope value is placed in the parameter list, preceded by a semicolon. Edited on May 6, 1985 11:26:55 am PDT, by Beretta Converted to ChipNDale CD20 Edited on May 20, 1985 2:38:11 pm PDT, by Beretta, Created new interface SXNMosBasicRules. Edited on June 18, 1985 4:56:52 pm PDT, by Beretta Changed transistor types from FooTrans to FooTran, as Thyme expects. changes to: ThymeNMosTransistor Last edited by: gbb July 18, 1985 4:47:07 pm PDT Converted to ChipNDale 2.1. changes to: ConvTransistor: Adapted by Christian, ConvertContact: Completely rewritten. gbb August 13, 1985 6:15:20 pm PDT Added creation of Core data structure. changes to: DIRECTORY, SXNMos, MakeCoreNMOSTransistor: new; type is not correct because Core does not yet cater for NMos transistors, Init gbb November 7, 1985 5:07:31 pm PST Conversions for ChipNDale22 gbb November 24, 1985 4:21:44 pm PST Removed creation of Core data structure. changes to: DIRECTORY, SXNMos Êø˜codešœ ™ Kšœ Ïmœ1™˜d—Mšœ˜K˜——šœ™N™Mšœ žœ˜Mšœ;žœ˜AKšœ1žœ˜6Kšœ1žœ˜6Mšœ žœ˜!M™šœžœžœ¡˜RKšœ-¡˜A—M™ šœžœžœ¡Ïe˜MKšœ/¡˜HKšœ#žœ¡;˜dKšœ$žœ¡*˜TKšœ"žœ¡&˜NKšœ"žœ¡#˜KKšœ$žœ¡/˜YJš£%Ðbk£!˜JJš£U˜UJš£?™?—š£§£§£Ðbc˜NJš£/¨˜LJš›@2 £#¨*˜SJš©£©£¨˜IJšœ£©£¨˜FJšœ£œ£¨˜FJš£œ£¨(˜PJš©£%¨5˜`Jš©£©£¨*˜VJšœ£œ£©£¨'˜SJšœ£œ£œ£¨)˜S—š¢œž œ˜Mšœžœ˜'Mšœžœ˜0MšœN£,œžœ˜ŽMšœ£@œžœ˜rMšœžœ˜)Mšœ žœžœžœžœžœžœžœ˜KMšœ˜Kšœ˜KšœY˜YKšœ˜Kšœ˜Mš£n˜nMš£Q˜QMšœžœ˜+Kšœžœ˜,Mš£§£˜+šœ&™&Mšœžœ$˜5Mšœžœ&˜9Kšœžœ0˜DKšœžœ(˜¬ « ˜SOš«>¬« ˜UOš«B¬« ˜YOš¬Z˜ZOš¬X˜XKš«˜Kš«˜—J˜š£)˜)Oš«d˜dOš«h˜hOš«i˜iOš«k˜kOš«k˜kOš«k˜kOš«\˜\Oš«n˜nOš«p˜pOš«p˜pOš«o˜oOš«\˜\Oš«˜Kš«˜—Mšœ?˜?Kšœ@˜@Jš£?˜?K˜——šÏl#™#Mšœ žœÑ˜áKšœ$žœ˜*Kšœ$žœ˜*Kšœ$žœ˜*Kšœ$žœ˜*Kšœ&žœl˜–Kšœ&žœ?˜iKšœ&žœ?˜i—š­™Mšœ@˜@Kšœ;˜;Kšœ<˜<—š­$™$Mšœ;˜;Kšœ;˜;Kšœ;˜;—š­>™>Mšœ>˜>Kšœ?˜?Kš£>˜>—š­™Mšœ!žœ˜&Kšœ"žœ˜'MšœL™LKšœ!žœ˜&Kšœžœ˜Mšœžœžœ˜Kšœ!žœ˜'Kšœžœ¡˜7Kš£3˜3Mšœ#žœ˜(Kšœžœ˜!Kšœžœ˜"Mšœù™ùKšœžœ˜#Kšœžœžœ˜Mš£˜Mš£'˜'Mš£)˜)Mš£&˜&Mš£'˜'Mš£,˜,Mš£%˜%Mš£˜Mš£%˜%Mš£¬£ ˜Mš£¬£ ˜ Mš£¬£ ˜ Mš£¬£ ˜ Mš£¬£ ˜Mš£&˜&Mš£¬£ ˜Mš£¬£ ˜Mš£¬£ ˜Mš£¬£ ˜Mš£¬£ ˜K˜—š­™M–M[key: REF ANY, technology: CD.Technology _ NIL, default: REF ANY _ NIL]šœžœpžœ9˜ÁMšœžœŽ˜ Mš œžœkžœ £œ £œ˜ºMšœžœ‡˜™Mšœžœ©˜½Mšœžœ©˜½Mšœžœ€˜”Mšœžœlžœ7˜»Mšœžœˆ˜šMš£§£ £6§£5˜¦Mšœ£§£ £L§£K˜ØMšœ£§£ £O§£K˜ÛMš£6 £›˜ÒMš£6 £›˜ÒMš œžœ œ6žœžœ žœžœ˜Kšœ‹™‹Kšœ2žœ˜8Mšœ!žœ6˜[Mšœ!žœO£,œ˜¹Mš£!§£_œ£˜—š­:™:M–<[propList: Atom.PropList, prop: REF ANY, val: REF ANY]šœW˜W—š­™MšœÏ˜ÏKšœª˜ªKšœ¥˜¥Mšœ˜Kšœy˜yMšœx˜xMš£s˜s—K˜——L˜Kšœ:˜:Kšžœ˜™0JšœJ¦!œ?Ïrœ'™åJšœ ®œ:¦!®œ ®™¢—™0J™K—™:J™BJšœ ®w™ƒ—™2Jšœ ®™—™1Jšœ1™1Jšœ ®w™ƒ—™4J™HJšœ ®™—™3J™1Jšœ ®œ™'—š¡3™3Jšœ‰™‰Jšœ ®œ"žœ™8—™1KšœP™PJšœ ®œx™——™1K™—™2Jšœ¦™'—™2J™DJšœ ®™—™0K™Kšœ ®œ®œ®™W—™"K™&Kšœ ®)œO®™Š—™#K™—™$K™(Kšœ ®™—K™—…—r¤¤