DIRECTORY CD USING [ApplicationPtr, DesignNumber, DesignPosition, DesignRect, lambda, Layer, Rect], CDBasics USING [RectAt], CDProperties USING [GetPropFromApplication], IO USING [char, int, Put, PutF, PutRope, rope], NMos USING [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], SXNMosBasicRules USING [contactWidth, difSep, difSpacing, difToPolExtSep, difToPolSep, difWidth, metSep, metSpacing, metWidth, polDifSep, polOverDif, polSep, polSpacing, polWidth], 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 [WriteRope] ; SXNMos: CEDAR PROGRAM IMPORTS CDBasics, CDProperties, IO, NMos, Rope, SX, SXOutputPrivate, SXTechnology, TerminalIO = BEGIN l: CD.DesignNumber ~ CD.lambda; ConvertNMosTransistor: SX.ConversionProc -- [appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, cir: REF ] -- ~ { p: NMosTransistors.TransistorPtr = NARROW[appl.ob.specificRef]; size: CD.DesignPosition _ appl.ob.size; xstr: REF SX.NodeLinkage; gateNode, sourceNode, drainNode, metNode: REF SX.CircuitNode; polExt: CD.DesignNumber ~ IF p.pullup THEN MIN[ (size.x-SXNMosBasicRules.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], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.SWNGrow[SXNMosBasicRules.polSep]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt, size.x-polExt, p.lExt+p.length], appl~appl, pos~ pos, orient~ orient, value~gateNode]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[size.x-polExt, p.lExt, size.x, p.lExt+p.length], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.NESGrow[SXNMosBasicRules.polSep], value~gateNode]; IF p.lExt-SXNMosBasicRules.difToPolSep > 0 THEN { [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt+p.length+SXNMosBasicRules.difToPolSep, size.x-polExt, size.y], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.WNEGrow[ SXNMosBasicRules.difToPolExtSep], value~pCnstr[pExcl]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[p.wExt, 0, size.x-p.wExt, p.lExt-SXNMosBasicRules.difToPolSep], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.ESWGrow[ SXNMosBasicRules.difToPolExtSep], value~pCnstr[pExcl]] }; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[polExt, p.lExt+p.length, size.x-polExt, p.lExt+p.length+SXNMosBasicRules.difToPolSep], appl~appl, pos~ pos, orient~ orient, value~pCnstr[pChE]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[p.wExt, p.lExt-SXNMosBasicRules.difToPolSep, size.x-p.wExt, p.lExt], appl~appl, pos~ pos, orient~ orient, value~pCnstr[pChE]]; [] _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[p.wExt, p.lExt, size.x-p.wExt, p.lExt+p.length], appl~appl, pos~ pos, orient~ orient, interestBloat~[dx1~ SXNMosBasicRules.difSep, dy1~ 0, dx2~ SXNMosBasicRules.difSep, 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], appl~appl, pos~ pos, orient~ orient, interestBloat~[dx1~ SXNMosBasicRules.difSep, dy1~ 0, dx2~ SXNMosBasicRules.difSep, dy2~ SXNMosBasicRules.difSep], value~dCnstr[dCh]]; sourceNode _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[polExt, p.lExt+p.length, size.x-polExt, size.y], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.WNEGrow[SXNMosBasicRules.difSep]]; drainNode _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[p.wExt, 0, size.x-p.wExt, p.lExt], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.ESWGrow[SXNMosBasicRules.difSep]]; IF p.pullup THEN { metNode _ cir.AddRect[ lev~NMos.met, dim~[ (size.x-SXNMosBasicRules.contactWidth)/2, size.y-6*l, (size.x+SXNMosBasicRules.contactWidth)/2, size.y], appl~appl, pos~ pos, orient~ orient]; } 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[appl, pos, orient, cir, difSpinifex, polSpinifex, dCnstr[dCh], pCnstr[pChE], SXNMosBasicRules.difSep, SXNMosBasicRules.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.WriteRope[ 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[appl]; 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 -- [r: CD.DesignRect, l: CD.Layer, data: REF ANY] RETURNS [TransistorMaterial] -- ~ { 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 -- [appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, cir: REF SX.Circuit] -- ~ { box: CD.Rect _ CDBasics.RectAt[pos~[0,0], size~appl.ob.size]; node: REF SX.CircuitNode; node _ cir.AddRect[ lev~NMos.met, dim~box, appl~appl, pos~ pos, orient~ orient]; [] _ cir.AddRect[ lev~appl.ob.layer, dim~box, appl~appl, pos~ pos, orient~ orient, value~node]; IF appl.ob.layer = NMos.dif THEN [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~box, appl~appl, pos~ pos, orient~ orient, value~pCnstr[pExCon]]; }; ConvertNMosButtingContact: SX.ConversionProc -- [appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, cir: REF SX.Circuit] -- ~ { rimWidth: CD.DesignNumber ~ l; polSize: CD.DesignNumber ~ appl.ob.size.y/2; box: CD.Rect _ CDBasics.RectAt[pos~[0,0], size~appl.ob.size]; node: REF SX.CircuitNode; node _ cir.AddRect[ lev~NMos.met, dim~box, appl~appl, pos~ pos, orient~ orient]; [] _ cir.AddRect[ lev~NMos.pol, dim~[0,0, appl.ob.size.x, polSize], appl~appl, pos~ pos, orient~ orient, value~node]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[-rimWidth,polSize, appl.ob.size.x+rimWidth, polSize+SXNMosBasicRules.difToPolSep], appl~appl, pos~ pos, orient~ orient, value~pCnstr[pChE]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[-rimWidth,polSize-rimWidth, 0, polSize], appl~appl, pos~ pos, orient~ orient, value~pCnstr[pDxorP]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[appl.ob.size.x,polSize-rimWidth, appl.ob.size.x+rimWidth, polSize], appl~appl, pos~ pos, orient~ orient, value~pCnstr[pDxorP]]; [] _ cir.AddBox[ spinifexLayer~polSpinifex, dim~[0,polSize+SXNMosBasicRules.difToPolSep, appl.ob.size.x, appl.ob.size.y], appl~appl, pos~ pos, orient~ orient, interestBloat~SXTechnology.WNEGrow[ SXNMosBasicRules.difToPolExtSep], value~pCnstr[pExCon]]; [] _ cir.AddBox[ spinifexLayer~difSpinifex, dim~[0,polSize, appl.ob.size.x, appl.ob.size.y], appl~appl, pos~ pos, orient~ orient, interestBloat~[ SXNMosBasicRules.difSep, SXNMosBasicRules.difSep, SXNMosBasicRules.difSep, SXNMosBasicRules.difSep], value~node]; }; ConvertNMosBuriedContact: SX.ConversionProc -- [appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, cir: REF SX.Circuit] -- ~ { s: CD.DesignPosition ~ appl.ob.size; cp: NMosContacts.ContactPtr ~ NARROW[appl.ob.specificRef]; node: REF SX.CircuitNode ~ cir.AddRect[ lev~NMos.pol, dim~[2*l, cp.lExt, s.x-cp.wExt, s.y-cp.lExt], appl~appl, pos~ pos, orient~ orient]; SELECT TRUE FROM cp.lExt < 2*l AND cp.wExt < 2*l => { wex: CD.DesignNumber ~ MAX[cp.wExt+l, 2*l]; lex: CD.DesignNumber ~ MAX[cp.lExt+l, 2*l]; [] _ cir.AddRect [ lev: appl.ob.layer, dim: [l, lex, 2*l, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-SXNMosBasicRules.difToPolSep, lex, 2*l, s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, lex, s.x-wex, s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pDandP]]; [] _ cir.AddBox [ spinifexLayer: difSpinifex, dim: [2*l, lex, s.x-wex, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; }; cp.lExt < 2*l AND cp.wExt >= 2*l => { lex: CD.DesignNumber ~ MAX[cp.lExt+l, 2*l]; [] _ cir.AddBox [ spinifexLayer: difSpinifex, dim: [2*l, lex, s.x-cp.wExt, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, lex, s.x-cp.wExt, s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pDandP]]; [] _ cir.AddRect [lev: appl.ob.layer, dim: [l, lex, 2*l, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-SXNMosBasicRules.difToPolSep, lex, 2*l, s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: appl.ob.layer, dim: [s.x-cp.wExt, lex, s.x-(cp.wExt-l), s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [s.x-cp.wExt, lex, s.x-(cp.wExt-SXNMosBasicRules.difToPolSep), s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; }; cp.lExt >= 2*l AND cp.wExt < 2*l => { wex: CD.DesignNumber ~ MAX[cp.wExt+l, 2*l]; lex: CD.DesignNumber ~ cp.lExt-l; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, cp.lExt, s.x-wex, s.y-cp.lExt], appl: appl, pos: pos, orient: orient, value: pCnstr[pDandP]]; [] _ cir.AddRect [ lev: appl.ob.layer, dim: [l, lex, s.x-wex, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l-SXNMosBasicRules.difToPolSep, lex, 2*l, s.y-lex], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: appl.ob.layer, dim: [2*l, s.y-cp.lExt, s.x-wex, s.y-lex], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, s.y-cp.lExt, s.x-wex, s.y-(cp.lExt-SXNMosBasicRules.difToPolSep)], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; [] _ cir.AddRect [ lev: appl.ob.layer, dim: [2*l, lex, s.x-wex, cp.lExt], appl: appl, pos: pos, orient: orient, value: node]; [] _ cir.AddBox [ spinifexLayer: polSpinifex, dim: [2*l, cp.lExt-SXNMosBasicRules.difToPolSep, s.x-wex, cp.lExt], appl: appl, pos: pos, orient: orient, value: pCnstr[pChE]]; }; cp.lExt >= 2*l AND cp.wExt >= 2*l => { ERROR SX.IllegalConstruct [appl.ob.p.interestRect[appl.ob], "Polysilicon surrounded by diffusion or all sides in Buried Contact"]; }; ENDCASE => ERROR; }; RoseNMosTransistor: SXOutput.LinkagePrintProc -- [ desWDir: ROPE, dfStream, cellStream: IO.STREAM, linkage: REF NodeLinkage, name: Rope.ROPE, PrintNode: NodePrintProc] -- ~ { 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.specificRef]; 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 -- [ desWDir: ROPE, dfStream, cellStream: IO.STREAM, linkage: REF NodeLinkage, PrintNode: NodePrintProc] -- ~ { 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.specificRef]; 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.GetPropFromApplication [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.WriteRope [" $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. Init: PROCEDURE ~ { GeometricRule: TYPE ~ SX.GeometricRule; difSpacingRule, difWidthRule: REF GeometricRule; polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule: REF GeometricRule; metSpacingRule, metWidthRule: 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; difResolution: REF SX.ConstraintResolution; polyResolution: 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]]; { 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, ,,,,,,,], [ nd, nd, pDPErr, pDPErr, pDPErr, pDPErr, nd, pDandP, ,,,,,,,], [ pExcl, pDPErr, pExcl, pExCon, pDPErr, pChE, pChE, pDandP, ,,,,,,,], [ pExCon, pDPErr, pExCon, pExCon, pDPErr, pExCon, pExCon, pDandP, ,,,,,,,], [ pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDPErr, pDandP, ,,,,,,,], [ pChE, pDPErr, pChE, pExCon, pDPErr, pChE, pChE, pDandP, ,,,,,,,], [ pDxorP, nd, pChE, pExCon, pDPErr, pChE, pDxorP, pDandP, ,,,,,,,], [ pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, pDandP, ,,,,,,,], ,,,,,,, ]; difResolution _ SXTechnology.SetUpResolution[ dCnstr, dResTab]; polyResolution _ SXTechnology.SetUpResolution[ pCnstr, pResTab] }; nMosHandle _ NEW[SX.TechHandle _ [numSpinifexLayers~3, layerInterestBloat~[SXNMosBasicRules.difSep, SXNMosBasicRules.polSep, SXNMosBasicRules.metSep, ,,,,]] ]; 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, SXNMosBasicRules.difSep], [polSpinifex,SXNMosBasicRules.difToPolExtSep,pCnstr[pExcl]]]; nMosHandle.cdLayerMapping[NMos.pol] _ LIST[ [polSpinifex,SXNMosBasicRules.polSep]]; nMosHandle.cdLayerMapping[NMos.met] _ LIST[ [metSpinifex,SXNMosBasicRules.metSep]]; 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; 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 polDifSepTriggerA[ SX.nodeIndex] _ TRUE; polDifSepTriggerB[ pExcl] _ TRUE; polDifSepTriggerB[ pExCon] _ TRUE; polOverDifTrigger1[ pDPErr] _ TRUE; polOverDifTrigger2 _ ALL[TRUE]; difSpacingRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.difSpacing, message~"Diffusion spacing", okIfConnected~TRUE, trigger1~difSpaceTrigger1, trigger2~spaceRuleTrigger]]; difWidthRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.difWidth, message~"Diffusion width", trigger1~widthRuleTrigger, trigger2~widthRuleTrigger]]; polSpacingRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.polSpacing, message~"Poly spacing", okIfConnected~TRUE, trigger1~spaceRuleTrigger, trigger2~spaceRuleTrigger]]; polWidthRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.polWidth, message~"Poly width", trigger1~polWidthTrigger, trigger2~polWidthTrigger]]; polDifSepRuleA _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.polDifSep, message~"Poly/Diffusion spacing[debug:A]", trigger1~polDifSepTriggerA, trigger2~polDifSepTriggerB]]; polDifSepRuleB _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.polDifSep, message~"Poly/Diffusion spacing[debug:B]", trigger1~polDifSepTriggerB, trigger2~polDifSepTriggerA]]; polOverDifRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.polOverDif, message~"Poly over Diffusion", trigger1~polOverDifTrigger1, trigger2~polOverDifTrigger2]]; metSpacingRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.metSpacing, message~"Metal spacing", okIfConnected~TRUE, trigger1~spaceRuleTrigger, trigger2~spaceRuleTrigger]]; metWidthRule _ NEW[ GeometricRule _ [extent~SXNMosBasicRules.metWidth, message~"Metal width", trigger1~widthRuleTrigger, trigger2~widthRuleTrigger]]; nMosHandle.rules[ difSpinifex] _ LIST[difSpacingRule, difWidthRule]; nMosHandle.rules[ polSpinifex] _ LIST[polSpacingRule, polWidthRule, polDifSepRuleA, polDifSepRuleB, polOverDifRule]; nMosHandle.rules[ metSpinifex] _ LIST[metSpacingRule, metWidthRule]; 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]; }; Init[]; TerminalIO.WriteRope["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: Beretta, June 18, 1985 4:57:52 pm PDT -- 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. -- Contact converters Attach two rectangles to the same node. -- Add rect for poly exclusion -- Add rect for diff width spacing and connection 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.) Polysilicon Surround Polysilicon/Diffusion Crossing. Left side. Right side. Diffusion Surround Left side. Top. Bottom. Diffusion Surround ! on all sides ??? 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 -- Construction of the Layer Constraints. -- 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. -- 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 Êp˜codešœ ™ Kšœ Ïmœ1™˜>Kšœ?˜?—š¦™Lšœ!žœ˜&Kšœ"žœ˜'LšœL™LKšœ!žœ˜&Kšœžœ˜Lšœžœžœ˜Kšœ!žœ˜'Kšœžœ£˜7Lšœ#žœ˜(Kšœžœ˜!Kšœžœ˜"Lšœü™üKšœžœ˜#Kšœžœžœ˜—š¦™L–M[key: REF ANY, technology: CD.Technology _ NIL, default: REF ANY _ NIL]šœžœbžœ9˜³Lšœžœ* œ\˜™Lšœžœ]žœ9˜®Lšœžœ* œU˜’Lšœžœ* œo˜®Lšœžœ* œo˜®Lšœžœ* œf˜¥Lšœžœ* œ3žœ9˜¯Lšœžœ* œX˜•Lšœ!žœ˜DLšœ!žœO˜tLšœ!žœ˜D—š¦=™=L–<[propList: Atom.PropList, prop: REF ANY, val: REF ANY]šœW˜W—š¦™LšœÏ˜ÏKšœª˜ªKšœ¥˜¥Lšœ˜Kšœy˜yLšœx˜x—K˜—L˜K˜