LayoutSchematics.mesa
Copyright © 1984 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet June 8, 1986 10:16:41 pm PDT
Bertrand Serlet June 9, 1986 7:30:24 pm PDT
DIRECTORY
CD, CDCells, CDDirectory, CDMenus, CDOps, CDSequencer,
Core, CoreProperties, IO, PW, PWCore, Rope, RopeList, Sinix, SoS, Sisyph, ViewerIO, ViewerTools;
LayoutSchematics: CEDAR PROGRAM
IMPORTS CDCells, CDDirectory, CDMenus, CDOps, CoreProperties, IO, PW, PWCore, Rope, RopeList, Sinix, SoS, Sisyph, ViewerIO, ViewerTools =
BEGIN
ROPE: TYPE = Core.ROPE;
CellType: TYPE = Core.CellType;
Wire: TYPE = Core.Wire;
due to a bug in TerminalIO.WriteF that does a WriteRope
WriteBold: PROC [before, bold, after: ROPENIL] = {
stream: IO.STREAM ← ViewerIO.CreateViewerStreams ["Terminal", ViewerTools.FindExistingViewer ["Terminal"]].out;
IO.PutF[stream, "%g%l%g%l%g", IO.rope[before], IO.rope["b"], IO.rope[bold], IO.rope["B"], IO.rope[after]];
};
LayoutSchematics: PW.UserProc = {
testLichen: BOOL ← PWCore.testLichen;
checkAbuts: BOOL ← PWCore.checkAbuts;
cx: Sisyph.Context ← Sisyph.Create[design];
selected: CD.Instance; multiple: BOOL;
[selected, multiple] ← CDOps.SelectedInstance[design];
IF selected=NIL THEN {PW.WriteF["\n** No current selection --can't do it.\n"]; RETURN};
IF multiple THEN {PW.WriteF["\n** Multiple instances selected --can't do it.\n"]; RETURN};
IF NOT CDCells.IsCell[selected.ob] THEN {PW.WriteF["\n** Not a cell --can't do it.\n"]; RETURN};
IF NOT Rope.Match["*.sch", CDDirectory.Name[selected.ob]] THEN {PW.WriteF["\n** Not a schematics --can't do it.\n"]; RETURN};
PWCore.testLichen ← TRUE;
PWCore.checkAbuts ← TRUE;
PW.WriteF["\nGenerating layout for %g.\n", IO.rope[CDDirectory.Name[selected.ob]]];
ob ← CheckObject[design, cx, selected.ob].layout;
PWCore.testLichen ← testLichen;
PWCore.checkAbuts ← checkAbuts;
};
CheckObject: PROC [design: CD.Design, cx: Sisyph.Context, obj: CD.Object] RETURNS [ok: BOOLTRUE, layout: CD.Object ← NIL] = {
name: ROPE ← CDDirectory.Name[obj];
cellType: CellType ← Sisyph.ES[name, cx ! ANY => {WriteBold["Sisyph extraction fails for ", name, ".\n"]; GOTO Fails}];
IF CoreProperties.GetCellTypeProp[cellType, PWCore.layoutAtomProp]=NIL THEN {
extracted: CellType;
name ← Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-4], PWCore.maskSuffix];
layout ← CDDirectory.Fetch[design, name].object;
IF layout=NIL THEN RETURN;
extracted ← NARROW [Sinix.Extract[layout, PWCore.extractMode! ANY => {WriteBold["Sinix extraction fails for ", name, " .\n"]; GOTO Fails}].result];
PWCore.DecorateGet[cellType, layout ! ANY => {WriteBold["Comparison with schematics fails for ", name, " .\n"]; GOTO Fails}];
} ELSE layout ← PWCore.Layout[cellType ! ANY => {WriteBold["Layout generation fails for ", name, " .\n"]; GOTO Fails}];
SoS.CheckDesignRules [cellType, design , NIL, NEW [BOOLFALSE], FALSE, NIL, PWCore.extractMode.instanceProp, PWCore.extractMode.wireGeometryProp ! ANY => {WriteBold["DRC fails for ", name, " .\n"]; GOTO Fails}];
IF CoreProperties.GetCellTypeProp[cellType, SoS.DRVkey]#NIL THEN {WriteBold["DRC errors in cell ", name, " .\n"]; GOTO Fails};
EXITS Fails => RETURN [FALSE, layout];
};
Cat: PROC [list: LIST OF ROPE] RETURNS [catted: ROPENIL] = {
WHILE list#NIL DO catted ← Rope.Cat[catted, " ", list.first]; list ← list.rest ENDLOOP;
};
CheckSchematics: PROC [command: CDSequencer.Command] = {
testLichen: BOOL ← PWCore.testLichen;
checkAbuts: BOOL ← PWCore.checkAbuts;
cx: Sisyph.Context ← Sisyph.Create[command.design];
checked, notSch, notOk: LIST OF ROPE;
sel, notCells: INT ← 0;
PW.WriteF["Check schematics\n"];
PWCore.testLichen ← TRUE;
PWCore.checkAbuts ← TRUE;
FOR instances: CD.InstanceList ← CDOps.InstList[command.design], instances.rest WHILE instances#NIL DO
obj: CD.Object ← instances.first.ob;
name: ROPE ← CDDirectory.Name[obj];
IF NOT instances.first.selected THEN LOOP;
sel ← sel + 1;
IF NOT CDCells.IsCell[obj] THEN {notCells ← notCells + 1; LOOP};
IF Rope.Match[Rope.Cat["*", PWCore.maskSuffix], name] THEN {
schName: ROPE ← Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-5], ".sch"];
sch: CD.Object ← CDDirectory.Fetch[command.design, schName].object;
IF sch#NIL AND CDCells.IsCell[sch] THEN {name ← schName; obj ← sch};
};
IF NOT Rope.Match["*.sch", name] THEN {
IF NOT RopeList.Memb[notSch, name] THEN notSch ← CONS [name, notSch]; LOOP;
};
IF RopeList.Memb[checked, name] THEN LOOP;
checked ← CONS [name, checked];
IF NOT CheckObject[command.design, cx, obj].ok THEN notOk ← CONS [name, notOk];
ENDLOOP;
PW.WriteF["%g instances selected.", IO.int[sel]];
IF notCells#0 THEN PW.WriteF[" %g instances not cells.", IO.int[notCells]];
IF notSch#NIL THEN PW.WriteF["\n%gcells not schematics.\n", IO.rope[Cat[notSch]]];
PW.WriteF[" %g schematics checked.\n", IO.int[RopeList.Length[checked]]];
IF notOk#NIL THEN WriteBold["", Cat[notOk], " not ok.\n"];
IF notOk=NIL AND notCells=0 THEN WriteBold["", "OK", ".\n"];
PWCore.testLichen ← testLichen;
PWCore.checkAbuts ← checkAbuts;
};
PW.Register[LayoutSchematics, "Layout selected schematics"];
CDMenus.ImplementEntryCommand[$ProgramMenu, "Check selected Schematics", CheckSchematics];
END.