<> <> <> <> <<>> 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.STREAM _ NIL; 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: BOOL _ FALSE] = { 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] ]; }; }; <> RootWireInstances: PROC [design: CD.Design, root: Core.CellType, flatWire: CoreFlat.FlatWireRec, onlyOne: BOOL _ FALSE] 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: BOOL _ FALSE, 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.