<> <> <> <> <<>> DIRECTORY CD, CDBasics, CDInstances, CDViewer, CDViewHighlight, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, IO, MessageWindow, RefTab, Rope, Sinix, SinixOps, Static, TerminalIO, ViewerClasses, ViewerOps; TestHighlight: CEDAR PROGRAM IMPORTS CDBasics, CDInstances, CDViewer, CDViewHighlight, CoreClasses, CoreFlat, CoreGeometry, CoreOps, MessageWindow, RefTab, SinixOps, Static, IO, TerminalIO, ViewerOps SHARES CoreGeometry = BEGIN StaticCheckReportGeometrically: PROC [decoration: CoreGeometry.Decoration, design: CD.Design, rootObject: CD.Object, root: Core.CellType, first: INT _ 0, last: INT _ 99999, onlyOne: BOOL _ FALSE] = { 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 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[decoration, 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 [decoration: CoreGeometry.Decoration, design: CD.Design, rootObject: CD.Object, root: Core.CellType, flatWire: CoreFlat.FlatWireRec, viewer: ViewerClasses.Viewer, onlyOne: BOOL _ FALSE] = { geometry: CoreGeometry.Instances _ RootWireInstances[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]]; }; <> RootWireInstances: PROC [decoration: CoreGeometry.Decoration, root: Core.CellType, normFlatWire: CoreFlat.FlatWireRec, onlyOne: BOOL _ FALSE] RETURNS [instances: CoreGeometry.Instances _ NIL] = { <> 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.