-- File CIFDrcError.mesa -- Written by Dan Fitzpatrick and Martin Newell, August 1980 -- Last updated: November 5, 1981 7:11 PM DIRECTORY CIFIODefs: FROM "CIFIODefs" USING [WriteLongDecimal, GetShort, GetReal, GetLong, WriteLineDirect, WriteLong, WriteStringDirect], CIFDrcErrorDefs: FROM "CIFDrcErrorDefs", CIFDrcUtilsDefs: FROM "CIFDrcUtilsDefs" USING [DisplayTrap, Edge, Trapezoid, TrapType, Tag, MakeEdge, MakeTrap, FreeTrap, FreeEdge], IODefs: FROM "IODefs" USING [WriteString, WriteLine, WriteDecimal, GetOutputStream, SetOutputStream], MergeDefs: FROM "MergeDefs" USING [Lookup, MergeValue], Real: FROM "Real" USING [Fix], StreamDefs: FROM "StreamDefs" USING [DiskHandle, StreamHandle, NewByteStream], SegmentDefs: FROM "SegmentDefs" USING [Read,Write,Append]; CIFDrcError: PROGRAM IMPORTS CIFDrcUtilsDefs, CIFIODefs, IODefs, MergeDefs, Real, StreamDefs EXPORTS CIFDrcErrorDefs = BEGIN OPEN CIFIODefs, CIFDrcUtilsDefs, IODefs, MergeDefs, Real, StreamDefs, SegmentDefs; InitError: PROCEDURE[baseName:STRING] = BEGIN x: CARDINAL; inFileName: STRING _ Tag[baseName,"tmp$"]; outFileName: STRING _ Tag[baseName,"DRV"]; logFileName: STRING _ Tag[baseName,"drclog"]; errorFile _ NewByteStream[inFileName,Read]; errorFile.reset[errorFile]; x _ GetShort[errorFile]; IF x # ErrorPassword THEN BEGIN WriteString[inFileName]; WriteLine[" is not a valid Error File"]; END; cifFile _ NewByteStream[outFileName,Write+Append]; cifFile.reset[cifFile]; defaultStream _ GetOutputStream[]; logFile _ NewByteStream[logFileName,Write+Append]; logFile.reset[logFile]; SetOutputStream[logFile]; WriteLineDirect["(Design Rule Violations);",cifFile]; ErrorCount _ 0; END; FinishError: PROCEDURE = BEGIN errorFile.destroy[errorFile]; cifFile.destroy[cifFile]; SetOutputStream[defaultStream]; logFile.destroy[logFile]; END; ErrorPass: PUBLIC PROCEDURE[baseName:STRING] = BEGIN InitError[baseName]; UNTIL errorFile.endof[errorFile] DO ReadError[]; ENDLOOP; FinishError[]; IF ErrorCount = 0 THEN WriteLine["No design rule violations found"] ELSE { WriteString["Design Rule Violations recorded on "]; WriteString[baseName]; WriteString[".drclog(CIF in "]; WriteString[baseName]; WriteLine[".DRV)"]; } END; ReadError: PROCEDURE = -- Read an error record from error file -- The format of an error record is as follows: -- type:INTEGER idenifies the type of error -- layer:CARDINAL identifies the layer on which the error occured -- ymin,ymax: REAL(long) minimum & maximum y extent of error trapezoid -- blx,tlx,brx,trx:REAL(Long) bottom left, top left, bot. right, & top right x -- type dependent information -- if type = 2 (minimum seperation violation) -- node1, node2:Long node numbers of voilating instances -- TYPES 1 = minimum width violation -- 2 = minimum seperation violation BEGIN type: INTEGER; layer:CARDINAL; miny,maxy,blx,tlx,brx,trx:REAL; left,right: Edge; trap: Trapezoid; type _ GetShort[errorFile]; layer _ GetShort[errorFile]; miny _ GetReal[errorFile]; maxy _ GetReal[errorFile]; blx _ GetReal[errorFile]; tlx _ GetReal[errorFile]; brx _ GetReal[errorFile]; trx _ GetReal[errorFile]; SELECT type FROM 1 => BEGIN -- Minimum Width Violation ErrorCount _ ErrorCount + 1; WriteLongDecimal[Fix[(blx+brx)/2]]; WriteString[" "]; WriteLongDecimal[Fix[(miny+maxy)/2]]; WriteString[" Minimum Width Violation on "]; WriteLayer[layer]; WriteLine[""]; left _ MakeEdge[blx,miny,tlx,maxy,TRUE]; right _ MakeEdge[brx,miny,trx,maxy,TRUE]; trap _ MakeTrap[left,right,miny,maxy,7,mask]; DisplayTrap[trap]; FreeEdge[left]; FreeEdge[right]; FreeTrap[trap]; WriteStringDirect["L MW",cifFile]; WriteStringDirect["; P ",cifFile]; WriteLong[Fix[blx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[miny],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[tlx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[maxy],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[trx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[maxy],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[brx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[miny],cifFile]; WriteLineDirect[";",cifFile]; END; 2 => BEGIN -- Minimum Seperation Violation node1,node2:MergeValue; node1 _ Lookup[GetLong[errorFile]]; node2 _ Lookup[GetLong[errorFile]]; IF node1 = node2 AND NOT IgnoreConnectivity AND node1 # NIL THEN RETURN; --This is not an error ErrorCount _ ErrorCount + 1; WriteLongDecimal[Fix[(blx+brx)/2]]; WriteString[" "]; WriteLongDecimal[Fix[(miny+maxy)/2]]; WriteString[" Minimum Seperation Violation on "]; WriteLayer[layer]; WriteString[", between nodes "]; WriteLongDecimal[LOOPHOLE[node1]]; WriteString[" & "]; WriteLongDecimal[LOOPHOLE[node2]]; WriteLine[""]; left _ MakeEdge[blx,miny,tlx,maxy,TRUE]; right _ MakeEdge[brx,miny,trx,maxy,TRUE]; trap _ MakeTrap[left,right,miny,maxy,7,mask]; DisplayTrap[trap]; FreeEdge[left]; FreeEdge[right]; FreeTrap[trap]; WriteStringDirect["L MS",cifFile]; WriteStringDirect["; P ",cifFile]; WriteLong[Fix[blx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[miny],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[tlx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[maxy],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[trx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[maxy],cifFile]; WriteStringDirect[", ",cifFile]; WriteLong[Fix[brx],cifFile]; WriteStringDirect[" ",cifFile]; WriteLong[Fix[miny],cifFile]; WriteLineDirect[";",cifFile]; END; ENDCASE => BEGIN ErrorCount _ ErrorCount + 1; WriteString["*** Unknown error record type("]; WriteDecimal[type]; WriteLine[") encountered in error file ***"]; END; END; WriteLayer: PUBLIC PROCEDURE [layer:CARDINAL] = BEGIN SELECT layer FROM implant => WriteString["implant"]; diff => WriteString["diffusion"]; poly => WriteString["poly"]; cut => WriteString["cut"]; metal => WriteString["metal"]; transistor => WriteString["transistor"]; ENDCASE => WriteString["unknown layer"]; END; ToggleConnectivity: PUBLIC PROCEDURE RETURNS[ConnectSet:BOOLEAN] = BEGIN ConnectSet _ IgnoreConnectivity; IgnoreConnectivity _ NOT IgnoreConnectivity; END; implant:CARDINAL = 0; diff:CARDINAL = 1; poly:CARDINAL = 2; cut:CARDINAL = 3; metal:CARDINAL = 4; transistor:CARDINAL = 6; ErrorCount:CARDINAL _ 3; errorFile:DiskHandle; cifFile:DiskHandle; logFile:StreamHandle; defaultStream:StreamHandle; ErrorPassword:CARDINAL = 12346; IgnoreConnectivity: BOOLEAN _ FALSE; -- If set ignore the connectivity properties of -- the circuit, electrically connected nodes may not -- violate seperation rules END. (672)\129b10B633b11B200b9B691b12B144b10B400b9B3765b11B321b19B