TestHighlight.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Barth, December 5, 1986 5:46:38 pm PST
Bertrand Serlet February 25, 1987 6:33:53 pm PST
DIRECTORY CD, CDBasics, CDInstances, CDViewer, CDViewHighlight, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, HashTable, IO, Rope, Sinix, SinixOps, SinixRawCMosB, Static, ViewerClasses, ViewerIO, ViewerOps;
TestHighlight: CEDAR PROGRAM
IMPORTS CDBasics, CDInstances, CDViewer, CDViewHighlight, CoreClasses, CoreFlat, CoreGeometry, CoreOps, HashTable, SinixOps, SinixRawCMosB, Static, IO, ViewerIO, ViewerOps
SHARES CoreGeometry
= BEGIN
tsin, tsout: IO.STREAMNIL;
StaticCheckReportGeometrically: PROC [design: CD.Design, rootObject: CD.Object, root: Core.CellType] = {
CheckReportGeometrically: Static.ConnectionCountProc = {
[count: INT, wireRoot: Core.Wire, wire: Core.Wire, public: BOOL, cellType: Core.CellType, unconnectedOK: BOOL]
IF (NOT unconnectedOK) AND ((public AND count<1) OR (NOT public AND count<2)) THEN {
IO.PutRope[tsout, CoreOps.GetFullWireName[wireRoot, wire]];
IO.PutRope[tsout, IF public THEN " of cell " ELSE " in cell "];
IO.PutRope[tsout, CoreOps.GetCellTypeName[cellType]];
IO.PutRope[tsout, " has "];
SELECT count FROM
0 => IO.PutRope[tsout, "no connection"];
1 => IO.PutRope[tsout, "only one connection"];
ENDCASE => ERROR;
HighlightFlatWire[design, rootObject, root, [flatCell: AnyFlatCell[root, cellType], wireRoot: IF public THEN public ELSE internal, wire: wire], viewer, TRUE];
[] ← IO.PutRope[tsout, " Proceed?"];
[] ← IO.GetChar[tsin];
};
};
viewer: ViewerClasses.Viewer ← FindViewer[design];
IF tsin=NIL THEN {
[tsin, tsout] ← ViewerIO.CreateViewerStreams[name: " Static Script"];
IO.PutRope[tsout, "\n"];
};
Static.CountLeafConnections[root, CheckReportGeometrically];
IO.PutRope[tsout, "\n"];
CDViewHighlight.RemoveAll[viewer];
};
AnyFlatCell: PROC [root: Core.CellType, cellType: Core.CellType] RETURNS [flatCellType: CoreFlat.FlatCellTypeRec ← []] = {
Find: PROC [cell: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec ← []] RETURNS [BOOL] = {
IF HashTable.Fetch[cellTypeVisit, cell].found THEN RETURN [FALSE];
IF NOT HashTable.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: HashTable.Table ← HashTable.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[design, 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 => ERROR; -- 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], 30*design.technology.lambda] ];
};
};
The following procedure assumes that flatWire has been normalized to the highest internal and that it is an atomic wire.
RootWireInstances: PROC [design: CD.Design, root: Core.CellType, flatWire: CoreFlat.FlatWireRec, onlyOne: BOOLFALSE] RETURNS [instances: CoreGeometry.Instances] = {
MoveToWireRoot: CoreFlat.UnboundFlatCellProc = {
IF CoreFlat.FlatCellTypeEqualRec[target, flatCell] THEN {
instances ← VisitBoundCells[cell, LIST[flatWire.wire]].instances;
IF onlyOne AND instances#NIL THEN instances ← LIST[instances.first];
}
ELSE CoreFlat.NextUnboundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, MoveToWireRoot];
IF instance#NIL AND cell=instance.type
THEN instances ← CoreGeometry.TransformList[CoreGeometry.GetTrans[decoration, instance], instances];
};
VisitBoundCells: PROC [cellType: Core.CellType, internals: Core.Wires] RETURNS [quit: BOOLFALSE, instances: CoreGeometry.Instances ← NIL] = {
FOR wires: Core.Wires ← internals, wires.rest UNTIL wires=NIL DO
instances ← CoreGeometry.GetGeometry[decoration, wires.first];
IF instances#NIL AND onlyOne THEN {
quit ← TRUE;
RETURN;
}
ELSE NULL; -- really should concatenate the instance lists
ENDLOOP;
SELECT TRUE FROM
cellType.class=CoreClasses.transistorCellClass => NULL; -- really need to explode the geometry in the transistor
cellType.class=CoreClasses.recordCellClass => {
rct: CoreClasses.RecordCellType ← NARROW[cellType.data];
FOR i: NAT IN [0..rct.size) DO
NewPublics: CoreOps.EachWirePairProc = {
IF CoreOps.Member[internals, actualWire] THEN publics ← CONS[publicWire, publics];
};
instance: CoreClasses.CellInstance ← rct[i];
publics: Core.Wires ← NIL;
IF CoreOps.VisitBindingSeq[instance.actual, instance.type.public, NewPublics] THEN ERROR;
IF publics#NIL THEN {
subQuit: BOOL;
subInstances: CoreGeometry.Instances;
[subQuit, subInstances] ← VisitBoundCells[instance.type, publics];
IF subInstances#NIL THEN {
-- really should concatenate the instance lists
instances ← CoreGeometry.TransformList[CoreGeometry.GetTrans[decoration, instance], subInstances];
quit ← subQuit;
IF quit THEN RETURN;
};
};
ENDLOOP;
};
ENDCASE => {
NewPublics: CoreOps.EachWirePairProc = {
IF CoreOps.Member[internals, actualWire] THEN publics ← CONS[publicWire, publics];
};
thisCell: Core.CellType ← CoreOps.Recast[cellType];
publics: Core.Wires ← NIL;
IF CoreOps.VisitBindingSeq[cellType.public, thisCell.public, NewPublics] THEN ERROR;
[quit, instances] ← VisitBoundCells[thisCell, publics];
};
};
decoration: CoreGeometry.Decoration = SinixRawCMosB.mode.decoration;
MoveToWireRoot[cell: root, target: flatWire.flatCell];
};
END.