TestHighlight.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Barth, December 5, 1986 5:46:38 pm PST
Bertrand Serlet May 8, 1987 4:09:14 pm PDT
DIRECTORY CD, CDBasics, CDInstances, CDViewer, CDViewHighlight, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, IO, MessageWindow, RefTab, Rope, Sinix, SinixOps, SinixRawCMosB, Static, TerminalIO, ViewerClasses, ViewerOps;
TestHighlight: CEDAR PROGRAM
IMPORTS CDBasics, CDInstances, CDViewer, CDViewHighlight, CoreClasses, CoreFlat, CoreGeometry, CoreOps, MessageWindow, RefTab, SinixOps, SinixRawCMosB, Static, IO, TerminalIO, ViewerOps
SHARES CoreGeometry
= BEGIN
StaticCheckReportGeometrically: PROC [design: CD.Design, rootObject: CD.Object, root: Core.CellType, first: INT ← 0, last: INT ← 99999, onlyOne: BOOLFALSE] = {
current: INT ← -1;
CheckReportGeometrically: Static.ConnectionCountProc = {
[count: INT, wireRoot: Core.Wire, wire: Core.Wire, public: BOOL, cellType: Core.CellType, unconnectedOK: BOOL]
wireName: Rope.ROPE ← "*****";
IF unconnectedOK OR NOT ((public AND count<1) OR (NOT public AND count<2)) THEN RETURN;
current ← current + 1;
IF current>last OR current<first THEN RETURN;
wireName ← CoreOps.GetFullWireName[wireRoot, wire ! ANY => CONTINUE];
TerminalIO.PutF[
"*** Static: %g %g cell %g has %g.\n",
IO.rope[wireName],
IO.rope[IF public THEN "of" ELSE "in"],
IO.rope[CoreOps.GetCellTypeName[cellType]],
IO.rope[SELECT count FROM 0 => "no connection", 1 => "only one connection", ENDCASE => ERROR]
];
HighlightFlatWire[design, rootObject, root, [flatCell: AnyFlatCell[root, cellType], wireRoot: IF public THEN public ELSE internal, wire: wire], viewer, onlyOne];
IF NOT MessageWindow.Confirm["Static: Proceed?"] THEN last ← current;
};
viewer: ViewerClasses.Viewer ← FindViewer[design];
Static.CountLeafConnections[root, CheckReportGeometrically];
CDViewHighlight.RemoveAll[viewer];
IF current=1
THEN TerminalIO.PutF["Static: No error.\n"]
ELSE TerminalIO.PutF["Static: %g errors found.\n", IO.int[current+1]];
};
AnyFlatCell: PROC [root: Core.CellType, cellType: Core.CellType] RETURNS [flatCellType: CoreFlat.FlatCellTypeRec ← []] = {
Find: PROC [cell: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec ← []] RETURNS [BOOL] = {
IF RefTab.Fetch[cellTypeVisit, cell].found THEN RETURN [FALSE];
IF NOT RefTab.Insert[cellTypeVisit, cell, $Visited] THEN ERROR;
IF cell=cellType THEN {
flatCellType ← flatCell;
RETURN [TRUE];
};
SELECT TRUE FROM
cell.class=CoreClasses.transistorCellClass => NULL;
cell.class=CoreClasses.recordCellClass => {
rct: CoreClasses.RecordCellType ← NARROW[cell.data];
FOR i: NAT IN [0..rct.size) DO
IF Find[rct[i].type, [CoreFlat.ExtendPath[flatCell.path, i, rct], 0]] THEN RETURN [TRUE];
ENDLOOP;
};
ENDCASE => IF Find[CoreOps.Recast[cell], [flatCell.path, flatCell.recastCount+1]] THEN RETURN [TRUE];
RETURN [FALSE];
};
cellTypeVisit: RefTab.Ref ← RefTab.Create[]; -- Marks visited cells
IF NOT Find[root] THEN ERROR; -- no such cell type reachable from root
};
FindViewer: PROC [design: CD.Design] RETURNS [viewer: ViewerClasses.Viewer] = {
viewer ← CDViewer.LastViewer[];
IF CDViewer.DesignOf[viewer]#design THEN {
viewers: CDViewer.ViewerList ← CDViewer.ViewersOf[design];
IF viewers=NIL THEN viewer ← CDViewer.CreateViewer[design]
ELSE viewer ← viewers.first;
};
};
TestHighLightError: SIGNAL [msg: Rope.ROPE] = CODE;
HighlightFlatWire: PROC [design: CD.Design, rootObject: CD.Object, root: Core.CellType, flatWire: CoreFlat.FlatWireRec, viewer: ViewerClasses.Viewer, onlyOne: BOOLFALSE] = {
geometry: CoreGeometry.Instances ← RootWireInstances[SinixRawCMosB.mode.decoration, root, flatWire, onlyOne];
highlight: CD.InstanceList ← NIL;
stack: LIST OF CD.PushRec ← design.actual;
topInstance: CD.Instance ← NIL;
UNTIL stack.rest=NIL DO
stack ← stack.rest;
ENDLOOP;
FOR topInstances: CD.InstanceList ← stack.first.specific.contents, topInstances.rest UNTIL topInstances=NIL DO
IF topInstances.first.ob=rootObject THEN {
topInstance ← topInstances.first;
EXIT;
};
REPEAT FINISHED => SIGNAL TestHighLightError["no instance of root object"];
ENDLOOP;
IF geometry=NIL THEN SIGNAL TestHighLightError["no geometry on this wire"]
ELSE {
geometry ← CoreGeometry.TransformList[topInstance.trans, geometry];
highlight ← SinixOps.HighLightListInst[geometry];
CDViewHighlight.ShowInstance[viewer, highlight];
ViewerOps.OpenIcon[viewer];
CDViewer.ShowAndScale[viewer: viewer, rect: CDBasics.Extend[CDInstances.InstRectO[highlight.first], 40*design.technology.lambda] ];
};
};
BindingContain: PROC [bindings: CoreFlat.Bindings, flatWire: CoreFlat.FlatWireRec] RETURNS [BOOL] = {
EachPublic: RefTab.EachPairAction = {
quit ← CoreFlat.FlatWireEqualRec[flatWire, NARROW [val, CoreFlat.FlatWire]^];
};
RETURN [RefTab.Pairs[bindings, EachPublic]];
};
The following procedure assumes that flatWire has been normalized to the highest internal and that it is an atomic wire.
RootWireInstances: PROC [decoration: CoreGeometry.Decoration, root: Core.CellType, normFlatWire: CoreFlat.FlatWireRec, onlyOne: BOOLFALSE] RETURNS [instances: CoreGeometry.Instances ← NIL] = {
We came from that one from a RecordCell [vertical move]
TransBoundFlat: CoreFlat.BoundFlatCellProc = {
trans: CoreGeometry.Transformation = CoreGeometry.GetTrans[decoration, instance];
refTrans: REF CoreGeometry.Transformation = NARROW [data];
currentTrans: CoreGeometry.Transformation = CDBasics.ComposeTransform[itemInCell: trans, cellInWorld: refTrans^];
BoundFlat[cell, target, flatCell, instance, index, parent, flatParent, NEW [CoreGeometry.Transformation ← currentTrans], bindings];
};
BoundFlat: CoreFlat.BoundFlatCellProc = {
refTrans: REF CoreGeometry.Transformation = NARROW [data];
IF target=CoreFlat.allFlatCells AND NOT BindingContain[bindings, normFlatWire] THEN RETURN;
IF CoreFlat.FlatCellTypeEqualRec[target, flatCell] THEN target ← CoreFlat.allFlatCells;
SELECT TRUE FROM
cell.class=CoreClasses.transistorCellClass => RETURN;
cell.class=CoreClasses.recordCellClass => {
RecordGeometry: CoreOps.EachWireProc = {
EachInstance: CoreGeometry.EachInstanceProc = {
instances ← CONS [CoreGeometry.Transform[refTrans^, instance], instances];
quit ← onlyOne;
};
refBoundWire: CoreFlat.FlatWire ← NARROW [RefTab.Fetch[bindings, wire].val];
IF CoreFlat.FlatWireEqualRec[normFlatWire, IF refBoundWire#NIL THEN refBoundWire^ ELSE [flatCell: flatCell, wire: wire]]
THEN quit ← CoreGeometry.EnumerateGeometry[decoration, wire, EachInstance];
};
rct: CoreClasses.RecordCellType = NARROW [cell.data];
IF target=CoreFlat.allFlatCells AND CoreOps.VisitWireSeq[rct.internal, RecordGeometry]
THEN RETURN;
CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, TransBoundFlat];
};
ENDCASE => CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, BoundFlat];
};
BoundFlat[cell: root, target: normFlatWire.flatCell, bindings: CoreFlat.InitialBindingTable[root], data: NEW [CoreGeometry.Transformation ← []]];
};
END.