DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, FS, AMatrix, IO, MonitorSmallCachePmCode, Ports, Rope, Rosemary, SmallCacheLogic, SmallCacheUtils, TerminalIO; MonitorSmallCachePmCodeImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, FS, IO, AMatrix, Ports, Rope, Rosemary, SmallCacheLogic, SmallCacheUtils, TerminalIO EXPORTS MonitorSmallCachePmCode ~ BEGIN OPEN MonitorSmallCachePmCode; 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: SmallCacheUtils.workingDirectory]; 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.am _ AMatrix.Create[h.size]; WHILE NOT GetTransitions[] DO FOR l: LIST OF ROPE _ toPCs, l.rest WHILE l#NIL DO h.am[LabelToPC[h, fromPC]][LabelToPC[h, l.first]] _ 1; ENDLOOP; ENDLOOP; END; h.amSeq _ AMatrix.CreateAMSeq[h.am] }; RecordPC: PUBLIC PROC [h: Handle, pc: NAT] = { ENABLE AMatrix.DisallowedPath => { TerminalIO.PutF["\n*** Got disallowed path from %g to %g ***", IO.rope[PCToLabel[h, from]], IO.rope[PCToLabel[h, to]]]; RESUME }; AMatrix.UpdateAMSeq[h.amSeq, pc]; IF tracingEnabled THEN TerminalIO.PutF["\n= %g", IO.rope[PCToLabel[h, pc]]]; }; PrintUnVisitedPaths: PUBLIC PROC [h: Handle, maxLength: NAT] = { seqSize: NAT _ h.amSeq.size; size: NAT _ h.amSeq.ams[0].size; existUnvisitedPaths: BOOL _ FALSE; TerminalIO.PutF["\n\n-- Printing unvisited paths up 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.amSeq.ams[p][i][j] = 1 THEN { existUnvisitedPaths _ TRUE; IF p+1 <= maxLength THEN TerminalIO.PutF["\n %g-->%g", 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", SmallCacheLogic.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[SmallCacheLogic.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 AMatrix.InitAMSeq[handle.amSeq]; 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; handle: Handle _ NIL; END. PMonitorSmallCachePmCodeImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Created: Sindhu July 27, 1987 2:00:51 pm PDT Pradeep Sindhu February 7, 1988 12:26:34 pm PST Implements monitoring of mcode to check if all paths have been traversed. Type Defs Signal Defs Public Procs Parses mCode file and creates the labelTable and AMatrix First build the labelTable: Find the start of the microcode labels Read the labels and put them into labelList Create handle, and then copy labelList into labelTable Next build the AMatrix This proc reads the transitions from one pc to all the others it jumps to Ignore stuff till we get to "=" or "-- End Transitions" Find the start of the section that defines the transitions Read the transitions and put them into AMatrix Finally, compute the sequence of AMatrices Internal Procs Κˆ˜codešœ ™ Kšœ Οmœ1™KšŸœ˜K˜—K˜K™8š ž œŸœŸœ ŸœŸœŸœ˜LKšœŸœŸœM˜YKšœŸœ ˜KšœŸœ˜ K˜K™šŸ˜šžœŸœŸœ Ÿœ˜+šŸ˜KšœŸœ˜(KšŸœ ŸœŸœŸœ˜DKšœŸœ˜(KšŸœŸœŸ˜%KšŸœ˜—K˜K˜—KšœŸ˜ Kš œ ŸœŸœŸœŸœ˜Kšœ Ÿœ˜K˜K™&KšœŸœŸœ˜0šŸœŸœŸœ'Ÿ˜GKšœŸœŸœ˜0KšŸœ˜K˜—Kšœ+™+K˜"šŸœŸœŸ˜'Kšœ Ÿœ˜$K˜K˜KšŸœ˜—K˜Kšœ6™6KšœŸœ˜š ŸœŸœŸ œŸœŸ˜*K˜>KšŸœ˜—KšŸœ˜—K˜K™šŸ˜KšœŸœŸœ˜Kš œŸœŸœŸœŸœ˜K™K™Iš žœŸœŸœŸœŸœ˜8Kšœ Ÿœ˜KšœŸœ˜ K˜Kšœ7™7KšœŸœŸœ˜/šŸœŸœŸœŸœŸœŸœΟeœŸ˜~KšœŸœŸœ˜.KšŸœ˜—šŸœŸœ‘œ˜>KšŸœŸœŸœ˜—K˜K˜KšœŸœ˜)KšœŸœ˜(KšŸœŸœŸœŸœ˜*K˜KšœŸœ˜(KšŸœŸœŸœŸœ˜)KšœΟc$˜5šŸœŸ˜KšœŸœ˜(šŸœŸ˜šœ ŸœŸœ˜/KšœŸœ˜(Kš ŸœŸœŸœŸœŸœ˜>KšœŸœ˜(KšŸœŸœ ŸœŸœ˜KšœŸœ˜K˜—šœ˜KšŸœŸœ˜9KšŸœŸœ˜9K˜—KšŸœ˜—KšŸœ˜—K˜—K™K™:KšœŸœŸœ˜0šŸœŸœŸœ,Ÿ˜LKšœŸœŸœ˜0KšŸœ˜K˜—K™.K˜šŸœŸœŸ˜š ŸœŸœŸœŸœŸœŸœŸ˜2K˜6KšŸœ˜—KšŸœ˜—KšŸœ˜—K˜K™*K˜#K˜—K˜šžœŸœŸœŸœ˜.šŸœ˜"Kšœ?ŸœŸœ˜wKšŸ˜K˜—Kšœ!˜!KšŸœŸœŸœ˜LK˜—K˜šžœŸœŸœŸœ˜@Kšœ Ÿœ˜KšœŸœ˜ KšœŸœŸœ˜"K˜KšœFŸœŸœ˜gšŸœŸœŸœŸ˜šŸœ˜KšŸœ7Ÿœ ˜H—šŸœŸœŸœ Ÿ˜šŸœŸœŸœ Ÿ˜šŸœŸœ˜"KšœŸœ˜šŸœ˜KšŸœŸœŸœ˜V—K˜—KšŸœ˜—KšŸœ˜—KšŸœ˜—KšŸœŸœA˜\K˜—K˜šž œŸœŸœŸœ˜4Kšœ#ŸœE˜lKšœ3˜3KšœG˜GKšœ-˜-Kšœ$˜$Kšœ/˜/K˜——™šΠbnœ˜Kšœ ˜ K˜šŸœ Ÿ˜šŸœ˜KšœŸœ ˜KšœŸœ/˜9K˜—KšŸœŸœ˜$—K˜KšœQ˜QKšœ ˜ Kšœ˜—K˜š£œ˜Kšœ Ÿœ ˜K˜Kš Ÿœ ŸœŸœŸœŸœ˜'K˜KšŸœŸœ˜2šŸœŸœŸœ˜(KšŸœŸœ!˜5KšŸœŸœ$˜8K˜—Kšœ˜K˜—K˜KšœŸœfŸœ˜KšœŸœŸœ˜KšœŸœ˜J˜—KšŸœ˜—…—r"J