DIRECTORY Buttons, ChoiceButtons, Containers, Convert, Core, CoreClasses, CoreFlat, CoreOps, HashTable, IO, Ports, Process, Rope, ReadEvalPrint, Rosemary, RosemaryUser, Rules, ViewerClasses, ViewerIO, ViewerOps, ViewerTools; RosemaryUserImpl: CEDAR MONITOR IMPORTS Buttons, ChoiceButtons, Containers, Convert, CoreClasses, CoreFlat, CoreOps, HashTable, IO, Ports, Process, Rope, ReadEvalPrint, Rosemary, Rules, ViewerIO, ViewerOps, ViewerTools EXPORTS RosemaryUser = BEGIN OPEN RosemaryUser; entryHeight: NAT = 15; -- how tall to make each line of items entryVSpace: NAT = 4; -- vertical leading space between lines pointsPerInch: NAT = 72; -- horizontal space for text ropes borderOffset: NAT = 2; Column: TYPE = NAT [0..3); ColumnStart: ARRAY Column OF NAT = [entryVSpace, 1*pointsPerInch+entryVSpace, 4*pointsPerInch+entryVSpace]; Tester: TYPE = REF TesterRec; TesterRec: TYPE = RECORD [ testPort: Ports.Port _ NIL, intermediatePort: Ports.Port _ NIL, runState: ViewerClasses.Viewer _ NIL, evalsSinceStart: ViewerClasses.Viewer _ NIL, evalSinceStartCount: INT, proceedUntil: ViewerClasses.Viewer _ NIL, evalUntil: INT, historyTrigger: ViewerClasses.Viewer _ NIL, historyTriggerCount: INT, currentStatePoint: NAT _ 0, displayedStatePoint: NAT _ 0, validStates: NAT _ 0, historySize: NAT _ 0, testVectorBuffer: Rosemary.PortSequence _ NIL, proceed: CONDITION, testStarted: BOOL _ FALSE, waiting: BOOL _ FALSE, abort: BOOL _ FALSE, interrupt: BOOL _ FALSE, singleEval: BOOL _ FALSE, testButtonList: LIST OF Buttons.Button, currentTestProc: ROPE _ NIL, logChanges: BOOL _ FALSE, display: RoseDisplay _ NIL]; DisplayWireHandle: TYPE = REF DisplayWireHandleRec; DisplayWireHandleRec: TYPE = RECORD[ packedPath: CoreFlat.PackedPath, wire: Core.Wire, wireSize: NAT]; testProcTable: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; DisplayViewer: PUBLIC PROC [simulation: Rosemary.Simulation, cellType: Core.CellType, name: ROPE _ NIL, displayWires: CoreFlat.FlatWires _ NIL] RETURNS [handle: RoseDisplay] = { viewer: ViewerClasses.Viewer_ Containers.Create[[ name: name, iconic: FALSE, column: left, scrollable: FALSE ]]; handle _ NEW[RoseDisplayRec]; handle.simulation _ simulation; handle.cellType _ cellType; MakeDisplayAndBrowse[displayWires: displayWires, height: entryVSpace, handle: handle, viewer: viewer, name: name]; }; TestProcedureViewer: PUBLIC PROC [cellType: Core.CellType, testButtons: LIST OF ROPE, name: ROPE _ NIL, displayWires: CoreFlat.FlatWires _ NIL, flatten: BOOL _ FALSE, cutSets: LIST OF ROPE _ NIL, historySize: NAT _ 0] RETURNS [simulation: Rosemary.Simulation] = { viewer: ViewerClasses.Viewer_ Containers.Create[[ name: name, iconic: FALSE, column: left, scrollable: FALSE ]]; height: CARDINAL _ entryVSpace; h: Tester _ NEW[TesterRec]; h.display _ NEW[RoseDisplayRec]; h.display.cellType _ cellType; h.testPort _ Ports.CreatePort[cellType.public, TRUE]; h.intermediatePort _ Ports.CreatePort[cellType.public, TRUE]; simulation _ h.display.simulation _ IF flatten THEN Rosemary.InstantiateInstances[cellType, h.intermediatePort, cutSets, historySize] ELSE Rosemary.InstantiateCellType[cellType, h.intermediatePort, historySize]; IF historySize>0 THEN { h.historySize _ historySize; h.testVectorBuffer _ NEW[Rosemary.PortSequenceRec[historySize]]; FOR b: NAT IN [0..historySize) DO h.testVectorBuffer[b] _ Ports.CreatePort[cellType.public, TRUE]; ENDLOOP; }; [] _ Buttons.Create[info: [name: "Start Test", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: StartTest]; h.runState _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[1], y: height-borderOffset, title: "Run State:", textViewerWidth: 2*pointsPerInch].textViewer; ViewerTools.InhibitUserEdits[h.runState]; ViewerTools.SetContents[h.runState, "Idle"]; IF historySize>0 THEN h.historyTrigger _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[2], y: height-borderOffset, title: "History Trigger:", textViewerWidth: 2*pointsPerInch].textViewer; height _ height + entryHeight + entryVSpace; [] _ Buttons.Create[info: [name: "Interrupt", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: Interrupt]; h.evalsSinceStart _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[1], y: height-borderOffset, title: "Evals Since Start:", textViewerWidth: 1*pointsPerInch].textViewer; ViewerTools.InhibitUserEdits[h.evalsSinceStart]; IF historySize>0 THEN [] _ Buttons.Create[info: [name: "Next State", wx: ColumnStart[2], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: NextState]; height _ height + entryHeight + entryVSpace; [] _ Buttons.Create[info: [name: "Proceed", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: Proceed]; h.proceedUntil _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[1], y: height-borderOffset, title: "Proceed Until:", textViewerWidth: 1*pointsPerInch].textViewer; IF historySize>0 THEN [] _ Buttons.Create[info: [name: "Previous State", wx: ColumnStart[2], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: PreviousState]; height _ height + entryHeight + entryVSpace; [] _ Buttons.Create[info: [name: "Abort", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: Abort, guarded: TRUE]; [] _ Buttons.Create[info: [name: "Single Eval", wx: ColumnStart[1]+borderOffset, wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: SingleEval]; height _ height + entryHeight + entryVSpace; [] _ Buttons.Create[info: [name: "Log", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: LogChanges]; height _ height + entryHeight + entryVSpace; Containers.ChildXBound[viewer, Rules.Create[[parent: viewer, wy: height, ww: viewer.cw, wh: 2]]]; height _ height + entryVSpace; IF testButtons.rest#NIL THEN { Column: TYPE = NAT [0..3); ColumnStart: ARRAY Column OF NAT = [entryVSpace, 2*pointsPerInch+entryVSpace, 4*pointsPerInch+entryVSpace]; column: Column _ 0; first: Buttons.Button _ NIL; FOR tbs: LIST OF ROPE _ testButtons, tbs.rest UNTIL tbs=NIL DO this: Buttons.Button _ Buttons.Create[info: [name: tbs.first, wx: ColumnStart[column], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: h, proc: TestButtonProc]; h.testButtonList _ CONS[this, h.testButtonList]; IF first=NIL THEN first _ this; IF column=LAST[Column] THEN { column _ 0; height _ height + entryHeight + entryVSpace; } ELSE column _ column+1; ENDLOOP; IF column>0 THEN height _ height + entryHeight + entryVSpace; Buttons.SetDisplayStyle[first, $BlackOnGrey]; Containers.ChildXBound[viewer, Rules.Create[[parent: viewer, wy: height, ww: viewer.cw, wh: 2]]]; height _ height + entryVSpace; }; h.currentTestProc _ testButtons.first; MakeDisplayAndBrowse[displayWires, height, h.display, viewer, name]; }; MakeDisplayAndBrowse: PROC [displayWires: CoreFlat.FlatWires, height: CARDINAL, handle: RoseDisplay, viewer: ViewerClasses.Viewer, name: ROPE] = { IF displayWires#NIL THEN { Column: TYPE = NAT [0..2); ColumnStart: ARRAY Column OF NAT = [entryVSpace, 3*pointsPerInch+pointsPerInch/4+entryVSpace]; column: Column _ 0; FOR dws: CoreFlat.FlatWires _ displayWires, dws.rest UNTIL dws=NIL DO handle.displayWires _ CONS[ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[column], y: height-borderOffset, title: CoreFlat.WirePathRope[handle.cellType, dws.first^], textViewerWidth: pointsPerInch, clientdata: dws.first], handle.displayWires]; ViewerTools.InhibitUserEdits[handle.displayWires.first.textViewer]; IF column=LAST[Column] THEN { column _ 0; height _ height + entryHeight + entryVSpace; } ELSE column _ column+1; ENDLOOP; IF column>0 THEN height _ height + entryHeight + entryVSpace; Containers.ChildXBound[viewer, Rules.Create[[parent: viewer, wy: height, ww: viewer.cw, wh: 2]]]; height _ height + entryVSpace; }; [] _ Buttons.Create[info: [name: "Update", wx: ColumnStart[0], wy: height, ww: 0, wh: entryHeight, parent: viewer, border: TRUE], clientData: handle, proc: UpdateDisplayButton]; height _ height + entryHeight + entryVSpace; handle.path _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[0], y: height-borderOffset, title: "Instantiation Path:", textViewerWidth: 4*pointsPerInch].textViewer; height _ height + entryHeight + entryVSpace; handle.currentWire _ ChoiceButtons.BuildTextPrompt[viewer: viewer, x: ColumnStart[0], y: height-borderOffset, title: "Current Wire:", textViewerWidth: 4*pointsPerInch].textViewer; height _ height + entryHeight + entryVSpace; Containers.ChildXBound[viewer, Rules.Create[[parent: viewer, wy: height, ww: viewer.cw, wh: 2]]]; height _ height + entryVSpace; { rep: ReadEvalPrint.Handle; [handle.tsin, handle.tsout] _ ViewerIO.CreateViewerStreams[name: Rope.Cat[name, " Rosemary Script"]]; rep _ ReadEvalPrint.CreateStreamEvaluator[clientProc: ExploreDesign, prompt: "%l> %l", in: handle.tsin, out: handle.tsout, topLevel: TRUE]; rep.clientData _ handle; ReadEvalPrint.MainLoop[h: rep, properties: NIL]; height _ height + 10 * entryHeight; height _ height + entryHeight + entryVSpace/2; }; ViewerOps.SetOpenHeight[viewer, height]; ViewerOps.PaintViewer[viewer, all]; }; LogChanges: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; IF (h.logChanges _ ~h.logChanges) THEN { Buttons.SetDisplayStyle[NARROW[parent], $WhiteOnBlack]; } ELSE Buttons.SetDisplayStyle[NARROW[parent], $BlackOnWhite]; }; RegisterTestProc: PUBLIC PROC [name: ROPE, proc: TestProc] = { [] _ HashTable.Store[table: testProcTable, key: name, value: NEW[TestProc _ proc]]; }; TestButtonProc: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; selectedButton: ViewerClasses.Viewer _ NARROW[parent]; FOR l: LIST OF Buttons.Button _ h.testButtonList, l.rest WHILE l#NIL DO Buttons.SetDisplayStyle[l.first, IF l.first = selectedButton THEN $BlackOnGrey ELSE $BlackOnWhite]; ENDLOOP; h.currentTestProc _ selectedButton.name; }; AbortSignal: SIGNAL = CODE; StartTest: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; IF NOT AlreadyStarted[h] THEN DoStartTest[h]; }; DoStartTest: PROC [h: Tester] = { Eval: PROC = { UpdateWire: Rosemary.UpdateProc = { coreWire: CoreFlat.FlatWireRec; IF h.abort THEN SIGNAL AbortSignal; IF NOT h.logChanges THEN RETURN; UpdateDisplay[h.display]; coreWire _ Rosemary.GetWirePath[wire]; wireKey^ _ coreWire; IO.PutF[h.display.tsout, "%g_%g ", IO.rope[CoreFlat.WirePathRope[h.display.cellType, coreWire]], IO.rope[Ports.LevelSequenceToRope[Rosemary.WireValue[ h.display.simulation, wireKey]]]]; }; DO inBuf: BOOL _ h.displayedStatePoint#h.currentStatePoint AND h.validStates>0; testPort: Ports.Port _ IF inBuf THEN h.testVectorBuffer[NextBuf[h, h.displayedStatePoint]] ELSE h.testPort; Ports.CopyPortValue[from: testPort, to: h.intermediatePort]; Rosemary.Settle[h.display.simulation, UpdateWire]; IF h.logChanges THEN IO.PutRope[h.display.tsout, "\n\n"]; UpdateESSC[h, h.evalSinceStartCount+1]; IF h.evalSinceStartCount>=h.historyTriggerCount AND NOT inBuf AND h.historySize>0 THEN { h.currentStatePoint _ NextBuf[h, h.currentStatePoint]; h.displayedStatePoint _ h.currentStatePoint; IF h.validStates < h.historySize THEN h.validStates _ h.validStates + 1; Rosemary.StatePoint[h.display.simulation, h.currentStatePoint]; Ports.CopyPortValue[from: h.testPort, to: h.testVectorBuffer[h.currentStatePoint]]; }; Ports.CheckPortValue[root: h.display.cellType.public, truth: testPort, question: h.intermediatePort ! Ports.CheckError => UpdateDisplay[h.display]]; IF EvalsFinished[h] THEN SIGNAL AbortSignal; IF inBuf THEN { h.displayedStatePoint _ NextBuf[h, h.displayedStatePoint]; IF h.displayedStatePoint=h.currentStatePoint THEN EXIT; } ELSE EXIT; ENDLOOP; }; wireKey: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec]; testProc: TestProc _ NARROW[HashTable.Fetch[table: testProcTable, key: h.currentTestProc].value, REF TestProc]^; IF testProc=NIL THEN ERROR; UpdateESSC[h, 0]; h.validStates _ 0; SetEvalUntil[h: h, interrupt: FALSE, abort: FALSE]; ViewerTools.SetContents[h.runState, "Running"]; testProc[h.display.cellType, h.testPort, Eval ! AbortSignal => CONTINUE; UNWIND => FinishedTest[h]]; FinishedTest[h]; }; AlreadyStarted: ENTRY PROC [h: Tester] RETURNS [started: BOOL] = { started _ h.testStarted OR h.singleEval; h.testStarted _ TRUE; BROADCAST h.proceed; }; FinishedTest: ENTRY PROC [h: Tester] = { UpdateDisplay[h.display]; ViewerTools.SetContents[h.runState, "Idle"]; h.testStarted _ FALSE; BROADCAST h.proceed; }; Interrupt: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; SetEvalUntil[h: h, interrupt: TRUE, abort: FALSE]; }; Proceed: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; SetEvalUntil[h: h, interrupt: FALSE, abort: FALSE]; }; Abort: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; SetEvalUntil[h: h, interrupt: FALSE, abort: TRUE]; }; SingleEval: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; DoSingleEval[h]; SetEvalUntil[h: h, interrupt: TRUE, abort: FALSE]; }; DoSingleEval: ENTRY PROC [h: Tester] = { h.singleEval _ TRUE; IF h.testStarted THEN { h.interrupt _ TRUE; UNTIL h.waiting OR NOT h.testStarted DO WAIT h.proceed ENDLOOP; IF h.testStarted THEN { count: INT _ h.evalSinceStartCount; until: INT _ h.evalUntil; h.evalUntil _ count+1; h.interrupt _ FALSE; BROADCAST h.proceed; UNTIL h.evalSinceStartCount > count OR h.abort OR NOT h.testStarted DO WAIT h.proceed; ENDLOOP; h.interrupt _ TRUE; h.evalUntil _ until; }; } ELSE TRUSTED { h.evalUntil _ 1; h.testStarted _ TRUE; Process.Detach[FORK DoStartTest[h]]; UNTIL h.waiting OR h.abort DO WAIT h.proceed ENDLOOP; }; h.singleEval _ FALSE; }; NextState: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; DoNextState[h]; }; DoNextState: ENTRY PROC [h: Tester] = { IF h.waiting AND NOT h.singleEval THEN { IF h.displayedStatePoint=h.currentStatePoint THEN IO.PutRope[h.display.tsout, "No next state"] ELSE { h.displayedStatePoint _ NextBuf[h, h.displayedStatePoint]; Rosemary.RestoreState[h.display.simulation, h.displayedStatePoint]; UpdateESSC[h, h.evalSinceStartCount+1]; UpdateDisplay[h.display]; }; }; }; PreviousState: Buttons.ButtonProc = { h: Tester _ NARROW[clientData]; DoPreviousState[h]; }; DoPreviousState: ENTRY PROC [h: Tester] = { IF h.waiting AND NOT h.singleEval THEN { ndsp: NAT _ IF h.displayedStatePoint=0 THEN h.historySize-1 ELSE h.displayedStatePoint-1; SELECT TRUE FROM ndsp>=h.validStates => IO.PutRope[h.display.tsout, "No previous state, not enough evals since history trigger"]; ndsp=h.currentStatePoint => IO.PutRope[h.display.tsout, "No previous state, buffer depth exceeded"]; ENDCASE => { h.displayedStatePoint _ ndsp; Rosemary.RestoreState[h.display.simulation, h.displayedStatePoint]; UpdateESSC[h, h.evalSinceStartCount-1]; UpdateDisplay[h.display]; }; }; }; SetEvalUntil: PROC [h: Tester, interrupt: BOOL, abort: BOOL] = { GetCount: PROC [v: ViewerClasses.Viewer] RETURNS [count: INT] = { IF v=NIL THEN count _ 0 ELSE { vRope: ROPE _ ViewerTools.GetContents[v]; count _ LAST[INT]; IF vRope#NIL THEN count _ Convert.IntFromRope[vRope ! Convert.Error => CONTINUE]; }; }; SetUntil[h, GetCount[h.proceedUntil], GetCount[h.historyTrigger], interrupt, abort]; }; SetUntil: ENTRY PROC [h: Tester, count: INT, trigger: INT, interrupt: BOOL, abort: BOOL] = { IF NOT h.singleEval THEN { h.evalUntil _ count; h.historyTriggerCount _ trigger; IF trigger>h.evalSinceStartCount THEN h.validStates _ 0; h.interrupt _ interrupt; }; h.abort _ abort; BROADCAST h.proceed; }; EvalsFinished: ENTRY PROC [h: Tester] RETURNS [abort: BOOL] = { resetRunState: BOOL _ FALSE; WHILE (h.evalUntil<=h.evalSinceStartCount OR h.interrupt) AND NOT h.abort DO UpdateDisplay[h.display]; ViewerTools.SetContents[h.runState, "Interrupted"]; resetRunState _ TRUE; BROADCAST h.proceed; h.waiting _ TRUE; WAIT h.proceed; h.waiting _ FALSE; ENDLOOP; IF resetRunState THEN ViewerTools.SetContents[h.runState, "Running"]; abort _ h.abort; }; UpdateDisplayButton: Buttons.ButtonProc = { handle: RoseDisplay _ NARROW[clientData]; UpdateDisplay[handle]; }; UpdateDisplay: PUBLIC PROC [handle: RoseDisplay] = { FOR dwvs: LIST OF ChoiceButtons.PromptDataRef _ handle.displayWires, dwvs.rest UNTIL dwvs=NIL DO dw: CoreFlat.FlatWire _ NARROW[dwvs.first.clientdata]; new: ROPE; value: Ports.LevelSequence _ Rosemary.WireValue[handle.simulation, dw]; new _ Ports.LevelSequenceToRope[value, CoreOps.WireBits[dw.wire]]; IF NOT Rope.Equal[new, ViewerTools.GetContents[dwvs.first.textViewer]] THEN ViewerTools.SetContents[dwvs.first.textViewer, new]; ENDLOOP; }; NextBuf: PROC [h: Tester, buf: NAT] RETURNS [next: NAT] = { next _ (buf + 1) MOD h.historySize; }; UpdateESSC: PROC [h: Tester, new: INT] = { h.evalSinceStartCount _ new; ViewerTools.SetContents[h.evalsSinceStart, Convert.RopeFromCard[from: h.evalSinceStartCount, showRadix: FALSE]]; }; ExploreDesign: ReadEvalPrint.ClientProc = { ENABLE CoreFlat.PathError => {result _ msg; GOTO Done}; Chop: PROC RETURNS [first, rest: ROPE _ NIL ] = { dStream: IO.STREAM = IO.RIS[command]; first _ dStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token; rest _ command.Substr[dStream.GetIndex]; }; handle: RoseDisplay _ NARROW[h.clientData]; operation, rest, pathName, fullPathName, wireName: ROPE; [operation, rest] _ Chop[]; pathName _ ViewerTools.GetContents[handle.path]; fullPathName _ Rope.Cat[pathName, rest]; wireName _ Rope.Cat[pathName, ViewerTools.GetContents[handle.currentWire], rest]; SELECT TRUE FROM Rope.Equal[operation, "v"] => result _ Rosemary.WireValueRope[handle.simulation, wireName]; Rope.Equal[operation, "c"] => { resultStream: IO.STREAM _ IO.ROS[]; path: CoreFlat.PackedPath _ CoreFlat.FindPath[handle.cellType, fullPathName]; CoreOps.PrintCellType[CoreFlat.GetCellType[handle.cellType, path], resultStream]; result _ IO.RopeFromROS[resultStream]; }; Rope.Equal[operation, "d"] => result _ DescribeWire[goryDetails: TRUE, handle: handle, wireName: wireName]; Rope.Equal[operation, "t"] => result _ DescribeWire[goryDetails: FALSE, handle: handle, wireName: wireName]; ENDCASE => IF NOT Rope.IsEmpty[operation] THEN result _ Rope.Cat["No such command: ", operation, ", commands are (v)alue, (t)race, (c)elltype, and (d)rivers"]; EXITS Done => NULL; }; DescribeWire: PROC [goryDetails: BOOL, handle: RoseDisplay, wireName: ROPE] RETURNS [result: ROPE] = { wireKey: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec]; wireRoot: CoreFlat.WireRoot; roseWire: Rosemary.RoseWire; cellType: Core.CellType; bindings: HashTable.Table; bind: CoreFlat.WireBind; [wireKey^, wireRoot] _ CoreFlat.FindWire[handle.cellType, wireName]; [bindings, cellType] _ CoreFlat.BoundCellType[handle.cellType, wireKey.path]; bind _ NARROW[HashTable.Fetch[table: bindings, key: wireKey.wire].value]; wireKey.path _ bind.path; wireKey.wire _ bind.wire; roseWire _ Rosemary.RawRoseWire[handle.simulation, wireKey]; result _ Rope.Cat[CoreFlat.WirePathRope[handle.cellType, wireKey^, wireRoot], " = ", Rosemary.WireValueRope[handle.simulation, wireName], "\n"]; result _ Rope.Cat[result, IF roseWire=NIL THEN "This wire is not stored as a Rosemary wire, try a parent or child of it." ELSE RoseWirePrint[goryDetails, handle.simulation, handle.cellType, roseWire]]; }; RoseWirePrint: PROC [goryDetails: BOOL, simulation: Rosemary.Simulation, root: Core.CellType, roseWire: Rosemary.RoseWire] RETURNS [result: ROPE] = { CatWire: PROC [roseWire: Rosemary.RoseWire] = { result _ Rope.Cat[result, CoreFlat.WirePathRope[root, roseWire.wire], " - "]; IF roseWire.currentValue=NIL THEN { IF goryDetails THEN { result _ Rope.Cat[result, "cd: ", Ports.driveNames[roseWire.connectionDrive]]; result _ Rope.Cat[result, ", sd: ", Ports.driveNames[roseWire.switchDrive]]; result _ Rope.Cat[result, ", ud: ", Ports.driveNames[roseWire.upDrive]]; result _ Rope.Cat[result, ", dd: ", Ports.driveNames[roseWire.downDrive]]; result _ Rope.Cat[result, ", wd: ", Ports.driveNames[roseWire.wireDrive]]; result _ Rope.Cat[result, ", cl: ", Ports.levelNames[roseWire.connectionLevel], ", "]; }; result _ Rope.Cat[result, "wl: ", Ports.levelNames[roseWire.wireLevel]]; } ELSE result _ Ports.LevelSequenceToRope[roseWire.currentValue]; }; CatTran: PROC [roseTran: Rosemary.RoseTransistor] = { result _ Rope.Cat[result, " tt: ", CoreClasses.transistorTypeNames[roseTran.type]]; IF goryDetails THEN result _ Rope.Cat[result, ", tc: ", Ports.driveNames[roseTran.conductivity]]; }; FindPortWire: Ports.EachWirePortPairProc = { IF (quit _ port=clientPort) THEN coreWire.wire _ wire; }; clientPort: Ports.Port; coreWire: CoreFlat.FlatWireRec; CatWire[roseWire]; result _ Rope.Cat[result, "\nConnections\n"]; IF roseWire.connections#NIL THEN FOR fields: NAT IN [0..roseWire.connections.size) DO field: Rosemary.Field _ roseWire.connections[fields]; roseInstance: Rosemary.RoseCellInstance _ field.portBinding.instance; result _ Rope.Cat[result, " "]; clientPort _ field.portBinding.clientPort; IF NOT Ports.VisitBinding[wire: IF roseInstance=NIL THEN CoreOps.ToBasic[root].public ELSE roseInstance.instance.instance.type.public, port: IF roseInstance=NIL THEN simulation.testPort ELSE roseInstance.publicPort, eachWirePortPair: FindPortWire] THEN ERROR; coreWire.path _ IF roseInstance=NIL THEN CoreFlat.NullPath ELSE CoreFlat.AddInstance[roseInstance.instance.path, roseInstance.instance.instance, CoreFlat.GetCellType[root, roseInstance.instance.path]]; result _ Rope.Cat[result, CoreFlat.WirePathRope[root, coreWire, public]]; IF goryDetails THEN { result _ Rope.Cat[result, " - d: ", Ports.driveNames[field.portBinding.currentDrive]]; result _ Rope.Cat[result, ", v: ", Ports.LevelSequenceToRope[field.currentValue]]; result _ Rope.Cat[result, ", sb: ", Convert.RopeFromCard[field.portStartBit]]; result _ Rope.Cat[result, ", fs: ", Convert.RopeFromCard[field.currentValue.size]]; }; result _ Rope.Cat[result, "\n"]; ENDLOOP; result _ Rope.Cat[result, "Channels\n"]; IF roseWire.channels#NIL THEN FOR channels: NAT IN [0..roseWire.channels.size) DO tran: Rosemary.RoseTransistor _ roseWire.channels[channels]; otherWire: Rosemary.RoseWire _ tran.ch1; CatTran[tran]; result _ Rope.Cat[result, "\n oc: "]; IF otherWire=roseWire THEN otherWire _ tran.ch2; CatWire[otherWire]; result _ Rope.Cat[result, "\n g: ", ]; CatWire[tran.gate]; result _ Rope.Cat[result, "\n"]; ENDLOOP; result _ Rope.Cat[result, "Gates\n"]; IF roseWire.gates#NIL THEN FOR gates: NAT IN [0..roseWire.gates.size) DO tran: Rosemary.RoseTransistor _ roseWire.gates[gates]; CatTran[tran]; result _ Rope.Cat[result, "\n c1: "]; CatWire[tran.ch1]; result _ Rope.Cat[result, "\n c2: ", ]; CatWire[tran.ch2]; result _ Rope.Cat[result, "\n"]; ENDLOOP; }; DisplayInstancePortLeafWires: PUBLIC PROC [instance: CoreFlat.FlatInstanceRec] RETURNS [displayWires: CoreFlat.FlatWires] = { displayWires _ DisplayPortLeafWires[instance.path, instance.instance.type.public]; }; DisplayCellTypePortLeafWires: PUBLIC PROC [cellType: Core.CellType] RETURNS [displayWires: CoreFlat.FlatWires] = { displayWires _ DisplayPortLeafWires[CoreFlat.NullPath, cellType.public]; }; DisplayPortLeafWires: PUBLIC PROC [path: CoreFlat.PackedPath, wire: Core.Wire] RETURNS [displayWires: CoreFlat.FlatWires] = { FindLeaves: CoreOps.EachWireProc = { IF Ports.WirePortType[wire]#composite THEN { subWires _ FALSE; displayWires _ CONS[NEW[CoreFlat.FlatWireRec _ [path: path, wire: wire]], displayWires]; }; }; IF CoreOps.VisitWire[wire, FindLeaves] THEN ERROR; }; END. ΰRosemaryUserImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Barth, June 13, 1986 2:26:02 pm PDT Louis Monier June 11, 1986 12:31:44 pm PDT check new state same as recorded state; Wire Display ΚX– "cedar" style˜codešœ™Kšœ Οmœ1™Jšœžœ "˜šœ=˜=Jšœ$˜$Jšœ˜Jšœžœ(˜D—Jšœžœ˜0Jšžœžœžœ˜šžœžœ žœ˜Jšœ ˜ Jšœ,˜,Jšœ˜—Jšžœ˜Jšžœ˜—Jšžœ žœ-˜=Jšœ-˜-Jšœa˜aJšœ˜J˜—Jšœ&˜&J˜JšœD˜DJ˜J˜—š‘œžœ,žœ;žœ˜’šžœžœžœ˜Jšœžœžœ˜Jšœ žœžœžœ>˜^Jšœ˜šžœ2žœžœž˜EKšœžœη˜JšœC˜Cšžœžœ žœ˜Jšœ ˜ Jšœ,˜,Jšœ˜—Jšžœ˜Kšžœ˜—Jšžœ žœ-˜=Kšœa˜aKšœ˜K˜J˜—Jšœ{žœ2˜±Jšœ,˜,Jšœ²˜²Jšœ,˜,Jšœ³˜³Jšœ,˜,Jšœa˜aJšœ˜J˜šœ˜Kšœ˜Kšœe˜eKšœ…žœ˜‹Kšœ˜Kšœ+žœ˜0Jšœ#˜#Jšœ.˜.K˜—J˜Jšœ(˜(Jšœ#˜#K˜K˜—šΟb œ˜"Kšœ žœ ˜šžœ žœ˜(Kšœžœ˜7K˜—Kšžœžœ˜Kšœ=žœ˜SKšœ˜K˜—š‘œ˜&Kšœ žœ ˜Kšœ'žœ ˜6š žœžœžœ+žœžœž˜GKšœ!žœžœžœ˜cKšžœ˜—Kšœ(˜(Kšœ˜K˜—šœ žœžœ˜K˜—š‘ œ˜!Kšœ žœ ˜Kšžœžœžœ˜-Kšœ˜K˜—š‘ œžœ˜!K˜š‘œžœ˜K˜š‘ œ˜#Kšœ˜Kšžœ žœžœ ˜#Kšžœžœžœžœ˜ Kšœ˜Kšœ&˜&Kšœ˜Kšžœ!žœ<žœV˜ΉK˜K˜—šž˜Kšœžœ-žœ˜LJšœžœžœ7žœ ˜kJšœ<˜žœžœž˜`Kšœžœ˜6Kšœžœ˜ KšœG˜GKšœB˜BKšžœžœAžœ5˜€Kšžœ˜—K˜K˜—š ‘œžœžœžœžœ˜;Kšœžœ˜#K˜K˜—š‘ œžœžœ˜*Kšœ˜Kšœhžœ˜pK˜K˜—šŸ œ˜+Kšžœ&žœ˜7J˜š ‘œžœžœžœžœ˜1Jš œ žœžœžœžœ ˜%Jšœžœ žœžœ˜KJšœ(˜(Jšœ˜J˜—Kšœžœ˜+Kšœ3žœ˜8Kšœ˜Kšœ0˜0Kšœ(˜(KšœQ˜Qšžœžœž˜Kšœ[˜[šœ˜Kš œžœžœžœžœ˜#KšœM˜MKšœQ˜QKšœ žœ˜&K˜—KšœAžœ&˜kKšœAžœ&˜lKšžœžœžœžœq˜Ÿ—Kšžœ žœ˜K˜K™—š ‘ œžœžœ!žœžœ žœ˜fKšœžœ˜7Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜KšœD˜DKšœM˜MKšœžœ<˜IK˜K˜Kšœ<˜