<> <> <> <> <> <> Directory Basics, DragOpsCross; TranslationNeeds Dragon; Imports CacheOps, ClusterParams, DragonRosemary, IO, LizardRosemary, Process, Rope, RoseRun, RoseTypes; Library IFU, EU, Cache; CELLTYPE "Cluster" PORTS[ <> <<>> <> IPRejectB > BOOL, DPRejectB > BOOL, <> PhA, PhB < BOOL, Vdd, Gnd < BOOL, PadVdd, PadGnd < BOOL, RescheduleAB < BOOL, ClusterError = BOOL, <

> DPData > INT[32], DPCmnd3A > EnumType["Dragon.PBusCommands"], DPFaultB > EnumType["Dragon.PBusFaults"], <

> MDataAB = INT[32], MCmdAB = EnumType["Dragon.MBusCommands"], MNShared = BOOL, MParityAB = BOOL, MNError > BOOL, MReadyBA < BOOL, M1Rq > BOOL, M2Rq > BOOL, MNewRq = BOOL, M1Gnt < BOOL, M2Gnt < BOOL, <> <> ResetAB < BOOL, DHoldAB < BOOL, -- must be high before testing DShiftAB < BOOL, -- shift the shift register by 1 bit if ~DNSelect DExecuteAB < BOOL, -- interpret the content of the shift register if ~DNSelect DNSelectAB < BOOL, -- if high, hold but don't Execute or Shift DDataInAB < BOOL, -- sampled during each PhB following a PhB that DShift is asserted DDataOutAB = BOOL -- changes during each PhA following a PhB that DShift is asserted, continues to be driven through the PhB following the PhA it changes ] Expand <

> IPData: INT[32]; -- PhA - address to cache, PhB - data to/from cache IPCmnd3A: EnumType["Dragon.PBusCommands"]; IPFaultB: EnumType["Dragon.PBusFaults"]; <> KBus: INT[32]; <> EUSt3AisCBus2BA: BOOL; EURes3BisPBus3AB: BOOL; EUWriteToPBus3AB: BOOL; EUAluOp2AB: EnumType["Dragon.ALUOps"]; EUCondSel2AB: EnumType["Dragon.CondSelects"]; EUCondition2B: BOOL; ifu: IFU[logRef: |ClusterParams.ifuLogRef|, lizardSimRef: |ClusterParams.lizardSimRef| ][]; eu: EU[logRef: |ClusterParams.euLogRef|][]; iCache: Cache[cacheParm: |ClusterParams.iCache|, skipRejectsParm: |ClusterParams.iCacheSkipRejects|][ PData: IPData, PCmdA: IPCmnd3A, PRejectB: IPRejectB, PFaultB: IPFaultB, MRq: M1Rq, MGnt: M1Gnt ]; eCache: Cache[cacheParm: |ClusterParams.eCache|, skipRejectsParm: |FALSE|][ PData: DPData, PCmdA: DPCmnd3A, PRejectB: DPRejectB, PFaultB: DPFaultB, MRq: M2Rq, MGnt: M2Gnt ]; CEDAR { }; Test T BlackBox originalPriority: Process.Priority = Process.GetPriority[]; diagnosticName: Rope.ROPE _ "unknown"; Process.SetPriority[ Process.priorityBackground ]; IF clusterPanelChecker=NIL THEN clusterPanelChecker _ FORK ClusterParams.PanelCheck[]; { ENABLE UNWIND => { ClusterParams.clusterLog.PutF["\nSimulation of %g aborted\n\n", IO.rope[diagnosticName]]; ClusterParams.clusterLog.Flush[]; Process.SetPriority[ originalPriority ] }; DoEval: PROC = { OPEN ClusterParams; clusterPanel.continueTestFromAbort _ FALSE; IF PhA THEN { RescheduleAB _ clusterPanel.resched; ResetAB _ clusterPanel.reset}; [] _ RoseRun.Eval[ handle ! RoseTypes.Stop => IF clusterPanel.continueTestFromAbort THEN CONTINUE ELSE REJECT ]; IF clusterPanel.reset THEN clusterPanel.instrCount _ -1; Process.Yield[]; clusterPanel.continueTestFromAbort _ FALSE}; Cycles: PROC [ n: INT ] = {FOR i: INT IN [0..n) DO DoPh[a]; DoPh[b] ENDLOOP}; DoPh: PROC [ ph: Dragon.Phase ] = { cp: REF ClusterParams.ControlPanel _ ClusterParams.clusterPanel; PhB _ ph=b; PhA _ ph=a; cp.phase _ ph; DoEval[]; IF (cp.cycle >= cp.slowFromCycle OR (cp.cycle>=0 AND cp.instrCount >= cp.slowFromInstr)) AND cp.stopInPh[ph] THEN { Remark[IO.PutFR["Doing cycle %g Ph%g...", IO.int[cp.cycle], IO.char[IF ph=a THEN 'A ELSE 'B]]]; DoEval[] }; PhA _ PhB _ FALSE; DoEval[]; WHILE cp.repeatPhase DO PhB _ ph=b; PhA _ ph=a; DoEval[]; Remark[IO.PutFR["...repeating Ph%g evaluation..", IO.char[IF ph=a THEN 'A ELSE 'B]]]; DoEval[]; PhA _ PhB _ FALSE; DoEval[]; ENDLOOP }; FOR port: ClusterPort IN ClusterPort DO IF drive[port]=test THEN drive[port] _ see ENDLOOP; drive[PhA] _ drive; drive[PhB] _ drive; drive[RescheduleAB] _ drive; drive[ResetAB] _ drive; root _ RoseTypes.GetSimulationFromCellTestHandle[handle].root; DO Chop: PROC RETURNS [ first, rest: Rope.ROPE _ NIL ] = BEGIN dStream: IO.STREAM = IO.RIS[ClusterParams.clusterPanel.diagnostic]; first _ dStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token; rest _ ClusterParams.clusterPanel.diagnostic.Substr[dStream.GetIndex]; END; diagnosticFileName: Rope.ROPE _ diagnosticName _ Chop[].first; ClusterError _ FALSE; ClusterParams.clusterPanel.reset _ TRUE; ClusterParams.clusterPanel.stopInPh _ ALL[TRUE]; ClusterParams.clusterPanel.repeatPhase _ ClusterParams.clusterPanel.resched _ FALSE; ClusterParams.clusterPanel.cycle _ -1; ClusterParams.clusterPanel.instrCount _ -1; Cycles[5 ! DragonRosemary.AssertionFailed => RESUME; RoseTypes.Stop => IF data = $FailedAssertion THEN RESUME ELSE REJECT ]; SELECT TRUE FROM Rope.Equal[s1: diagnosticFileName, s2: "END", case: FALSE] => EXIT; diagnosticFileName # NIL => BEGIN CacheOps.VirtualMemoryFromFile[ClusterParams.vm, diagnosticFileName ]; ClusterParams.lizardSimRef^ _ (IF ClusterParams.clusterPanel.lizardToo THEN LizardRosemary.StartNewLizard[ClusterParams.vm] ELSE NIL); END; ClusterParams.clusterPanel.randomSeed#0 => BEGIN diagnosticName _ IO.PutFR["random code (seed = %d)", IO.int[ClusterParams.clusterPanel.randomSeed]]; ClusterParams.InsertRandomProgramInVM[ClusterParams.vm, ClusterParams.clusterPanel.randomSeed, ClusterParams.clusterLog]; ClusterParams.lizardSimRef^ _ (IF ClusterParams.clusterPanel.lizardToo THEN LizardRosemary.StartNewLizard[ClusterParams.vm] ELSE NIL); END; ENDCASE => EXIT; -- test is finished!!! DoPh[a]; ClusterError _ FALSE; ClusterParams.clusterPanel.reset _ FALSE; DoEval[]; -- changes ResetAB during PhA DoPh[b]; IF ClusterParams.clusterPanel.slowFromCycle<=0 THEN Remark["Processor has been reset..."]; ClusterParams.clusterPanel.cycle _ 0; ClusterParams.clusterLog.PutF["\n\n\n%g Dragon Rosemary simulation of %g beginning...\n\n", IO.time[], IO.rope[diagnosticName]]; WHILE ClusterParams.clusterPanel.randomSeed=0 OR ClusterParams.clusterPanel.cycle<=ClusterParams.clusterPanel.randomCycleLimit DO ENABLE { LizardRosemary.SuccessHalt => { ClusterParams.clusterLog.PutF["\n%g Success XOP in %g at instruction %d, cycle %d.\n\n", IO.time[], IO.rope[diagnosticName], IO.int[ClusterParams.clusterPanel.instrCount], IO.int[ClusterParams.clusterPanel.cycle]]; EXIT; }; LizardRosemary.Breakpoint => { ClusterParams.clusterLog.PutF["\n%g Breakpoint XOP in %g at instruction %d, cycle %d.\n\n", IO.time[], IO.rope[diagnosticName], IO.int[ClusterParams.clusterPanel.instrCount], IO.int[ClusterParams.clusterPanel.cycle]]; SELECT TRUE FROM ClusterParams.clusterPanel.emulateBreakpoint => RESUME; diagnosticFileName # NIL => REJECT; ENDCASE => EXIT; }; }; DoPh[a]; DoPh[b]; IF ClusterParams.clusterPanel.ckptEveryNCycles > 0 AND ClusterParams.clusterPanel.ckptAtCycle <= ClusterParams.clusterPanel.cycle THEN ClusterParams.clusterPanel.ckptAtCycle _ ClusterParams.clusterPanel.cycle+ClusterParams.clusterPanel.ckptEveryNCycles; ClusterParams.clusterPanel.cycle _ ClusterParams.clusterPanel.cycle+1; IF ClusterParams.clusterPanel.ckpt OR ClusterParams.clusterPanel.ckptAtCycle = ClusterParams.clusterPanel.cycle THEN { ClusterParams.clusterPanel.ckpt _ FALSE; ClusterParams.CheckPoint[ClusterParams.clusterPanel.ckptFile, root] }; ENDLOOP; -- on ClusterParams.clusterPanel.cycle SELECT TRUE FROM diagnosticFileName # NIL => BEGIN first, rest: Rope.ROPE; [first, rest] _ Chop[]; IF first.Equal[diagnosticFileName] THEN ClusterParams.clusterPanel.diagnostic _ Rope.Cat[rest, " ",first]; END; ClusterParams.clusterPanel.randomSeed # 0 => ClusterParams.clusterPanel.randomSeed _ ClusterParams.clusterPanel.randomSeed+1; ENDCASE => NULL; ENDLOOP; -- on ClusterParams.clusterPanel.randomSeed }; -- for catching UNWIND ENDCELLTYPE; CEDAR root: RoseTypes.Cell _ NIL; clusterPanelChecker: PROCESS _ NIL; Remark: PROC[message: Rope.ROPE] = ClusterParams.Remark;