File: MPCControl.Mesa
Derived from MEBESControl of November 26, 1979
November 1979 by MN
Updated: August 22, 1980 8:27 PM
TRS convert to new Parser/Interpreter December 10, 1980
TRS change for storing file remote as BINARY March 10, 1981
PJM added 1um spot capability November 22, 1983 3:07 PM
Last Edited by: McCreight, February 18, 1985 1:50:41 pm PST
DIRECTORY
BasicTime, FS, IntDefs, IntTransDefs, IO, IODefs, LayerFileDefs, MPCDefs, MPCParserDefs, OutputDefs, ParserDefs, ParserErrorDefs, ParserInputDefs, Rope;
MPCControl: CEDAR PROGRAM
IMPORTS
FS, IntDefs, IO, IODefs, IntTransDefs, LayerFileDefs, OutputDefs, ParserDefs, ParserErrorDefs, ParserInputDefs, Rope
EXPORTS MPCDefs =
BEGIN
space: Rope.ROPE = " ";
InitMPC: PUBLIC PROCEDURE [mpc: REF MPCDefs.MPCDescriptor]
RETURNS [ok: BOOLEAN] =
Set overall parameters
date must have exactly 6 characters (mmddyy)
BEGIN
IODefs.PrintTime[" InitMPC"];
IODefs.WriteString[" "];
IODefs.WriteString[mpc.title];
IODefs.WriteString[space];
IODefs.WriteString[mpc.date];
IODefs.WriteString[space];
IODefs.WriteLine[mpc.account];
ok ← mpc.title.Length <= 7 AND mpc.date.Length = 6 AND mpc.account.Length <= 20;
END;
InitWafer: PUBLIC PROCEDURE [wafer: REF MPCDefs.WaferDescriptor]
RETURNS [ok: BOOLEAN] =
Set wafer parameters
BEGIN
IODefs.PrintTime[" InitWafer"];
IODefs.WriteString[" "];
IODefs.WriteString[wafer.waferName];
IODefs.WriteString[space];
IODefs.WriteReal[wafer.waferSizeX];
IODefs.WriteString[space];
IODefs.WriteReal[wafer.waferSizeY];
IODefs.WriteString[space];
IODefs.WriteReal[wafer.outputUnitsPerMicron];
IODefs.WriteLine[""];
ok ← (SELECT wafer.outputUnitsPerMicron FROM 1, 2, 4 => TRUE, ENDCASE => FALSE)
AND wafer.inMPC.title.Length+wafer.waferName.Length <= 7;
END;
InitChip: PUBLIC PROCEDURE [chip: REF MPCDefs.ChipDescriptor]
RETURNS [ok: BOOLEAN] =
Set chip parameters
chipName must have no more than 7 characters
chipSizeX, chipSizeY are in microns
positionOnWafer is not yet implemented
BEGIN
IODefs.PrintTime[" InitChip"];
IODefs.WriteString[" "];
IODefs.WriteString[chip.chipName];
IODefs.WriteString[space];
IODefs.WriteReal[chip.chipSizeX];
IODefs.WriteString[space];
IODefs.WriteReal[chip.chipSizeY];
IODefs.WriteLine[""];
ok ← chip.inWafer.inMPC.title.Length + chip.inWafer.waferName.Length + chip.chipName.Length = 7 AND
OutputDefs.InitOutput[chip];
END;
ConvertProject: PUBLIC PROCEDURE [project: REF MPCDefs.ProjectDescriptor]
RETURNS [
ok: BOOLEAN,
errorSummary: ARRAY ParserErrorDefs.ErrorType OF CARDINAL] =
Set Project parameters and convert the project
rotateX, rotateY are as in CIF
translateX, translateY are in microns
layerArray provides correspondence between CIF layer names and
the internal fileLayer (normally to be numbered sequentially from
zero - used in WriteLayerFile) and with the stretches to be
used (in microns)
The errorSummary returned is a copy of the one from ParserErrorDefs
BEGIN
bias: LONG INTEGER; --Rounding fudge in CIF units to jog coords away from half units
aborted: BOOLEANFALSE;
bias ← 8/project.inChip.inWafer.outputUnitsPerMicron;
IODefs.PrintTime[" ConvertProject"];
IODefs.WriteLine[IO.PutFR[" %g", IO.rope[UniqueID[project.cifFileName]]]];
IODefs.WriteLine[IO.PutFR[" %g %g %g %g", IO.real[project.rotateX], IO.real[project.rotateY], IO.real[project.translateX], IO.real[project.translateY]]];
ok ← TRUE;
errorSummary ← ALL[0];
[] ← OutputDefs.InitProject[project];
IF ~ParserDefs.InitParser[] OR ~ParserInputDefs.InFromFile[project.cifFileName] THEN RETURN[FALSE, errorSummary];
IF ~IntDefs.InitInterpreter[] THEN RETURN[FALSE, errorSummary];
Main loop to convert CIF file
BEGIN
ENABLE
ParserErrorDefs.ParserAbort =>
BEGIN aborted ← TRUE; IODefs.WriteLine["---Parser aborted---"]; CONTINUE; END;
nStatements: INT ← 0;
DO
SELECT ParserDefs.ParseStatement[] FROM
End => BEGIN nStatements ← nStatements + 1; EXIT; END;
SemanticError, SyntaxError =>
IF ParserInputDefs.EndOfFile[] THEN aborted ← TRUE;
ENDCASE;
nStatements ← nStatements + 1;
IF nStatements MOD 100 = 0 THEN
IODefs.PostIt[IO.PutFR["CIF File: %g, Statement: %g...", IO.rope[project.cifFileName], IO.int[nStatements]]];
IF ParserInputDefs.EndOfFile[] THEN
BEGIN
IODefs.WriteLine[
"Unexpected end of input file, Probably missing End command"];
aborted ← TRUE;
END;
ENDLOOP;
END; --End of Enable clause
errorSummary ← ParserErrorDefs.ErrorSummary[];
[] ← ParserDefs.FinishParser[];
IntTransDefs.Push[];
IntTransDefs.Rotate[project.rotateX, project.rotateY]; --Orient project
IntTransDefs.Translate[(project.translateX*100) + bias, (project.translateY*100) + bias]; --Position project(converting to CIF units)
IntTransDefs.Scale[project.inChip.inWafer.outputUnitsPerMicron, 100]; --CIF units to Output(Mebes) units
IntTransDefs.Push[]; --Just in case next transformation user doesn't
ok ← ~aborted
AND
(errorSummary[Fatal] + errorSummary[FatalSyntax] + errorSummary[
FatalSemantic] + errorSummary[FatalInternal]) = 0;
IF ok THEN IntDefs.Instantiate[];
IntTransDefs.Pop[]; --to match safety Push
IntTransDefs.Pop[]; --project transformation
[] ← IntDefs.FinishInterpreter[];
END;
WriteLayerFile: PUBLIC PROCEDURE [layerFile: MPCDefs.LayerFileItem, chip: REF MPCDefs.ChipDescriptor]
RETURNS [ok: BOOLEAN] =
Write Mebes layer file for internal fileLayer, using the Mebes
identification strings mebesLayerNumber and mebesLayerName
(e.g. "04" and "PO", respectively, for polysilicon)
BEGIN
totalChipName: Rope.ROPEIO.PutFR["%g%g%g",
IO.rope[chip.inWafer.inMPC.title], IO.rope[chip.inWafer.waferName],
IO.rope[chip.chipName]];
layerFileName: Rope.ROPEIO.PutFR["%g-%g-%g.mebes",
IO.rope[totalChipName], IO.rope[layerFile.layerNumber],
IO.rope[layerFile.layerName]];
layerNameString: Rope.ROPEIO.PutFR["%g%g.%g",
IO.rope[totalChipName], IO.rope[layerFile.layerNumber],
IO.rope[layerFile.layerName]];
IODefs.WriteLine[IO.PutFR[" WriteLayerFile %g %g %g ...", IO.rope[layerFile.layerNumber], IO.rope[layerFile.layerName], IO.time[]]];
LayerFileDefs.MakeLayerFile[
layerFileName, layerFile.pFileLayer, layerNameString, chip.inWafer.inMPC.date, " " -- mask shop info --,
chip.chipSizeX*chip.inWafer.outputUnitsPerMicron,
chip.chipSizeY*chip.inWafer.outputUnitsPerMicron,
chip.inWafer.outputUnitsPerMicron];
IODefs.WriteLine[IO.PutFR[" %g {%g} ... written", IO.rope[UniqueID[layerFileName]], IO.rope[layerNameString]]];
ok ← TRUE;
END;
FinishChip: PUBLIC PROCEDURE RETURNS [ok: BOOLEAN] =
BEGIN
IODefs.WriteString[" FinishChip -- "];
ok ← OutputDefs.FinishOutput[];
IODefs.PrintTime[" "];
END;
FinishWafer: PUBLIC PROCEDURE RETURNS [ok: BOOLEAN] =
Release all structures associated with the current wafer
BEGIN IODefs.PrintTime[" FinishWafer"]; RETURN[TRUE]; END;
FinishMPC: PUBLIC PROCEDURE RETURNS [ok: BOOLEAN] =
Release all structures associated with the whole run
BEGIN IODefs.PrintTime[" FinishMPC"]; RETURN[TRUE]; END;
UniqueID: PROC [ fileName: Rope.ROPE ] RETURNS [ id: Rope.ROPE ] =
BEGIN
fullFileName: Rope.ROPE ← fileName;
attachedTo: Rope.ROPENIL;
bytes: INT ← 0;
gmt: BasicTime.GMT ← BasicTime.nullGMT;
[fullFName: fullFileName, attachedTo: attachedTo, bytes: bytes, created: gmt] ← FS.FileInfo[name: fileName, remoteCheck: TRUE ! FS.Error => CONTINUE];
id ← IO.PutFR["%g%g (%g bytes) Of %g",
IO.rope[fullFileName],
IO.rope[(IF attachedTo.Length=0 THEN NIL ELSE IO.PutFR["(%g)", IO.rope[attachedTo]])],
IO.int[bytes],
(IF gmt=BasicTime.nullGMT THEN IO.rope["??"] ELSE IO.time[gmt])];
END;
END.