-- File CIFExtNMOS.mesa -- Written by Dan Fitzpatrick and Martin Newell, June 1980 -- Last updated: December 21, 1981 3:55 PM by DF DIRECTORY CIFDevicesDefs: FROM "CIFDevicesDefs" USING [LENGTHLayerArray, LookupLayer], CIFExtDictDefs: FROM "CIFExtDictDefs" USING [InitDictionary], CIFExtIODefs: FROM "CIFExtIODefs" USING [OpenFile,CloseStream,DeleteFile], CIFExtNMOS2Defs: FROM "CIFExtNMOS2Defs", CIFExtNMOSDefs: FROM "CIFExtNMOSDefs", CIFExtScanDefs: FROM "CIFExtScanDefs" USING [In, XatY, EdgeLength, Edge], CIFExtUtilsDefs: FROM "CIFExtUtilsDefs" USING [ --DrawString, -- DrawNumber, WriteLongDecimal, Tag], IODefs: FROM "IODefs" USING [ WriteString, WriteLine, GetOutputStream, SetOutputStream], MergeDefs: FROM "MergeDefs" USING [InitMerge, FinishMerge, ConsolidateMerge], Real: FROM "Real" USING [Fix], SystemDefs: FROM "SystemDefs" USING [AllocateHeapString, FreeHeapString], StreamDefs: FROM "StreamDefs" USING [StreamHandle, DiskHandle], StringDefs: FROM "StringDefs" USING [AppendString]; CIFExtNMOS: PROGRAM IMPORTS CIFExtNMOS2Defs, CIFDevicesDefs, CIFExtDictDefs, CIFExtIODefs, CIFExtScanDefs, CIFExtUtilsDefs, IODefs, MergeDefs, Real, SystemDefs, StringDefs EXPORTS CIFExtNMOSDefs = BEGIN OPEN CIFExtNMOS2Defs, CIFDevicesDefs, CIFExtDictDefs, CIFExtIODefs, CIFExtScanDefs, CIFExtUtilsDefs, IODefs, MergeDefs, Real, SystemDefs, StreamDefs, StringDefs; deplNodeList, enhaNodeList, diffNodeList: NodeSegment; -- place holders in their respective node lists InitNMOS: PUBLIC PROCEDURE [str: STRING] = BEGIN ErrorFlag _ FALSE; BaseFileName.length _ 0; AppendString[BaseFileName, str]; InitMerge["Merge.tmp$"]; TransistorFile _ OpenFile["CIFExtractor.tmp$",'w]; CapacitorFile _ OpenFile["CIFExtractor.tmp2$",'w]; NodeFile _ OpenFile["CIFNodes.tmp$",'w]; LabelNodeFile _ OpenFile["CIFLabelNode.tmp$",'w]; errorStream _ OpenFile[Tag[BaseFileName, "extlog"],'w]; out1 _ OpenFile[Tag[BaseFileName, "sim"],'w]; newNodeList _ oldNodeList _ NodeList _ ALL[NIL]; NodeNumber _ LOOPHOLE[LONG[0]]; depl _ LookupLayer[['G, 'A, 'T, 'D]]; enha _ LookupLayer[['G, 'A, 'T, 'E]]; LabelList _ NIL; -- Get the scale factor to convert from screen to CIF co-ordinates without translation --kludge for now - expect scale to be unity Scale _ 1; END; FinishNMOS: PUBLIC PROCEDURE = BEGIN InitSwath[YCurr, YCurr]; -- Done twice to free node segements created on last InitSwath[YCurr, YCurr]; -- valid pass. NodeFile.destroy[NodeFile]; OutputTransistors[]; -- Write out all the transistors CloseStream[TransistorFile]; CloseStream[CapacitorFile]; CloseStream[LabelNodeFile]; -- End of extraction -- Start second phase: looking up node numbers for new values, replacing node numbers -- with their coresponding label, if any WriteLine["Extraction Phase Complete --- Creating Output Files"]; ConsolidateMerge[]; InitDictionary[]; CorrectLabelNodes[Tag[BaseFileName, "al"]]; -- deletes CIFLabelNode.tmp$ DeleteFile["CIFNodes.tmp$"]; -- Save standard output stream and Set output stream to file FileName defaultStream _ GetOutputStream[]; SetOutputStream[out1]; ConvertTransToText[out1]; -- deletes CIFExtractor.tmp2$ DeleteFile["CIFExtractor.tmp$"]; -- Restore standard output stream SetOutputStream[defaultStream]; CloseStream[out1]; -- Free the storage consumed by transistors ReleaseTransistors[]; FinishMerge[]; -- Print out statisics on how much dynamic memory has not been freed PrintAllocation[FALSE]; --Print the total number of transistors extracted PrintTransistors[]; SetErrorStream[FALSE]; PrintTransistors[]; ResetErrorStream[]; CloseStream[errorStream]; WriteString["Simulation file is "]; WriteString[BaseFileName]; WriteString[".sim and node names are in "]; WriteString[BaseFileName]; WriteLine[".nodes"]; IF AliasFlag THEN { WriteString["alias file is "]; WriteString[BaseFileName]; WriteLine[".al"]; }; IF ErrorFlag THEN { WriteString["errors recorded on "]; WriteString[BaseFileName]; WriteLine[".extlog"]; }; END; NameNMOS: PUBLIC PROCEDURE [name: STRING, x, y: REAL, layer:CARDINAL] = BEGIN label: NodeLabel _ AllocateNodeLabel[]; label.label _ AllocateHeapString[name.length]; NoAllocString _ NoAllocString + 1; AppendString[label.label, name]; label.x _ x; label.y _ y; label.layer _ layer; label.used _ FALSE; label.next _ LabelList; LabelList _ label; END; InitSwath: PUBLIC PROCEDURE [prev, curr: REAL] = BEGIN node: NodeSegment; label, next: NodeLabel; tranSeg, diffSeg, polySeg, metalSeg, cutSeg, lastDiffSeg, lastPolySeg: NodeSegment; i: CARDINAL; YCurr _ curr; YPrev _ prev; -- the following statements mark the progression of the program on the screen scanCount _ scanCount + 1; IF scanCount > 100 THEN BEGIN DrawNumber[1, LOOPHOLE[LONG[displayCount]], 200, YCurr]; displayCount _ displayCount + 1; scanCount _ 1; END; FOR i IN [0..LENGTHLayerArray) DO -- Free old nodes FOR node _ oldNodeList[i], oldNodeList[i] UNTIL node = NIL DO oldNodeList[i] _ node.next; IF node.mark THEN WriteNodeCap[node, CapacitorFile]; FreeNodeSegment[node]; ENDLOOP; -- Set new nodes to current oldNodeList[i] _ NodeList[i] _ newNodeList[i]; newNodeList[i] _ NIL; ptrnewNodeList[i] _ @newNodeList[i]; ENDLOOP; diffNodeList _ NodeList[diff]; deplNodeList _ NodeList[depl]; enhaNodeList _ NodeList[enha]; -- since both diffNodeList & NodeList[diff] march through the node list -- it is necessary to delay freeing the nodes till now, that is the reason -- for having oldNodeList -- Free old labels next _ LabelList; LabelList _ NIL; FOR label _ next, next UNTIL label = NIL DO next _ label.next; IF label.y < YPrev THEN BEGIN IF NOT label.used THEN BEGIN SetErrorStream[TRUE]; WriteFloat[label.x]; WriteString[" "]; WriteFloat[label.y]; WriteString[" The name '"]; WriteString[label.label]; WriteLine["' does not correspond to any node"]; ResetErrorStream[]; END; FreeHeapString[label.label]; NoAllocString _ NoAllocString - 1; FreeNodeLabel[label]; END ELSE BEGIN label.next _ LabelList; LabelList _ label; END; ENDLOOP; diffSeg _ NodeList[diff]; lastPolySeg _ NodeList[poly]; -- Scan for Transistors FOR tranSeg _ NodeList[depl], tranSeg.next UNTIL tranSeg = NIL DO FOR diffSeg _ diffSeg, diffSeg.next UNTIL diffSeg = NIL OR diffSeg.right >= tranSeg.left DO ENDLOOP; WITH t: tranSeg SELECT TRUE FROM TRUE => BEGIN IF diffSeg # NIL AND diffSeg.right = t.left THEN BEGIN SetDiff[NodeToTransistor[t.number], diffSeg.number, t.leftLength]; diffSeg _ diffSeg.next; END; IF diffSeg # NIL AND diffSeg.left = t.right THEN BEGIN SetDiff[NodeToTransistor[t.number], diffSeg.number, t.rightLength]; END; END; ENDCASE; -- Poly cannot end inside a transistor FOR polySeg _ lastPolySeg, polySeg.next UNTIL polySeg = NIL OR tranSeg.right <= polySeg.right DO ENDLOOP; SetPoly[NodeToTransistor[tranSeg.number], polySeg.number]; ENDLOOP; diffSeg _ NodeList[diff]; lastPolySeg _ NodeList[poly]; FOR tranSeg _ NodeList[enha], tranSeg.next UNTIL tranSeg = NIL DO FOR diffSeg _ diffSeg, diffSeg.next UNTIL diffSeg = NIL OR diffSeg.right >= tranSeg.left DO ENDLOOP; WITH t: tranSeg SELECT TRUE FROM TRUE => BEGIN IF diffSeg # NIL AND diffSeg.right = t.left THEN BEGIN SetDiff[NodeToTransistor[t.number], diffSeg.number, t.leftLength]; diffSeg _ diffSeg.next; END; IF diffSeg # NIL AND diffSeg.left = t.right THEN BEGIN SetDiff[NodeToTransistor[t.number], diffSeg.number, t.rightLength]; END; END; ENDCASE; -- Poly cannot end inside a transistor FOR polySeg _ lastPolySeg, polySeg.next UNTIL polySeg = NIL OR tranSeg.right <= polySeg.right DO ENDLOOP; SetPoly[NodeToTransistor[tranSeg.number], polySeg.number]; ENDLOOP; -- Connect nodes through contact cuts lastDiffSeg _ NodeList[diff]; lastPolySeg _ NodeList[poly]; metalSeg _ NodeList[metal]; FOR cutSeg _ NodeList[contact], cutSeg.next UNTIL cutSeg = NIL DO FOR metalSeg _ metalSeg, metalSeg.next UNTIL metalSeg = NIL OR cutSeg.right <= metalSeg.right DO ENDLOOP; IF metalSeg = NIL OR cutSeg.left < metalSeg.left THEN BEGIN SetErrorStream[TRUE]; WriteLongDecimal[Fix[cutSeg.left]]; WriteString[", "]; WriteLongDecimal[Fix[YPrev]]; WriteLine[" Metal doesn't surround contact cut"]; ResetErrorStream[]; LOOP; END; FOR diffSeg _ lastDiffSeg, diffSeg.next UNTIL diffSeg = NIL OR cutSeg.left <= diffSeg.right DO ENDLOOP; lastDiffSeg _ diffSeg; FOR diffSeg _ diffSeg, diffSeg.next UNTIL diffSeg = NIL OR cutSeg.right < diffSeg.left DO Combine[metalSeg, diffSeg, metal]; lastDiffSeg _ diffSeg; ENDLOOP; FOR polySeg _ lastPolySeg, polySeg.next UNTIL polySeg = NIL OR cutSeg.left < polySeg.right DO ENDLOOP; lastPolySeg _ polySeg; FOR polySeg _ polySeg, polySeg.next UNTIL polySeg = NIL OR cutSeg.right < polySeg.left DO Combine[metalSeg, polySeg, metal]; lastPolySeg _ polySeg; ENDLOOP; ENDLOOP; -- Connect nodes through buried contacts -- only affected nodes are those on poly and diffusion -- Since diffusion overlaps poly only in buried contact region -- there is no need to look at the buried layer IF gotBuried THEN BEGIN -- don't need to do following if there are no buried contacts polySeg _ NodeList[poly]; FOR diffSeg _ NodeList[diff], diffSeg.next UNTIL diffSeg = NIL DO -- skip all poly left of diffusion region WHILE polySeg # NIL AND polySeg.right <= diffSeg.left DO polySeg _ polySeg.next; ENDLOOP; -- merge all poly that properly intersect the diffusion region IF polySeg # NIL AND polySeg.left < diffSeg.right THEN { polySegExtra: NodeSegment _ polySeg; WHILE polySegExtra # NIL AND polySegExtra.left < diffSeg.right DO Combine[polySegExtra, diffSeg, poly]; polySegExtra _ polySegExtra.next; ENDLOOP; }; ENDLOOP; END; -- done with buried layer trapleft _ ALL[NIL]; gotBuried _ FALSE; END; StartTrap: PUBLIC PROCEDURE [eleft: Edge, layer: CARDINAL] = BEGIN IF eleft = NIL THEN WriteLine["StartTrap called with NIL value for eleft"]; SELECT layer FROM poly => BEGIN IF In[diff] AND NOT In[buried] THEN BEGIN EndTrap[eleft, diff]; -- end of diffusion IF In[implant] THEN StartTrap[eleft, depl] -- start of transistor ELSE StartTrap[eleft, enha]; END; trapleft[layer] _ eleft; END; diff => IF In[poly] AND NOT In[buried] THEN BEGIN IF In[implant] THEN StartTrap[eleft, depl] -- start of transistor ELSE StartTrap[eleft, enha]; RETURN; -- do not record start of diffusion END ELSE trapleft[layer] _ eleft; buried => BEGIN trapleft[layer] _ eleft; IF In[poly] AND In[diff] THEN BEGIN IF In[implant] THEN EndTrap[eleft, depl] --end of transistor ELSE EndTrap[eleft, enha]; StartTrap[eleft, diff]; END; END; implant => BEGIN IF In[poly] AND In[diff] AND NOT In[buried] THEN BEGIN -- transistor is now deplection EndTrap[eleft, enha]; -- end enhancement StartTrap[eleft, depl]; -- start deplection END; trapleft[layer] _ eleft; END; ENDCASE => trapleft[layer] _ eleft; END; EndTrap: PUBLIC PROCEDURE [eright: Edge, layer: CARDINAL] = BEGIN eleft: Edge _ trapleft[layer]; xleft: REAL _ XatY[eleft, YPrev]; -- only if eleft # NIL xright: REAL _ XatY[eright, YPrev]; leftTop: REAL _ XatY[eleft, YCurr]; rightTop: REAL _ XatY[eright, YCurr]; LLength: REAL _ EdgeLength[eleft, YCurr, YPrev]; RLength: REAL _ EdgeLength[eright, YCurr, YPrev]; node: NodeNumberType; Propagate: PROCEDURE = -- Propagate maintains node numbers -- The node number is stored in node BEGIN nodeSeg, newNodeSeg, nodeSegExtra: NodeSegment; -- DrawTrap[eleft,YPrev,eright,YCurr,layer]; ** on screen FOR nodeSeg _ NodeList[layer], NodeList[layer] UNTIL nodeSeg = NIL OR xleft <= nodeSeg.right DO NodeList[layer] _ nodeSeg.next; ENDLOOP; --allocate a new node segment for the trapezoid newNodeSeg _ MakeNodeSegment[ NIL, XatY[eleft, YCurr], XatY[eright, YCurr], (layer = depl OR layer = enha)]; ptrnewNodeList[layer]^ _ newNodeSeg; ptrnewNodeList[layer] _ @newNodeSeg.next; --establish a node number for the trapezoid IF nodeSeg = NIL OR xright < nodeSeg.left THEN BEGIN node _ GenNodeNumber[layer]; IF layer # depl AND layer # enha THEN WITH n: newNodeSeg SELECT FALSE FROM FALSE => BEGIN -- calculate the area and perimeter for the node WriteNodeLocation[ node, (xleft + xright)/2, (YPrev + YCurr)/2, layer]; LLength _ EdgeLength[eleft, YCurr, YPrev]; RLength _ EdgeLength[eright, YCurr, YPrev]; n.circumference _ [0.0, 0.0, 0.0, 0.0]; n.area _ [0.0, 0.0, 0.0, 0.0]; n.area[layer] _ (YCurr - YPrev)*((xright - xleft) + ((xleft - leftTop) + (rightTop - xright))/2); n.circumference[layer] _ (xright - xleft) + (rightTop - leftTop) + LLength + RLength; n.mark _ TRUE; END ENDCASE ELSE BEGIN trans: Transistor _ NodeToTransistor[node]; trans.x _ (xleft + xright)/2; trans.y _ (YPrev + YCurr)/2; END; END ELSE BEGIN --propogate from below -- Adjust Node Segment for common perimeter IF NOT (layer = depl OR layer = enha) THEN WITH n2: nodeSeg SELECT FALSE FROM FALSE => n2.circumference[layer] _ n2.circumference[layer] - 2*(MIN[xright,n2.right] - MAX[xleft,n2.left]); ENDCASE; FOR nodeSegExtra _ nodeSeg.next, nodeSeg.next UNTIL nodeSegExtra = NIL OR nodeSegExtra.left > xright DO -- propagate transistors IF layer = depl OR layer = enha THEN BEGIN trans1: Transistor _ NodeToTransistor[nodeSeg.number]; trans2: Transistor _ NodeToTransistor[nodeSegExtra.number]; trans1.circumference _ trans1.circumference + trans2.circumference - (nodeSeg.right - MAX[xleft, nodeSeg.left]); trans2.circumference _ 0; END -- propagate nodes ELSE WITH n2: nodeSegExtra SELECT FALSE FROM FALSE => WITH n3: nodeSeg SELECT FALSE FROM FALSE => BEGIN -- Combine Node Areas n3.area[diff] _ n2.area[diff] + n3.area[diff]; n3.area[poly] _ n2.area[poly] + n3.area[poly]; n3.area[metal] _ n2.area[metal] + n3.area[metal]; -- Combine Node Perimeters n3.circumference[diff] _ n2.circumference[diff] + n3.circumference[diff]; n3.circumference[poly] _ n2.circumference[poly] + n3.circumference[poly]; n3.circumference[metal] _ n2.circumference[metal] + n3.circumference[metal]; -- Correct Node Perimeter for current layer n3.circumference[layer] _ n3.circumference[layer] - 2*(MIN[xright,n2.right] - MAX[xleft,n2.left]); -- Mark and Unmark the three nodes n2.mark _ FALSE; n3.mark _ TRUE; n2.circumference _ [0.0, 0.0, 0.0, 0.0]; n2.area _ [0.0, 0.0, 0.0, 0.0]; END ENDCASE ENDCASE; Combine[nodeSeg, nodeSegExtra, layer]; NodeList[layer] _ nodeSeg _ nodeSegExtra; ENDLOOP; node _ nodeSeg.number; IF layer = depl OR layer = enha THEN BEGIN trans: Transistor _ NodeToTransistor[node]; trans.circumference _ trans.circumference - (2*(MIN[nodeSeg.right, xright] - MAX[nodeSeg.left, xleft])); END ELSE BEGIN WITH n1: newNodeSeg SELECT FALSE FROM FALSE => BEGIN -- calculate the area and perimeter for the node LLength _ EdgeLength[eleft, YCurr, YPrev]; RLength _ EdgeLength[eright, YCurr, YPrev]; n1.circumference _ [0.0, 0.0, 0.0, 0.0]; n1.area _ [0.0, 0.0, 0.0, 0.0]; n1.area[layer] _ (YCurr - YPrev)*((xright - xleft) + ((xleft - leftTop) + (rightTop - xright))/2); n1.circumference[layer] _ (xright - xleft) + (rightTop - leftTop) + LLength + RLength; END ENDCASE; WITH n1: nodeSeg SELECT FALSE FROM FALSE => WITH n3: newNodeSeg SELECT FALSE FROM FALSE => BEGIN -- Combine Node Areas n3.area[diff] _ n1.area[diff] + n3.area[diff]; n3.area[poly] _ n1.area[poly] + n3.area[poly]; n3.area[metal] _ n1.area[metal] + n3.area[metal]; -- Combine Node Perimeters n3.circumference[diff] _ n1.circumference[diff] + n3.circumference[diff]; n3.circumference[poly] _ n1.circumference[poly] + n3.circumference[poly]; n3.circumference[metal] _ n1.circumference[metal] + n3.circumference[metal]; -- Mark and Unmark the three nodes n1.mark _ FALSE; n3.mark _ TRUE; n1.circumference _ [0.0, 0.0, 0.0, 0.0]; n1.area _ [0.0, 0.0, 0.0, 0.0]; END ENDCASE ENDCASE END; END; newNodeSeg.number _ node; IF layer = depl OR layer = enha THEN BEGIN leftTop _ XatY[eleft, YCurr]; rightTop _ XatY[eright, YCurr]; WITH t: newNodeSeg SELECT TRUE FROM TRUE => BEGIN trans: Transistor _ NodeToTransistor[node]; t.leftLength _ EdgeLength[eleft, YCurr, YPrev]; t.rightLength _ EdgeLength[eright, YCurr, YPrev]; trans.area _ trans.area + (YCurr - YPrev)*((xright - xleft) + ((xleft - leftTop) + (rightTop - xright))/2); trans.circumference _ trans.circumference + (xright - xleft) + (rightTop - leftTop) + t.leftLength + t.rightLength; END; ENDCASE; END; CheckForLabel[eleft,eright,node,layer]; END; FindGate: PROCEDURE = INLINE BEGIN length: REAL; nodeSeg: NodeSegment; FOR deplNodeList _ deplNodeList, deplNodeList.next UNTIL deplNodeList = NIL OR deplNodeList.right > xleft DO ENDLOOP; FOR nodeSeg _ deplNodeList, nodeSeg.next UNTIL nodeSeg = NIL OR nodeSeg.left > xright DO -- At this point we know that the transistor's right side is past the -- diffusion's left and that the diffusion's right is not past the -- transistor's left side, -- therefore the transistor and the diffusion intersect. length _ MIN[nodeSeg.right, xright] - MAX[nodeSeg.left, xleft]; SetDiff[NodeToTransistor[nodeSeg.number], node, length]; ENDLOOP; FOR enhaNodeList _ enhaNodeList, enhaNodeList.next UNTIL enhaNodeList = NIL OR enhaNodeList.right > xleft DO ENDLOOP; FOR nodeSeg _ enhaNodeList, nodeSeg.next UNTIL nodeSeg = NIL OR nodeSeg.left > xright DO -- At this point we know that the transistor's right side is past the -- diffusion's left and that the diffusion's right is not past the -- transistor's left side, -- therefore the transistor and the diffusion intersect. length _ MIN[nodeSeg.right, xright] - MAX[nodeSeg.left, xleft]; SetDiff[NodeToTransistor[nodeSeg.number], node, length]; ENDLOOP; END; FindDiff: PROCEDURE = INLINE BEGIN length: REAL; nodeSeg: NodeSegment; FOR diffNodeList _ diffNodeList, diffNodeList.next UNTIL diffNodeList = NIL OR diffNodeList.right > xleft DO ENDLOOP; FOR nodeSeg _ diffNodeList, nodeSeg.next UNTIL nodeSeg = NIL OR nodeSeg.left > xright DO -- At this point we know that the transistor's right side is past the -- diffusion's left and that the diffusion's right is not past the -- transistor's left side, -- therefore the transistor and the diffusion intersect. length _ MIN[nodeSeg.right, xright] - MAX[nodeSeg.left, xleft]; SetDiff[NodeToTransistor[node], nodeSeg.number, length]; ENDLOOP; END; MakeContact: PROCEDURE = INLINE BEGIN nodeSeg: NodeSegment; node _ LOOPHOLE[LONG[0]]; nodeSeg _ MakeNodeSegment[node, XatY[eleft, YCurr], XatY[eright, YCurr]]; ptrnewNodeList[layer]^ _ nodeSeg; ptrnewNodeList[layer] _ @nodeSeg.next; END; IF eleft # NIL THEN xleft _ XatY[eleft, YPrev] ELSE xleft _ 0; -- Avoid zero width trapezoids IF xleft = xright AND XatY[eleft, YCurr] = XatY[eright, YCurr] THEN RETURN; SELECT layer FROM metal => Propagate[]; poly => BEGIN Propagate[]; IF In[diff] AND NOT In[buried] THEN BEGIN IF In[implant] THEN EndTrap[eright, depl] ELSE EndTrap[eright, enha]; StartTrap[eright, diff]; END; END; diff => IF In[poly] AND NOT In[buried] THEN IF In[implant] THEN EndTrap[eright, depl] ELSE EndTrap[eright, enha] ELSE BEGIN Propagate; -- see if there is a gate below FindGate; END; depl, enha => BEGIN Propagate; IF layer = depl THEN NodeToTransistor[node].ion _ TRUE; -- see if there is diffusion below FindDiff; END; buried => BEGIN gotBuried _ TRUE; IF In[diff] AND In[poly] THEN BEGIN EndTrap[eright, diff]; IF In[implant] THEN StartTrap[eright, depl] -- start of transistor ELSE StartTrap[eright, enha]; END; END; implant => IF In[poly] AND In[diff] AND NOT In[buried] THEN BEGIN -- End of deplection EndTrap[eright, depl]; StartTrap[eright, enha]; -- Start enhancement END; contact => MakeContact[]; ENDCASE -- => DrawTrap[eleft,YPrev,eright,YCurr,layer] -- ; END; CheckForLabel: PROCEDURE[eleft,eright: Edge, node: NodeNumberType, layer:CARDINAL] = INLINE BEGIN label: NodeLabel; FOR label _ LabelList,label.next UNTIL label = NIL DO IF XatY[eleft,label.y] < label.x AND label.x < XatY[eright,label.y] AND YPrev <= label.y AND label.y <= YCurr THEN IF label.layer = undef OR label.layer = layer THEN { WriteNodeLabel[label,node]; WriteNodeLocation[node,label.x,label.y,7]; --DrawString[label.label,label.x,label.y]; label.used _ TRUE; }; ENDLOOP; END; gotBuried: BOOLEAN; END. (635)\24317b13B520b1B