<> <> <> <> <<>> DIRECTORY BitOps, Dragon, DragOpsCross, DragOpsCrossUtils, eu, RoseCreate, Rope, RoseRun, RoseTypes; EUTest: CEDAR PROGRAM IMPORTS BitOps, Dragon, RoseCreate, RoseRun SHARES eu = BEGIN OPEN BitOps, eu; EUTestExerciseEveryBlock: RoseTypes.CellTestProc = BEGIN instructions: EUIORef _ NARROW[io]; drive: EUDriveRef _ NARROW[driveAsAny]; initPattern: LONG CARDINAL _ 0H; BEGIN OPEN instructions; PackAddress: PROC[a, b, c: DragOpsCross.ProcessorRegister] RETURNS[k: BitDWord] = { -- for EU RAM mux k _ ICID[Dragon.PRtoByte[a], k, 32, 0, 8]; k _ ICID[Dragon.PRtoByte[b], k, 32, 8, 8]; k _ ICID[Dragon.PRtoByte[c], k, 32, 16, 8]; }; PhAUp: PROC = {PhA _ TRUE; nPhA _ FALSE; [] _ RoseRun.Eval[handle]}; PhADown: PROC = {PhA _ FALSE; nPhA _ TRUE; [] _ RoseRun.Eval[handle]}; PhBUp: PROC = {PhB _ TRUE; nPhB _ FALSE; [] _ RoseRun.Eval[handle]}; PhBDown: PROC = {PhB _ FALSE; nPhB _ TRUE; [] _ RoseRun.Eval[handle]}; <> <> <> <> <> <> <> < Cache/data -> FPU>> < Cache/FPU>> <<>> <<>> NullCycles: PROC [n: NAT] = { THROUGH [0..n) DO PhAUp[]; PhADown[]; KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; ENDLOOP; }; Reset: PROC = { -- Homing sequence drive.s[MHold] _ drive.s[MnReset] _ Ignore; -- set tri-state driver "strength" = 0 drive.s[DDataOut] _ Ignore; drive.s[EPData] _ Ignore; drive.s[EUCondition2BA] _ Ignore; drive.s[KBus] _ Ignore; NullCycles[5]; -- Timing & power up PhA _ FALSE; nPhA _ TRUE; PhB _ FALSE; nPhB _ TRUE; drive.s[PhA] _ drive.s[nPhA] _ drive.s[PhB] _ drive.s[nPhB] _ Drive; Vdd _ TRUE; Gnd _ FALSE; PadVdd _ TRUE; PadGnd _ FALSE; drive.s[Vdd] _ drive.s[Gnd] _ drive.s[PadVdd] _ drive.s[PadGnd] _ Drive; -- MBus/ main memory MHold _ FALSE; -- driver "level" = 0 MnReset _ TRUE; -- driver "level" = 1 drive.s[MHold] _ drive.s[MnReset] _ Drive; -- driver "strength" = 1 -- DBus DShift _ DExecute _ DDataIn _ DNSelect _ FALSE; drive.s[DShift] _ drive.s[DExecute] _ drive.s[DDataIn] _ drive.s[DNSelect] _ Drive; drive.s[DDataOut] _ Ignore; -- PBus <-> Cache/FPU EPData _ BitDWordZero; drive.s[EPData] _ Ignore; EPFaultB _ Dragon.None; drive.s[EPFaultB] _ Drive; EPParityB _ EPRejectB _ FALSE; drive.s[EPParityB] _ drive.s[EPRejectB] _ Drive; EPNPErrorB _ TRUE; drive.s[EPNPErrorB] _ Drive; -- KBus <-> IFU KBus _ PackAddress[euConstant, euConstant, euJunk]; drive.s[KBus] _ Drive; EUAluLeftSrc1BA _ aBus; drive.s[EUAluLeftSrc1BA] _ Drive; EUAluRightSrc1BA _ bBus; drive.s[EUAluRightSrc1BA] _ Drive; EUStore2ASrc1BA _ bBus; drive.s[EUStore2ASrc1BA] _ Drive; EUAluOp2AB _ Or; drive.s[EUAluOp2AB] _ Drive; EUCondSel2AB _ False; drive.s[EUCondSel2AB] _ Drive; EURes3AisCBus2BA _ FALSE; drive.s[EURes3AisCBus2BA] _ Drive; EUSt3AisCBus2BA _ FALSE; drive.s[EUSt3AisCBus2BA] _ Drive; EURes3BisPBus3AB _ FALSE; drive.s[EURes3BisPBus3AB] _ Drive; EUCheckParity3AB _ FALSE; drive.s[EUCheckParity3AB] _ Drive; EUWriteToPBus3AB _ FALSE; drive.s[EUWriteToPBus3AB] _ Drive; drive.s[EUCondition2BA] _ Ignore; }; <<>> GeneratePattern: PROC [data: LONG CARDINAL, shift: INTEGER] RETURNS [bits: LONG CARDINAL] = { -- Use BitOps interface for twiddling bits --newLowWord: WORD _ BITSHIFT[lowWord, shift]; --bits _ BITOR[highWord, newLowWord]; bits _ 00000001H }; <<>> WriteRAM: PROC [address: CARDINAL, data: LONG CARDINAL] = { d: BitDWord _ ILID[data, BitDWordZero, 32, 0, 32]; PhAUp[]; PhADown[]; -- phase A pulse; level 1 -- IFU stimulates KBus control signal to setup rightOp2AB (1 phase in advance) EUAluRightSrc1BA _ kBus; -- latches on PhB; stable on PhA PhBUp[]; PhBDown[]; -- phase B pulse; level 1 -- IFU puts data word on KBus KBus _ d; -- will latch in next phase PhAUp[]; PhADown[]; -- level 2 EUAluRightSrc1BA _ bBus; -- to rightOp2AB OR-ed with euConst = 0 in ALU -- IFU puts address on KBus (simulation uses junk address) KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; PhAUp[]; PhADown[]; -- level 3 -- IFU puts valid cAddr on KBus (for write into RAM) KBus _ PackAddress[euConstant, euConstant, LOOPHOLE[address]]; PhBUp[]; PhBDown[]; PhAUp[]; --write into RAM takes place here; level 1 again PhADown[]; -- IFU addressing KBus period ( (using junk addr) KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; }; ReadRAM: PROC [address: CARDINAL, expectedData: LONG CARDINAL] = { PhAUp[]; PhADown[]; -- level 1 -- IFU puts valid aAddr on KBus (for read from RAM) KBus _ PackAddress[LOOPHOLE[address], euConstant, euJunk]; PhBUp[]; PhBDown[]; -- IFU stimulates KBus KBus _ PackAddress[euConstant, euConstant, euJunk]; PhAUp[]; PhADown[]; -- level 2 PhBUp[]; PhBDown[]; -- Move data onto PBus(of Cache) EPData _ ILID[expectedData, BitDWordZero, 32, 0, 32]; -- BitOps.InsertLongInDouble drive.s[EPData] _ Test; -- acquired by simulator for comparison PhAUp[]; -- level 3 drive.s[EPData] _ Ignore; -- tri-state driver between edges; prior to next Eval PhADown[]; PhBUp[]; PhBDown[]; }; IFURegisterOp: PROC [address, ifuReg: CARDINAL, expectedData: LONG CARDINAL] = { PhAUp[]; PhADown[]; -- 1 KBus _ PackAddress[LOOPHOLE[address], euConstant, euJunk]; -- get data out of RAM PhBUp[]; PhBDown[]; PhAUp[]; PhADown[]; -- 2 KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; PhAUp[]; PhADown[]; -- 3 KBus _ PackAddress[euConstant, euConstant, LOOPHOLE[ifuReg]]; PhBUp[]; PhBDown[]; KBus _ ILID[expectedData, BitDWordZero, 32, 0, 32]; -- put data on KBus - > IFU drive.s[KBus] _ Test; PhAUp[]; -- 4 drive.s[KBus] _ Ignore; -- tri-state the driver PhADown[]; KBus _ PackAddress[euConstant, euConstant, euJunk]; -- overwrite data on the bus drive.s[KBus] _ Drive; PhBUp[]; PhBDown[]; }; CacheReject: PROC = { EPRejectB _ TRUE; drive.s[EPRejectB] _ Drive; }; CachePageFault: PROC = { EPFaultB _ Dragon.Page; -- FPlsInfE drive.s[EPFaultB] _ Drive; }; ExerciseStack: PROC [fromReg, toReg: CARDINAL, data, eData: LONG CARDINAL] = { IF NOT(fromReg IN [0..128)) OR NOT(toReg IN [0..128)) THEN ERROR; FOR addr: CARDINAL IN [fromReg..toReg) DO WriteRAM[address: addr, data: data]; ReadRAM[address: addr, expectedData: eData]; ENDLOOP; }; ExerciseIStack: PROC [fromReg, toReg: CARDINAL, data, eData: LONG CARDINAL] = { addr: CARDINAL _ 0; IF NOT(fromReg IN [240..255]) OR NOT(toReg IN [240..255]) THEN ERROR; FOR cAddr: CARDINAL IN [fromReg..toReg] DO WriteRAM[address: addr, data: data]; IFURegisterOp[address: addr, ifuReg: cAddr, expectedData: eData]; ENDLOOP; }; ExerciseCacheExceptions: PROC [fault: Dragon.PBusFaults] = { ramAddr: CARDINAL _ 0; requestAddr: LONG CARDINAL _ 10101010H; IF fault = Dragon.None THEN RETURN; WriteRAM[address: ramAddr, data: requestAddr]; -- read operation puts data on PBus THROUGH [0..5) DO IF EPRejectB THEN EXIT; PhAUp[]; PhADown[]; -- 1 KBus _ PackAddress[LOOPHOLE[ramAddr], euConstant, euJunk]; PhBUp[]; PhBDown[]; PhAUp[]; PhADown[]; -- 2 KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; EPData _ ILID[requestAddr, BitDWordZero, 32, 0, 32]; drive.s[EPData] _ Test; PhAUp[]; -- 3 drive.s[EPData] _ Ignore; PhADown[]; CacheReject[]; -- "wait"; received during PhB KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; ENDLOOP; IF fault = Dragon.Page THEN CachePageFault[]; PhAUp[]; PhADown[]; KBus _ PackAddress[euConstant, euConstant, euJunk]; PhBUp[]; PhBDown[]; NullCycles[5]; }; <> <> <> <> <> <<>> <> <> <> <> <> Reset[]; ExerciseCacheExceptions[Dragon.Page]; END; END; ctest: RoseTypes.CellTest _ NEW[RoseTypes.CellTestRep _ ["ExerciseEveryBlock", EUTestExerciseEveryBlock, FALSE]]; ct: RoseTypes.CellType _ RoseCreate.GetCellType["EU"]; [] _ RoseCreate.SetTest[ctest, ct, TRUE]; END... of EUTest <> <<>> <> <> <> <> << >> <> <<(Examine simplest elements first)>> <> <> <>