DIRECTORY Core, Dragon, DragOpsCross, EUArith, ICTest, IO, Rope, RosemaryUser, Ports, TerminalIO; EUTestProcs: CEDAR PROGRAM IMPORTS EUArith, ICTest, IO, Ports, RosemaryUser, TerminalIO = BEGIN OPEN Core; ROPE: TYPE = Rope.ROPE; nbPhases: INT _ 0; REProc: TYPE = PROC [memory: BOOL _ TRUE]; Vdd, Gnd, PadVdd, PadGnd, PhA, PhB, DPRejectB, DPData, -- 32 bits KBus, -- 32 bits EURdFromPBus3AB, EUWriteToPBus3AB, EUAluOp2AB, -- 4 bits EUCondSel2AB, -- 4 bits EUCondition2B, DShA, DShB, DShRd, DShWt, DShIn, DShOut, DHold, DStAd: NAT _ LAST[NAT]; allOnes: LONG CARDINAL _ LOOPHOLE[LONG[-1]]; opName: ARRAY Dragon.ALUOps OF ROPE; Initialize: PROC [p: Ports.Port, public: Wire] = { [Vdd, Gnd, PadVdd, PadGnd, PhA, PhB, DPRejectB, DPData] _ Ports.PortIndexes[public, "Vdd", "Gnd", "PadVdd", "PadGnd", "PhA", "PhB", "DPRejectB", "DPData"]; [KBus, EURdFromPBus3AB, EUWriteToPBus3AB, EUAluOp2AB, EUCondSel2AB, EUCondition2B] _ Ports.PortIndexes[public, "KBus", "EURdFromPBus3AB", "EUWriteToPBus3AB", "EUAluOp2AB", "EUCondSel2AB", "EUCondition2B"]; [DShA, DShB, DShRd, DShWt, DShIn, DShOut, DHold, DStAd] _ Ports.PortIndexes[public, "DShA", "DShB", "DShRd", "DShWt", "DShIn", "DShOut", "DHold", "DStAd"]; p[DPRejectB].b _ FALSE; p[DShA].b _ p[DShB].b _ TRUE; -- hack to clean up the ShReg. p[DShRd].b _ p[DShWt].b _ p[DShIn].b _ p[DHold].b _ FALSE; p[DStAd].c _ 0; p[EUCondSel2AB].c _ 0; -- false p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[Or]]; -- 0 p[EURdFromPBus3AB].b _ TRUE; -- read data from PBus p[EUWriteToPBus3AB].b _ FALSE; -- and don't write onto PBus during PhB p[DShOut].b _ FALSE; p[DShOut].d _ none; p[EUCondition2B].b _ FALSE; p[EUCondition2B].d _ none; p[KBus].d _ none; p[DPData].d _ none; nbPhases _ 0; }; constAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euConstant]]; junkAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euJunk]]; ifuAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euToKBus]]; fieldAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euField]]; Phase: TYPE = {A, B}; DoPh: PROC [p: Ports.Port, Eval: REProc, ph: Phase] = { IF PhA=0 AND PhB=0 THEN ERROR; -- port indexes not initialized IF ph=A AND p[DPData].d=force THEN ERROR; p[PhA].b _ ph=A; p[PhB].b _ ph=B; Eval[]; p[PhA].b _ FALSE; p[PhB].b _ FALSE; Eval[ ! Ports.CheckError => RESUME]; nbPhases _ nbPhases+1; }; SlowPh: PROC [p: Ports.Port, Eval: REProc, ph: Phase] ~ {NULL}; Ignore: PROC [p: Ports.Port, port: NAT] ~ {p[port].d _ none}; Force: PROC [p: Ports.Port, port: NAT, val: LONG CARDINAL] ~ {p[port].d _ force; p[port].lc _ val}; Expect: PROC [p: Ports.Port, port: NAT, val: LONG CARDINAL] ~ {p[port].d _ expect; p[port].lc _ val}; PackK: PROC [a, b: NAT _ constAdr, c: NAT _ junkAdr, st3AisC: BOOL _ FALSE, aluL, aluR, st2A: NAT _ 0] RETURNS [k: LONG CARDINAL] ~ { k _ (((((LONG[a]*256+LONG[b])*256+LONG[c])*2+(IF st3AisC THEN 1 ELSE 0))*4+aluL)*8+aluR)*4+st2A; }; WriteInRam: PROC [p: Ports.Port, Eval: REProc, ad: NAT, val: LONG CARDINAL] ~ { Force[p, KBus, PackK[c: ad]]; -- load c address in kReg Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: kReg _ ad; dataIn _ val p[EURdFromPBus3AB].b _ TRUE; -- because of a bug, needed to let... p[EUWriteToPBus3AB].b _ TRUE; -- ... the cBus driver drive the bus Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: ram[ad] _ val p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; }; ReadFromRam: PROC [p: Ports.Port, Eval: REProc, ad: NAT, val: LONG CARDINAL, m: LONG CARDINAL _ 01234567H, slow: BOOL _ TRUE] ~ { p[EURdFromPBus3AB].b _ TRUE; Force[p, KBus, PackK[b: ad, st2A: 0]]; -- load b address in kReg Force[p, DPData, m]; -- to detect no drive on PBus DoPh[p, Eval, B]; -- 0B: kReg _ ad Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st2A _ ram[ad] Force[p, KBus, PackK[]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 1B: st2B _ st2A Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: st3A _ st2B p[EUWriteToPBus3AB].b _ TRUE; IF slow THEN SlowPh[p, Eval, B]; Force[p, KBus, PackK[]]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 2B: PBus _ st3A = val ??? p[EURdFromPBus3AB].b _ TRUE; p[EUWriteToPBus3AB].b _ FALSE; Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 3A: just for sync. }; FromPtoK: PROC [p: Ports.Port, Eval: REProc, val: LONG CARDINAL] ~ { p[EURdFromPBus3AB].b _ TRUE; p[EUWriteToPBus3AB].b _ FALSE; Force[p, KBus, PackK[c: ifuAdr]]; -- cBus->IFU on next PhA Force[p, DPData, val]; DoPh[p, Eval, B]; -- Cycle 0: dataIn _ val p[EURdFromPBus3AB].b _ TRUE; -- because of a bug, needed to let... p[EUWriteToPBus3AB].b _ TRUE; -- ... the cBus driver drive the bus SlowPh[p, Eval, A]; Ignore[p, DPData]; Expect[p, KBus, val]; DoPh[p, Eval, A]; -- Cycle 1: KBus _ cBus _ val p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; }; SanityCheck: RosemaryUser.TestProc = { FromPtoP2: PROC [val: LONG CARDINAL] ~ { p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; Force[p, KBus, PackK[st3AisC: TRUE]]; -- st3A _ cBus on next PhA Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: dataIn _ val p[EURdFromPBus3AB].b _ TRUE; -- because of a bug, needed to let... p[EUWriteToPBus3AB].b _ TRUE; -- ... the cBus driver drive the bus Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st3A _ cBus _ val p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ TRUE; SlowPh[p, Eval, B]; Force[p, KBus, PackK[]]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 1B: PBus _ st3A = val ??? p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: just for sync. }; FromPtoP4: PROC [val: LONG CARDINAL] ~ { p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; Force[p, KBus, PackK[st2A: 2]]; -- st2A _ cBus on next PhA Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: dataIn _ val p[EURdFromPBus3AB].b _ TRUE; -- because of a bug, needed to let... p[EUWriteToPBus3AB].b _ TRUE; -- ... the cBus driver drive the bus Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st2A _ cBus _ val Force[p, KBus, PackK[]]; Force[p, DPData, 01234567H]; -- to eliminate old (good) value on PBus DoPh[p, Eval, B]; -- 1B: st2B _ st2A Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: st3A _ st2B p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ TRUE; SlowPh[p, Eval, B]; Force[p, KBus, PackK[]]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 2B: PBus _ st3A = val ??? p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 3A: just for sync. }; Initialize[p, cellType.public]; FromPtoP4[000000000H]; FromPtoP4[0AAAAAAAAH]; FromPtoP4[055555555H]; FromPtoP4[0FFFFFFFFH]; FromPtoP4[02BAD2BADH]; FromPtoP2[000000000H]; FromPtoP2[0AAAAAAAAH]; FromPtoP2[055555555H]; FromPtoP2[0FFFFFFFFH]; FromPtoP2[02BAD2BADH]; FromPtoK[p, Eval,000000000H]; FromPtoK[p, Eval,0AAAAAAAAH]; FromPtoK[p, Eval,055555555H]; FromPtoK[p, Eval,0FFFFFFFFH]; FromPtoK[p, Eval,02BAD2BADH]; }; RamTest: RosemaryUser.TestProc = { CheckRamBlock: PROC [from, to: NAT] ~ { FOR i: NAT IN [from..to) DO IF i MOD 4 # 0 THEN WriteInRam[p, Eval, i, 55555555H]; ENDLOOP; FOR i: NAT IN [from..to) DO IF i MOD 4 # 0 THEN { ReadFromRam[p, Eval, i, 55555555H, i]; WriteInRam[p, Eval, i, 0AAAAAAAAH]}; ENDLOOP; FOR i: NAT IN [from..to) DO IF i MOD 4 # 0 THEN ReadFromRam[p, Eval, i, 0AAAAAAAAH, i]; ENDLOOP; }; Initialize[p, cellType.public]; CheckRamBlock[0, 160]; }; LoopRamTest: RosemaryUser.TestProc = { Initialize[p, cellType.public]; WriteInRam[p, Eval, 1, 000000000H]; ReadFromRam[p, Eval, 1, 000000000H,, FALSE]; WriteInRam[p, Eval, 1, 0FFFFFFFFH]; ReadFromRam[p, Eval, 1, 0FFFFFFFFH,, FALSE]; }; LoopAddTest: RosemaryUser.TestProc = { Initialize[p, cellType.public]; ALUOp[p, Eval, VAdd, 000000001H, 0FFFFFFFFH, 000000000H] }; ALUOp: PROC [p: Ports.Port, Eval: REProc, op: Dragon.ALUOps, opL, opR, res: LONG CARDINAL, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE, slow: BOOL _ FALSE] ~ { lAd: NAT = 1; rAd: NAT = 3; WriteInRam[p, Eval, lAd, opL]; WriteInRam[p, Eval, rAd, opR]; p[EURdFromPBus3AB].b _ FALSE; Force[p, KBus, PackK[a: lAd, b: rAd]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 0B: aAdr _ lAd, bAdr _ rAd p[EUAluOp2AB].c _ ORD[op]; Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: opL _ ram[lAd]; opR _ ram[rAd] p[EUCondSel2AB].c _ ORD[cc]; IF slow THEN SlowPh[p, Eval, B]; p[EUCondition2B].b _ cond; p[EUCondition2B].d _ expect; p[DShOut].b _ FALSE; p[DShOut].d _ expect; Force[p, KBus, PackK[]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 1B: r2B _ opL op opR TerminalIO.PutF["ALU, phase %g: %g (%g) %g -> %g", IO.card[nbPhases], IO.card[opL], IO.rope[opName[op]], IO.card[opR], IO.card[res]]; TerminalIO.PutF[" cc: %g\n", IO.int[ORD[cc]]]; p[EUCondSel2AB].c _ 0; p[EUCondition2B].b _ FALSE; p[EUCondition2B].d _ none; p[DShOut].d _ none; IF slow THEN SlowPh[p, Eval, A]; Ignore[p, KBus]; Expect[p, DPData, res]; DoPh[p, Eval, A]; -- 2A: PBus _ r2B p[EUAluOp2AB].c _ 0; }; ALUTest: RosemaryUser.TestProc = { ResetCarry: PROC ~ {TestALU[LAdd, 0, 0, 0,,, TRUE]}; SetCarry: PROC ~ {TestALU[UAdd, 0FFFFFFFFH, 000000001H, 0,,, TRUE]}; TestALU: PROC [op: Dragon.ALUOps, opL, opR, res: LONG CARDINAL, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE, slow: BOOL _ FALSE] ~ { ALUOp[p, Eval, op, opL, opR, res, cc, cond, slow]; }; TestAdd: PROC [op: Dragon.ALUOps] ~ { IF op#SAdd AND op#UAdd AND op#VAdd AND op#LAdd AND op#VAdd2 THEN ERROR; ResetCarry[]; TestALU[op, 000000000H, 000000000H, 000000000H]; TestALU[op, 000000001H, 000000002H, 000000003H]; TestALU[op, 00FFFFFFFH, 000000001H, 010000000H]; TestALU[op, 012345678H, 087654321H, 099999999H]; TestALU[op, 0FFFFFFFFH, 000000000H, 0FFFFFFFFH]; TestALU[op, 000000000H, 0FFFFFFFFH, 0FFFFFFFFH]; TestALU[op, 000000001H, 0FFFFFFFFH, 000000000H]; ResetCarry[]; }; TestSub: PROC [op: Dragon.ALUOps] ~ { IF op#SSub AND op#USub AND op#VSub AND op#LSub THEN ERROR; TestALU[op, 000000000H, 000000000H, 000000000H]; TestALU[op, 000000003H, 000000002H, 000000001H]; TestALU[op, 010000000H, 000000001H, 00FFFFFFFH]; TestALU[op, 099999999H, 087654321H, 012345678H]; TestALU[op, 0FFFFFFFFH, 000000000H, 0FFFFFFFFH]; TestALU[op, 0FFFFFFFFH, 0FFFFFFFFH, 000000000H]; TestALU[op, 000000000H, 0FFFFFFFFH, 000000001H]; ResetCarry[]; }; Initialize[p, cellType.public]; TerminalIO.PutF["New Test\n"]; TestALU[BndChk, 000000000H, 000000000H, 000000000H]; TestALU[BndChk, 055555555H, 000000000H, 055555555H]; TestALU[BndChk, 0AAAAAAAAH, 000000000H, 0AAAAAAAAH]; TestALU[BndChk, 0FFFFFFFFH, 000000000H, 0FFFFFFFFH]; TestALU[Or, 000FF00FFH, 00F0F0F0FH, 00FFF0FFFH]; TestALU[And, 000FF00FFH, 00F0F0F0FH, 0000F000FH]; TestALU[Xor, 000FF00FFH, 00F0F0F0FH, 00FF00FF0H]; TestAdd[SAdd]; TestAdd[UAdd]; TestAdd[VAdd]; TestAdd[LAdd]; TestAdd[VAdd2]; TestSub[SSub]; TestSub[USub]; TestSub[VSub]; TestSub[LSub]; TestALU[LAdd, 000000000H, 000000000H, 000000000H, False, FALSE]; TestALU[LAdd, 000000000H, 000000000H, 000000000H, ModeFault, TRUE]; ResetCarry[]; TestALU[BndChk, 000000000H, 000000001H, 000000000H, BC, TRUE]; ResetCarry[]; TestALU[BndChk, 000000002H, 000000001H, 000000002H, BC, FALSE]; ResetCarry[]; TestALU[BndChk, 000000000H, 000000001H, 000000000H, NotBC, FALSE]; ResetCarry[]; TestALU[BndChk, 000000002H, 000000001H, 000000002H, NotBC, TRUE]; TestALU[LAdd, 07FFFFFFFH, 000000001H, 080000000H, IL, TRUE]; -- opL=011 TestALU[LAdd, 000000000H, 0FFFFFFFFH, 0FFFFFFFFH, IL, FALSE]; -- all 0 or 1 TestALU[LAdd, 010000000H, 010000000H, 020000000H, IL, TRUE]; -- res=001 TestALU[LAdd, 000000001H, 000000001H, 000000002H, IL, FALSE]; -- all 0 TestALU[LAdd, 07FFFFFFFH, 000000001H, 080000000H, NotIL, FALSE]; -- opL=011 TestALU[LAdd, 000000000H, 0FFFFFFFFH, 0FFFFFFFFH, NotIL, TRUE]; -- all 0 or 1 TestALU[LAdd, 010000000H, 010000000H, 020000000H, NotIL, FALSE]; -- res=001 TestALU[LAdd, 000000001H, 000000001H, 000000002H, NotIL, TRUE]; -- all 0 ResetCarry[]; TestALU[USub, 000000000H, 000000000H, 000000000H, EZ, TRUE]; TestALU[USub, 02BAD2BADH, 02BAD2BADH, 000000000H, EZ, TRUE]; TestALU[USub, 0FFFFFFFFH, 0FFFFFFFFH, 000000000H, EZ, TRUE]; TestALU[USub, 000000001H, 000000000H, 000000001H, EZ, FALSE]; TestALU[USub, 02BAD2BADH, 000000001H, 02BAD2BACH, EZ, FALSE]; TestALU[USub, 000000001H, 000000002H, 0FFFFFFFFH, EZ, FALSE]; }; LoopFUTest: RosemaryUser.TestProc = { Initialize[p, cellType.public]; FUOp[p, Eval, 000000001H, 0FFFFFFFFH, 32, 0, TRUE] }; FUOp: PROC [p: Ports.Port, Eval: REProc, leftW, rightW, mask, shift: LONG CARDINAL, insert: BOOL _ FALSE] ~ { fd: NAT _ ((IF insert THEN 1 ELSE 0)*64+mask)*64+shift; res: LONG CARDINAL _ EUArith.FieldOp[leftW, rightW, fd]; TerminalIO.PutF["FU, phase %g, mask: %g, shift: %g, insert: %g\n", IO.card[nbPhases], IO.card[mask], IO.card[shift], IO.bool[insert]]; WriteInRam[p, Eval, fieldAdr, LONG[fd]]; -- field_fd WriteInRam[p, Eval, 1, leftW]; -- ram[0]_leftW WriteInRam[p, Eval, 2, rightW]; -- ram[1]_rightW Force[p, KBus, PackK[a: 1, b: 2, aluR: 4]]; -- right_field; left_leftW; st2A_rightW Ignore[p, DPData]; DoPh[p, Eval, B]; -- 0B: load operand addresses p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[FOP]]; Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: read ram Force[p, KBus, PackK[]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 1B: field unit is active SlowPh[p, Eval, A]; Ignore[p, KBus]; Expect[p, DPData, res]; DoPh[p, Eval, A]; -- 2A: PBus _ r2B }; FUTest: RosemaryUser.TestProc = { TestFU: PROC [leftW, rightW, mask, shift: LONG CARDINAL, insert: BOOL _ FALSE] ~ { FUOp[p, Eval, leftW, rightW, mask, shift, insert]; }; Initialize[p, cellType.public]; FOR shift: NAT IN [0..32] DO TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: 32, shift: shift]; ENDLOOP; FOR shift: NAT IN [0..32] DO TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: shift, shift: 0]; ENDLOOP; FOR i: NAT IN [0..32] DO TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: (4*i+19) MOD 33, shift: (3*i+5) MOD 33]; ENDLOOP; TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 0, shift: 0, insert: TRUE]; TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 32, shift: 0, insert: TRUE]; TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 32, shift: 32, insert: TRUE]; TestFU[leftW: 0F0402010H, rightW: 0AAAAAAAAH, mask: 18, shift: 4, insert: TRUE]; TestFU[leftW: 0F0402010H, rightW: 02BAD2BADH, mask: 21, shift: 12, insert: TRUE]; }; QADTest: RosemaryUser.TestProc = { ReadFromReg: PROC [reg: NAT, val: LONG CARDINAL] ~ { p[EURdFromPBus3AB].b _ TRUE; -- read data from PBus, and keep cBus clean Force[p, KBus, PackK[c: ifuAdr]]; -- cBus->IFU on next PhA Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: dataIn _ val p[DShA].b _ FALSE; p[DShB].b _ FALSE; p[DShRd].b _ TRUE; p[DShWt].b _ FALSE; p[DHold].b _ TRUE; p[DStAd].c _ reg; SlowPh[p, Eval, A]; Expect[p, KBus, val]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: KBus _ cBus _ val p[EURdFromPBus3AB].b _ FALSE; p[DShRd].b _ FALSE; p[DHold].b _ FALSE; }; Initialize[p, cellType.public]; }; LoopTest: RosemaryUser.TestProc = { Initialize[p, cellType.public]; FromPtoK[p, Eval,000000000H]; FromPtoK[p, Eval,0FFFFFFFFH]; }; euTest: ROPE = "EU2 Test"; opName[Or] _ "Or"; opName[And] _ "And"; opName[VAdd2] _ "VAdd2"; opName[BndChk] _ "BndChk"; opName[SAdd] _ "SAdd"; opName[SSub] _ "SSub"; opName[LAdd] _ "LAdd"; opName[LSub] _ "LSub"; opName[Xor] _ "Xor"; opName[res9] _ "res9"; opName[FOP] _ "FOP"; opName[res11] _ "res11"; opName[VAdd] _ "VAdd"; opName[VSub] _ "VSub"; opName[UAdd] _ "UAdd"; opName[USub] _ "USub"; ICTest.RegisterTestProc[euTest, "Sanity Check", SanityCheck]; ICTest.RegisterTestProc[euTest, "RamTest", RamTest]; ICTest.RegisterTestProc[euTest, "ALUTest", ALUTest]; ICTest.RegisterTestProc[euTest, "FUTest", FUTest]; ICTest.RegisterTestProc[euTest, "LoopTest", LoopTest]; ICTest.RegisterTestProc[euTest, "QADTest", QADTest]; ICTest.RegisterTestProc[euTest, "LoopRam", LoopRamTest]; ICTest.RegisterTestProc[euTest, "LoopAdd", LoopAddTest]; ICTest.RegisterTestProc[euTest, "LoopFU", LoopFUTest]; RosemaryUser.RegisterTestProc["Sanity Check", SanityCheck]; END. ΎEUTestProcs.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Louis Monier July 31, 1985 3:03:17 pm PDT Last Edited by: Louis Monier January 27, 1987 11:09:05 am PST Last Edited by: Gasbarro October 15, 1986 2:06:13 pm PDT -- Initial values -- Invariants -- On PhA the chip always drives the PBus, so we check that the tester is not driving -- appropriate clock up -- both clocks down SlowPh: PROC [p: Ports.Port, Eval: REProc, ph: Phase] ~ { Ignore[p, KBus]; Ignore[p, DPData]; p[PhA].b _ ph=A; p[PhB].b _ ph=B; Eval[]; Eval[]; }; -- From PBus to dataIn to cBus to KBus -- The minimum expected from a chip -- Test the entire RAM (minus the quarter with broken bit lines) Illinois: RosemaryUser.TestProc = { CycleRAM: PROC [address: CARDINAL, data: CARDINAL, write: BOOL] = { AccessRAM[write: write, address: address, data: data, p: p, Eval: Eval]; }; HalfStep: PROC [upper: BOOL, data: BOOL, write: BOOL] = { address: CARDINAL _ IF upper THEN halfBit ELSE 0; addressMod: CARDINAL; DO CycleRAM[address, IF data THEN LAST[CARDINAL] ELSE 0, write]; address _ address + 1; addressMod _ address MOD (2*halfBit); IF (upper AND addressMod=0) OR (NOT upper AND addressMod=halfBit) THEN address _ address + halfBit; IF address>=Size THEN EXIT; ENDLOOP; }; StepIndex: TYPE = [0..8); complementUpper: ARRAY StepIndex OF BOOL = [TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,TRUE,FALSE]; writeData: ARRAY StepIndex OF BOOL = [TRUE,FALSE,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE]; readData: ARRAY StepIndex OF BOOL = [FALSE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE]; halfBit: CARDINAL _ BitOps.TwoToThe[addressBits]; InitRAM[p, Eval]; write zero to all locations divide RAM by columns instead of rows FOR address: CARDINAL IN [0..Size) DO CycleRAM[address, 0, TRUE]; ENDLOOP; UNTIL (halfBit _ halfBit/2) = 4 DO FOR step: StepIndex IN StepIndex DO HalfStep[upper: complementUpper[step], data: writeData[step], write: TRUE]; HalfStep[upper: NOT complementUpper[step], data: readData[step], write: FALSE]; ENDLOOP; ENDLOOP; }; -- may generates a carry -- may generates a carry Check integrity of aluLeft-> r2B-> pDriver path (passed) Logic operations (passed) All additions (passed) All subtractions (passed) Constant Conditions (passed) BC _ ~Cout (passed) IL _ all 3 high-order bits equal (passed) EZ _ zero, found after a sub at the top of the CLA tree (passed) -- LZ _ Cout XOR opL[0] XOR opR[0], so we need a carry out; GE _ ~ LZ ResetCarry[]; TestALU[USub, 000000000H, 000000001H, 0FFFFFFFFH, LZ, TRUE]; ResetCarry[]; TestALU[UAdd, 000000000H, 000000000H, 000000000H, LZ, FALSE]; ResetCarry[]; TestALU[UAdd, 000000000H, 000000000H, 000000000H, GE, TRUE]; ResetCarry[]; TestALU[USub, 000000000H, 000000001H, 0FFFFFFFFH, GE, FALSE]; -- LE _ EZ OR LZ TestALU[USub, 000000000H, 000000000H, 000000000H, LE, TRUE]; TestALU[USub, 000000001H, 000000000H, 000000001H, LE, FALSE]; TestALU[USub, 000000001H, 000000000H, 000000001H, NE, TRUE]; TestALU[USub, 000000001H, 000000001H, 000000000H, NE, FALSE]; TestALU[USub, 000000001H, 000000000H, 000000001H, GZ, TRUE]; TestALU[USub, 000000000H, 000000000H, 000000000H, GZ, FALSE]; -- OvFl _ (Cout XOR opL[0] XOR opR[0]) XOR res[0], so we need a carry out; ResetCarry[]; TestALU[UAdd, 0FFFFFFFFH, 000000001H, 000000000H, OvFl, TRUE]; ResetCarry[]; TestALU[UAdd, 0FFFFFFFFH, 000000000H, 0FFFFFFFFH, OvFl, FALSE]; -- Testing the shifter (no masking) (passed) -- Testing the mask generator (no shifting) (passed) -- General Shift and Mask test (passed) -- With insert (passed) ΚP– "cedar" style˜codešœ™Jšœ Οmœ1™Kšœ £œ˜ Kš£œ£&ž£€£˜?Kšœ £œ˜ Kš£œ£&œ£€£˜BKšœ £œ˜ Kš£œ£&œ£€£˜A—šœ"₯œ™)Kš£2ž£€£Πcf ˜GKš£2ž£€£¦ ˜KKš£2ž£€£¦ ˜GKš£2ž£€£¦˜FKš£2œ£€£¦ ˜KKš£2œ£€£¦ ˜MKš£2œ£€£¦ ˜KKš£2œ£€£¦˜H—šœ9₯œ™@Kšœ £œ˜ Kš£œ£&€£€£˜Kšœ £œ™ Kš£œ£&œ£€£™?—Kšœ˜K˜—šŸ œ˜%Kšœ˜Kšœ£€œ˜2Kšœ˜K˜K˜—šŸœžœŸœžœžœžœ žœžœ˜mKš œžœžœžœžœ˜7Kšœžœžœ&˜8Kš œCžœžœ žœžœ˜†Kšœžœ  ˜4Kšœ  ˜/Kšœ! ˜1K˜Kšœ, '˜Sšœ˜Jšœ ’ ˜5—Kšœžœžœ˜*Kšœ˜šœ˜Jšœ ’  ˜'—Kšœ˜šœ˜Jšœ ’ ˜3—Kšœ˜Kšœ˜šœ˜Jšœ ’  ˜)—K˜—šŸœ˜!š Ÿœžœžœžœ žœžœ˜RKšœ2˜2K˜—Kšœ˜šœ%₯œ™,šžœžœžœ ž˜KšœF˜FKšžœ˜——šœ-₯œ™4šžœžœžœ ž˜KšœE˜EKšžœ˜——šœ ₯œ™'šžœžœžœ ž˜Kšœ=žœžœ˜\Kšžœ˜——šœ₯œ™Kšœ"£ œžœ˜OKšœ"£ œžœ˜PKšœ"£ œžœ˜QKšœJžœ˜PKšœ"£ œžœ˜Q—Kšœ˜—K˜šŸœ˜"š Ÿ œžœžœžœžœ˜4Kšœžœ +˜HKšœ" ˜:šœ˜Jšœ ’ ˜-—Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜šœ˜Jšœ ’ ˜2—Kšœžœ˜Kšœ žœ˜Kšœ žœ˜K˜—Kšœ˜Kšœ˜—K˜šŸœ˜#Kšœ˜Kš£˜Kš£˜Kšœ˜—K˜Kšœžœ˜Kšœ*˜*Kšœ5˜5Kšœ.˜.Kšœ.˜.Kšœ,˜,Kšœžœ$˜.Kšœ/˜/Kšœ.˜.K˜Kšœ=˜=Kšœ4˜4Kšœ4˜4Kšœ2˜2Kšœ6˜6Kšœ4˜4Kšœ8˜8Kšœ8˜8Kšœ6˜6K˜Kšœ;˜;K˜Kšžœ˜K˜K˜—…—?ddr