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]
;
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: BOOLEAN ← TRUE;
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.ROPE ← NARROW[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];