CifCDCmds.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Christian Le Cocq September 18, 1987 2:40:50 pm PDT
Last Edited by: Gasbarro April 27, 1988 11:21:49 am PDT
Don Curry January 17, 1989 8:33:04 pm PST
DIRECTORY
Atom USING [MakeAtom],
CD,
CDBasics,
CDCells,
CDCommandOps USING [RegisterWithMenu],
CDIO,
CDImports USING [HasUnloadedImports],
CDDirectory,
CDSequencer USING [Command],
CDOps,
CDProperties,
CDViewer USING [CreateViewer],
CDToCif USING [WriteCIF],
CifToCD USING [ReadFile],
CMosB,
Commander USING [CommandProc, Register],
CommandTool,
FileNames,
FS USING [binaryStreamOptions, StreamOpen, Error],
IO,
Rope,
TerminalIO USING [PutRope, PutRopes, RequestRope]
;
CifCDCmds: CEDAR PROGRAM
IMPORTS
Atom, CD, CDBasics, CDCells, CDCommandOps, CDImports, CDDirectory, CDIO, CDOps, CDProperties, CDViewer, CDToCif, CifToCD, CMosB, Commander, CommandTool, FileNames,
FS, IO, Rope, TerminalIO
~ BEGIN
cifExt: Rope.ROPE ← ".cif";
regKey: ATOM ← $EcadErrorsCif;
cifPerLambda: INT ← 100;
commented: BOOLEANTRUE;
CDToCifCmd: PROC [comm: CDSequencer.Command] ~ {
Called by ChipNDale upon activation of the command.
topCellName, fileName, msg: Rope.ROPE;
cifFile: IO.STREAM;
mainInst: CD.Instance;
flattenAtomics: BOOLEAN;
IF CDCells.IsPushedIn[comm.design] THEN {
TerminalIO.PutRope["**Design is pushed in\n"];
GOTO Exit
};
IF CDImports.HasUnloadedImports[comm.design].yes THEN {
TerminalIO.PutRope["**Design has non bound imports\n"];
GOTO Exit
};
mainInst ← CDOps.TheInstance[comm.design, "cif generation\n"];
IF mainInst=NIL THEN {
TerminalIO.PutRope["**CIF generation needs single selected object\n"];
GOTO Exit
};
topCellName ← CDDirectory.Name[mainInst.ob, comm.design];
fileName ← Rope.Cat[topCellName, cifExt];
cifFile ← FS.StreamOpen[fileName, create !
FS.Error =>
IF error.group#bug THEN {
TerminalIO.PutRope[error.explanation];
GOTO Exit;  
}
];
TerminalIO.PutRopes["CIF file generated: ", fileName, "\n"];
flattenAtomics ← CDProperties.GetProp[$CDxCIFRegistrations, $CDxFlattenAtomic]=$TRUE;
msg ← CDToCif.WriteCIF[comm.design, mainInst, cifFile, cifPerLambda, flattenAtomics];
TerminalIO.PutRope["CD -> CIF cmd finished\n"];
EXITS Exit => {TerminalIO.PutRope[" CD -> CIF cmd failed\n"]};
};
CifToCDCmd: PROC [comm: CDSequencer.Command] ~ {
Called by ChipNDale upon activation of the command.
cifFile: IO.STREAM;
msg: Rope.ROPE;
fileName: Rope.ROPE ← TerminalIO.RequestRope["CIF file: "];
cifFile ← FS.StreamOpen[fileName, read !
FS.Error =>
IF error.group#bug THEN {
TerminalIO.PutRope[error.explanation];
GOTO Exit;  
}
];
msg ← CifToCD.ReadFile[cifFile, comm.design, regKey, , , commented];
IF msg#NIL THEN {TerminalIO.PutRope[msg]; GOTO Exit};
TerminalIO.PutRope["CIF -> CD cmd finished\n"];
CDOps.Redraw[comm.design];
EXITS Exit => {TerminalIO.PutRope[" CIF -> CD cmd failed\n"]}};
ReadCifComm: Commander.CommandProc ~ {
library: CD.Design ← CDOps.CreateDesign[CMosB.cmosB];
wDir:  Rope.ROPE ← CommandTool.CurrentWorkingDirectory[];
nofArgs: INT;
objs:  LIST OF CD.Object;
CDOps.SetMutability[library];
CommandTool.StarExpansion[cmd];
nofArgs     ← CommandTool.NumArgs[cmd];
SELECT nofArgs FROM
1 => msg ← doc;
2 => msg ← Rope.Concat["Too few arguments", doc];
ENDCASE => {
key: ATOM ← Atom.MakeAtom[CommandTool.ArgN[cmd, 1]];
FOR arg: INT IN [2..nofArgs) DO
design: CD.Design ← CDOps.CreateDesign[CMosB.cmosB];
fileName: Rope.ROPE ← CommandTool.ArgN[cmd, arg];
root:  Rope.ROPE ← FileNames.GetShortName[fileName];
cdFile: Rope.ROPE;
obj:  CD.Object;
root ← root.Substr[0, root.Index[0, "."]];
cdFile ← CDIO.MakeName[root, ".dale", wDir];
IF Rope.Find[fileName, "."] = -1 THEN fileName ← Rope.Concat[fileName, ".cif"];
CDOps.SetMutability[design];
msg ← CifToCD.ReadFile[
FS.StreamOpen[
fileName:   fileName,
accessOptions: $read,
streamOptions: FS.binaryStreamOptions,
wDir:    wDir
! FS.Error => {msg ← error.explanation; GOTO Failed} ],
design, key];
IF msg#NIL THEN GOTO Failed;
obj ← CDOps.InstList[design].first.ob;
[] ← CDDirectory.Rename[design, obj, root];
[] ← CDOps.RenameDesign[design, root];
[] ← CDIO.WriteDesign[design, cdFile];
obj ← CDDirectory.AnotherRecursed[obj, library, design];
CDProperties.PutProp[obj, $CellName, root];
cmd.out.PutF[" File: %g\n", IO.rope[cdFile]];
IF nofArgs=3
THEN [] ← CDViewer.CreateViewer[design, FALSE]
ELSE objs ← CONS[obj, objs];
REPEAT Failed => {result ← $Failure} ENDLOOP };
IF nofArgs>3 THEN {
libraryName: IO.ROPE ← "CifLibrary";
sep:  INT ← CMosB.cmosB.lambda*16;
pos:  CD.Position ← [0,0];
temp:  LIST OF CD.Object;
FOR objs ← objs, objs.rest WHILE objs#NIL DO
temp  ← CONS[objs.first, temp] ENDLOOP;
WHILE temp#NIL DO
off:  CD.Position ← CDBasics.SubPoints[pos, CDBasics.BaseOfRect[CD.InterestRect[temp.first]]];
shift:  INT ← ((CD.InterestSize[temp.first].x+sep+sep-1)/sep)*sep;
name:  IO.ROPENARROW[CDProperties.GetProp[temp.first, $CellName]];
CDProperties.PutProp[temp.first, $CellName, NIL];
[] ← CDDirectory.Include[library, temp.first, name];
[] ← CDOps.IncludeObject[library, temp.first, [off]];
temp ← temp.rest;
pos ← [pos.x + shift, pos.y] ENDLOOP;
[] ← CDOps.RenameDesign[library, libraryName];
[] ← CDIO.WriteDesign[library, libraryName];
[] ← CDViewer.CreateViewer[library, FALSE]}};
doc: Rope.ROPE ← "\nRead a cif file into ChipNDale\n Usage: ReadCif <registrationKey> <file1.cif> <file2.cif> . . .\n";
Commander.Register[key:"ReadCif", proc: ReadCifComm, doc: doc];
CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "CD->CIF", doc: "Writes a CIF file", key: $CDToCifSel, proc: CDToCifCmd];
CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "CIF->CD", doc: "Reads a CIF file", key: $CifToCDSel, proc: CifToCDCmd];
END.