<> <> <> <> <<>> <> <<>> DIRECTORY CommandTool, Core, CoreClasses, CoreCreate, CoreFlat, FS, IMatrix, IO, MonitorSCPmCode, Ports, Rope, Rosemary, SCLogic, TerminalIO; <<>> MonitorSCPmCodeImpl: CEDAR PROGRAM IMPORTS CommandTool, CoreClasses, CoreCreate, CoreFlat, FS, IO, IMatrix, Ports, Rope, Rosemary, SCLogic, TerminalIO EXPORTS MonitorSCPmCode ~ BEGIN OPEN MonitorSCPmCode; <> State: TYPE = REF StateRec; StateRec: TYPE = RECORD [ pc: LevelSequence, prevClock: Level ]; <> PC, Reset, Clock: NAT; <> LabelToPC: PUBLIC PROC [h: Handle, label: ROPE] RETURNS [INT] = { FOR i: INT IN [0..h.size) DO IF Rope.Equal[label, h.labelTable[i]] THEN RETURN [i] ENDLOOP; RETURN [-1]; }; PCToLabel: PUBLIC PROC [h: Handle, pc: NAT] RETURNS [ROPE] = { RETURN [h.labelTable[pc]]; }; <> ParseMCode: PUBLIC PROC [fileName: ROPE, wDir: ROPE] RETURNS [h: Handle] = { s: IO.STREAM _ FS.StreamOpen[fileName: fileName, wDir: wDir]; tk: IO.TokenKind; token: ROPE; <> BEGIN GetLabel: PROC [] RETURNS [label: ROPE] = { DO [tk, label, ] _ IO.GetCedarTokenRope[s]; WHILE tk#tokenID DO [tk, label, ] _ IO.GetCedarTokenRope[s] ENDLOOP; [tk, token, ] _ IO.GetCedarTokenRope[s]; IF Rope.Equal[token, ":"] THEN RETURN ENDLOOP; }; label: ROPE; labelList: LIST OF ROPE _ NIL; numLabels: NAT _ 0; <> [tk , token, ] _ IO.GetCedarTokenRope[s, FALSE]; WHILE NOT (tk=tokenCOMMENT AND Rope.Equal[token, "-- Begin Labels"]) DO [tk , token, ] _ IO.GetCedarTokenRope[s, FALSE]; ENDLOOP; <> numLabels _ 0; label _ GetLabel[]; WHILE NOT Rope.Equal[label, "MaxPC"] DO labelList _ CONS [label, labelList]; numLabels _ numLabels+1; label _ GetLabel[]; ENDLOOP; <> h _ NEW [HandleRec[numLabels]]; FOR i: NAT DECREASING IN [0..numLabels) DO h.labelTable[i] _ labelList.first; labelList _ labelList.rest; ENDLOOP; END; <> BEGIN fromPC: ROPE _ NIL; toPCs: LIST OF ROPE _ NIL; <<>> <> GetTransitions: PROC [] RETURNS [done: BOOL _ FALSE] = { curlyCount: INT; toPCs _ NIL; <> [tk, token, ] _ IO.GetCedarTokenRope[s, FALSE]; WHILE NOT (tk=tokenSINGLE AND Rope.Equal[token, "="]) AND NOT (tk=tokenCOMMENT AND Rope.Equal[token, "-- End Transitions"]) DO [tk, token, ] _ IO.GetCedarTokenRope[s, FALSE] ENDLOOP; IF tk=tokenCOMMENT AND Rope.Equal[token, "-- End Transitions"] THEN RETURN [TRUE]; [tk, fromPC, ] _ IO.GetCedarTokenRope[s]; [tk, token, ] _ IO.GetCedarTokenRope[s]; IF NOT Rope.Equal[token, "=>"] THEN ERROR; [tk, token, ] _ IO.GetCedarTokenRope[s]; IF NOT Rope.Equal[token, "{"] THEN ERROR; curlyCount _ -1; -- to indicate one "{" has been seen WHILE curlyCount#0 DO [tk, token, ] _ IO.GetCedarTokenRope[s]; SELECT tk FROM = tokenID => IF Rope.Equal[token, "Jmp"] THEN { [tk, token, ] _ IO.GetCedarTokenRope[s]; IF NOT (tk=tokenSINGLE AND Rope.Equal[token, "["]) THEN ERROR; [tk, token, ] _ IO.GetCedarTokenRope[s]; IF NOT tk=tokenID THEN ERROR; toPCs _ CONS[token, toPCs]; }; = tokenSINGLE => { IF Rope.Equal[token, "{"] THEN curlyCount _ curlyCount-1; IF Rope.Equal[token, "}"] THEN curlyCount _ curlyCount+1; }; ENDCASE; ENDLOOP; }; <<>> <> [tk , token, ] _ IO.GetCedarTokenRope[s, FALSE]; WHILE NOT (tk=tokenCOMMENT AND Rope.Equal[token, "-- Begin Transitions"]) DO [tk , token, ] _ IO.GetCedarTokenRope[s, FALSE]; ENDLOOP; <> h.im _ IMatrix.Create[h.size]; WHILE NOT GetTransitions[] DO FOR l: LIST OF ROPE _ toPCs, l.rest WHILE l#NIL DO h.im[LabelToPC[h, fromPC]][LabelToPC[h, l.first]] _ 1; ENDLOOP; ENDLOOP; END; <> h.imSeq _ IMatrix.CreateIMSeq[h.im] }; RecordPC: PUBLIC PROC [h: Handle, pc: NAT] = { ENABLE IMatrix.DisallowedPath => { TerminalIO.PutF["\n*** Got disallowed path from %g to %g ***", IO.rope[PCToLabel[h, from]], IO.rope[PCToLabel[h, to]]]; RESUME }; IMatrix.UpdateIMSeq[h.imSeq, pc]; IF tracingEnabled THEN TerminalIO.PutF["\n= %g", IO.rope[PCToLabel[h, pc]]]; }; PrintUnVisitedPaths: PUBLIC PROC [h: Handle, maxLength: NAT] = { seqSize: NAT _ h.imSeq.size; size: NAT _ h.imSeq.ims[0].size; existUnvisitedPaths: BOOL _ FALSE; TerminalIO.PutF["\n\n-- Printing unvisited paths to length %g --", IO.int[MIN[maxLength, seqSize]]]; FOR p: NAT IN [0..seqSize) DO IF p+1 <= maxLength THEN TerminalIO.PutF["\n\n Unvisited paths of length %g:", IO.int[p+1]]; FOR i: NAT IN [0..size) DO FOR j: NAT IN [0..size) DO IF h.imSeq.ims[p][i][j] = 1 THEN { existUnvisitedPaths _ TRUE; IF p+1 <= maxLength THEN TerminalIO.PutF["\n %g --> %g not visited", IO.rope[PCToLabel[h, i]], IO.rope[PCToLabel[h, j]]] } ENDLOOP; ENDLOOP; ENDLOOP; IF existUnvisitedPaths THEN TerminalIO.PutF["\n\n*** Warning: Unvisited paths exist ***\n"]; }; PCMonitor: PUBLIC PROC [] RETURNS [ct: CellType] = { public: Wire _ CoreCreate.WireList[LIST[CoreCreate.Seq["PC", SCLogic.NumPCBits], "Reset", "Clock"]]; ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: pcMonitorName]; [] _ CoreFlat.CellTypeCutLabels[ct, "Logic"]; Ports.InitPorts[ct, ls, none, "PC"]; Ports.InitPorts[ct, l, none, "Reset", "Clock"]; }; <> Init: Rosemary.InitProc = { s: State; IF oldStateAny=NIL THEN { s _ NEW [StateRec]; s.pc _ NEW [LevelSequenceRec[SCLogic.NumPCBits]]; } ELSE s _ NARROW[oldStateAny, State]; s.prevClock _ X; [PC, Reset, Clock] _ Ports.PortIndexes[cellType.public, "PC", "Reset", "Clock"]; stateAny _ s; }; Simple: Rosemary.EvalProc = { s: State _ NARROW[stateAny]; IF clockEval OR handle=NIL THEN RETURN; IF p[Clock].l=L THEN Ports.CopyLS[p[PC].ls, s.pc]; IF s.prevClock=L AND p[Clock].l=H THEN { IF p[Reset].l=H THEN IMatrix.InitIMSeq[handle.imSeq]; IF p[Reset].l=L THEN RecordPC[handle, Ports.LSToC[s.pc]] }; s.prevClock _ p[Clock].l; }; pcMonitorName: ROPE = Rosemary.Register[roseClassName: "PCMonitor", init: Init, evalSimple: Simple, scheduleIfClockEval: TRUE]; tracingEnabled: BOOL _ TRUE; wDir: Rope.ROPE _ CommandTool.CurrentWorkingDirectory[]; handle: Handle _ NIL; END.