-- 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
--
TYPES1 = 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.