reportMsg: Rope.ROPE;
rules: Rope.ROPE;
fileServer: UnixRemoteFile.UnixServerHandle ← UnixRemoteFile.CreateHandle[fileHost];
myName: Rope.ROPE ← SunAuthUnix.FixNameForUnix[UserCredentials.Get[].name];
workingDir: Rope.ROPE ← Rope.Cat[remoteServerDir, myName];
{
ENABLE
ABORTED, Process.InvalidProcess => {
reportMsg ← "DRC ABORTED";
GOTO Failed
};
CatchOne: UnixRemoteFile.EachNameProc ~ {
IF Rope.Fetch[name, 0]#'. THEN victimList ← CONS[Rope.Cat[workingDir, "/", name], victimList];
};
victimList: LIST OF ROPE;
topCellName, fileName: ROPE;
remoteFile, log: IO.STREAM;
sizeX, sizeY, minX, minY, maxX, maxY: REAL;
nX, nY: NAT;
hasErrors: BOOLEAN ← FALSE;
lambda: REAL ← design.technology.lambda; -- conversion from INT
dx: REAL ← (instance.ob.bbox.x2-instance.ob.bbox.x1)/lambda;
ox: REAL ← instance.ob.bbox.x1/lambda;
dy: REAL ← (instance.ob.bbox.y2-instance.ob.bbox.y1)/lambda;
oy: REAL ← instance.ob.bbox.y1/lambda;
topCellName ← CDDirectory.Name[instance.ob, design];
IF topCellName=NIL THEN {reportMsg ← "Impossible to DRC non named objects"; GOTO Failed;};
UnixRemoteFile.MkDir[fileServer, [workingDir], 0666B ! UnixRemoteFile.Error => {
IF code=$exist
THEN {
TerminalIO.PutRope[Rope.Cat["Dracula Warning: ", fileHost, ":", workingDir, " already exists\n"]];
CONTINUE;
}
ELSE {
reportMsg ← IO.PutFR["Dracula Error: %g (%g)\n", IO.rope[msg], IO.atom[code]];
GOTO Failed;
}
}];
fileName ← Rope.Cat[workingDir, "/", topCellName, cifExt];
remoteFile ← UnixRemoteFile.OpenWriteStream[fileServer, [fileName], 0666B ! UnixRemoteFile.Error =>
{reportMsg ← IO.PutFR["WriteError: %g (%g)\n", IO.rope[msg], IO.atom[code]]; GOTO Failed;}];
TerminalIO.PutRopes["Dracula DRC. CIF file: ", fileName, "\n"];
reportMsg ← CDToCif.WriteCIF[design, instance, remoteFile, cifPerLambda, flattenAtomics];
IO.Close[remoteFile];
IF reportMsg#NIL THEN GOTO Failed;
[sizeX, sizeY, nX, nY] ← GetJobSize[dx, dy];
minX ← ox-overlap;
maxX ← ox+sizeX+overlap;
THROUGH [0..nX)
DO
minY ← oy-overlap;
maxY ← oy+sizeY+overlap;
THROUGH [0..nY)
DO
fileName ← Rope.Cat[workingDir, "/", topCellName, descrExt];
remoteFile ← UnixRemoteFile.OpenWriteStream[fileServer, [fileName], 0666B ! UnixRemoteFile.Error =>
{reportMsg ← IO.PutFR["WriteError: %g (%g)\n", IO.rope[msg], IO.atom[code]]; GOTO Failed;}];
IO.PutFL[stream: remoteFile, format: description, list:
LIST[
[rope[topCellName]], -- PRIMARY = cellName
[real[minX]], [real[minY]], [real[maxX]], [real[maxY]], --WINDOW x1 y1 x2 y2
[rope[topCellName]], -- INDISK = %g.cif
[rope[topCellName]] ]]; -- OUTDISK = %g.errors.cif
IO.Close[remoteFile];
log ← FS.StreamOpen[fileName: Rope.Cat[topCellName, ".log"], accessOptions: create];
IF nX#1 OR nY#1 THEN TerminalIO.PutF["Dracula: Now DRCing [%d, %d, %d, %d]\n", [real[minX]], [real[minY]], [real[maxX]], [real[maxY]]];
reportMsg ← Rsh.RSH[
remoteMachine: cpuHost,
command: Rope.Cat[Rope.Cat["cd ", workingDir, "; "], ecadCmd, topCellName, " ", rules], --i.e. cd /tmp/lecocq/; /usr/ecad/bin/dracula thisCell VTI
in: IO.noInputStream, out: log, error: TerminalIO.TOS[]
];
IO.Close[log];
IF reportMsg#NIL THEN GOTO Failed;
fileName ← Rope.Cat[workingDir, "/", logFile];
remoteFile ← UnixRemoteFile.OpenReadStream[fileServer, [fileName] ! UnixRemoteFile.Error =>
{reportMsg ← IO.PutFR["ReadError: %g (%g)\n", IO.rope[msg], IO.atom[code]]; GOTO Failed;}];
IF CheckForErrors[remoteFile !
IO.Error,
IO.EndOfStream => {reportMsg ← "Bad or no DRCSUM file";
GOTO Failed;}]
THEN {
fileName ← Rope.Cat[workingDir, "/", topCellName, errorsExt];
remoteFile ← UnixRemoteFile.OpenReadStream[fileServer, [fileName] ! UnixRemoteFile.Error =>
{reportMsg ← IO.PutFR["ReadError: %g (%g)\n", IO.rope[msg], IO.atom[code]]; CONTINUE;}];
IF reportMsg#NIL THEN GOTO Failed;
reportMsg ← CifToCD.ReadFile[remoteFile, design, ecadKey, instance.trans];
IF reportMsg#NIL THEN GOTO Failed;
hasErrors ← TRUE;
};
minY ← minY+sizeY;
maxY ← maxY+sizeY;
ENDLOOP;
minX ← minX+sizeX;
maxX ← maxX+sizeX;
ENDLOOP;
IF hasErrors THEN CDOps.RedrawInstance[design, instance]
ELSE TerminalIO.PutRope["\n*\n* Dracula: No DRC Errors !\n*\n"];
UnixRemoteFile.Enumerate[fileServer, [workingDir], "*", CatchOne];
UNTIL victimList=
NIL
DO
UnixRemoteFile.Delete[fileServer, [victimList.first]];
victimList ← victimList.rest;
ENDLOOP;
UnixRemoteFile.RmDir[fileServer, [workingDir]]
EXITS Failed => {TerminalIO.PutRope[reportMsg]; result ← reportMsg;}
};