DIRECTORY BitOps, Core, CoreFlat, Dragon, DragOpsCross, EUArith, ICTest, IO, Rope, Rosemary, RosemaryUser, Ports, TerminalIO; EUSim: CEDAR PROGRAM IMPORTS BitOps, CoreFlat, EUArith, ICTest, IO, Rosemary, RosemaryUser, Ports, TerminalIO = BEGIN ROPE: TYPE = Rope.ROPE; nbPhases: INT _ 0; 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]; REProc: TYPE = PROC [memory: BOOL _ TRUE]; Initialize: PROC [p: Ports.Port, public: Core.Wire] = { InitializePublic[public]; p[DPRejectB].b _ FALSE; p[DShA].b _ p[DShB].b _ FALSE; 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 _ FALSE; -- don't 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; }; InitializePublic: PROC [public: Core.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"]; [] _ Rosemary.SetFixedWire[public[Vdd], H]; [] _ Rosemary.SetFixedWire[public[Gnd], L]; [] _ Rosemary.SetFixedWire[public[PadVdd], H]; [] _ Rosemary.SetFixedWire[public[PadGnd], L]; [] _ Ports.InitTesterDrive[public[PhA], force]; [] _ Ports.InitTesterDrive[public[PhB], force]; [] _ Ports.InitTesterDrive[public[DPRejectB], force]; [] _ Ports.InitPort[public[DPData], lc]; [] _ Ports.InitTesterDrive[public[DPData], expect]; [] _ Ports.InitPort[public[KBus], lc]; [] _ Ports.InitTesterDrive[public[KBus], force]; [] _ Ports.InitTesterDrive[public[EURdFromPBus3AB], force]; [] _ Ports.InitTesterDrive[public[EUWriteToPBus3AB], force]; [] _ Ports.InitPort[public[EUAluOp2AB], c]; [] _ Ports.InitTesterDrive[public[EUAluOp2AB], force]; [] _ Ports.InitPort[public[EUCondSel2AB], c]; [] _ Ports.InitTesterDrive[public[EUCondSel2AB], force]; [] _ Ports.InitTesterDrive[public[EUCondition2B], expect]; [] _ Ports.InitTesterDrive[public[DShA], force]; [] _ Ports.InitTesterDrive[public[DShB], force]; [] _ Ports.InitTesterDrive[public[DShRd], force]; [] _ Ports.InitTesterDrive[public[DShWt], force]; [] _ Ports.InitTesterDrive[public[DShIn], force]; [] _ Ports.InitTesterDrive[public[DHold], force]; [] _ Ports.InitPort[public[DStAd], c]; [] _ Ports.InitTesterDrive[public[DStAd], force]; [] _ Ports.InitTesterDrive[public[DShOut], none]; }; ExerciseRose: PUBLIC PROC [ct: Core.CellType, cutSets: LIST OF ROPE _ NIL] RETURNS [tester: RosemaryUser.Tester] = { InitializePublic[ct.public]; tester _ RosemaryUser.TestProcedureViewer[ cellType: ct, testButtons: LIST["AllTests", "ZeroAndOne", "Sanity Check", "RamTest", "ALUTest", "FUTest", "WiresTest", "DBusTest"], name: "EUTest", displayWires: RosemaryUser.DisplayPortLeafWires[ct], cutSet: CoreFlat.CreateCutSet[labels: cutSets], steady: FALSE]; }; stackAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euStack]]; junkAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euJunk]]; ifuAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euToKBus]]; marAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euMAR]]; fieldAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euField]]; constAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euConstant]]; bogusAdr: NAT = ORD[DragOpsCross.ProcessorRegister[euBogus]]; Phase: TYPE = {A, B}; DoPh: PROC [p: Ports.Port, Eval: REProc, ph: Phase] = { nbPhases _ nbPhases+1; 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[FALSE]; p[PhA].b _ FALSE; p[PhB].b _ FALSE; Eval[FALSE ! Ports.CheckError =>RESUME]; }; Ignore: PROC [p: Ports.Port, port: NAT] ~ {p[port].d _ none}; Force: PROC [p: Ports.Port, port: NAT, val: CARD] ~ {p[port].d _ force; p[port].lc _ val}; Expect: PROC [p: Ports.Port, port: NAT, val: CARD] ~ {p[port].d _ expect; p[port].lc _ val}; ReadPBus: PROC [p: Ports.Port] ~ { p[EURdFromPBus3AB].b _ TRUE; p[EUWriteToPBus3AB].b _ FALSE; }; WritePBus: PROC [p: Ports.Port] ~ { p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ TRUE; }; IgnorePBus: PROC [p: Ports.Port] ~ { p[EURdFromPBus3AB].b _ FALSE; p[EUWriteToPBus3AB].b _ FALSE; }; PackK: PROC [a, b: NAT _ constAdr, c: NAT _ junkAdr, st3AisC: BOOL _ FALSE, aluL, aluR, st2A: NAT _ 0] RETURNS [k: CARD] ~ { 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: CARD] ~ { Force[p, KBus, PackK[c: ad]]; -- load c address in kReg ReadPBus[p]; Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: kReg _ ad; dataIn _ val Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: ram[ad] _ val }; ReadFromRam: PROC [p: Ports.Port, Eval: REProc, ad: NAT, val: CARD, m: CARD _ 01234567H] ~ { Force[p, KBus, PackK[b: ad, st2A: 0]]; -- load b address in kReg ReadPBus[p]; Force[p, DPData, m]; -- to detect no drive on PBus DoPh[p, Eval, B]; -- 0B: kReg _ ad Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st2A _ ram[ad] CheckSt2A[p, Eval, val]; -- 4 more phases }; PutValInR2B: PROC [p: Ports.Port, Eval: REProc, val, k: CARD] ~ { Force[p, KBus, PackK[a: constAdr, aluR: 3]]; -- load addresses in kReg IgnorePBus[p]; Force[p, DPData, 0]; -- to detect no drive on PBus DoPh[p, Eval, B]; -- 0B: kReg _ ad Force[p, KBus, val]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: left _ ram[ad], right _ kBus p[EUAluOp2AB].c _ 0; -- ORD[Or] Force[p, KBus, k]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 1B: r2B _ right }; PutValInR3B: PROC [p: Ports.Port, Eval: REProc, val, k: CARD, reject: BOOL _ FALSE] ~ { PutValInR2B[p, Eval, val, PackK[]]; -- 1B: r2B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: r3A _ val IF reject THEN p[DPRejectB].b _ TRUE; Force[p, KBus, k]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 2B: r3B _ val p[DPRejectB].b _ FALSE; }; CheckSt2A: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { Force[p, KBus, PackK[]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 0B: st2B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st3A _ val Force[p, KBus, PackK[]]; WritePBus[p]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 1B: PBus _ st3A = val ??? Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: just for sync. }; OpAndCheck: PROC [p: Ports.Port, Eval: REProc, val: CARD, op: NAT] ~ { p[EUAluOp2AB].c _ op; -- ORD[alu opcode] Force[p, KBus, PackK[]]; Ignore[p, DPData]; DoPh[p, Eval, B]; -- 0B: r2B _ val Ignore[p, KBus]; Expect[p, DPData, val]; DoPh[p, Eval, A]; -- 1A: PBus _ r2B = val ???. }; FromPtoK: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { Force[p, KBus, PackK[c: ifuAdr]]; -- cBus->IFU on next PhA ReadPBus[p]; Force[p, DPData, val]; DoPh[p, Eval, B]; -- Cycle 0: dataIn _ val Expect[p, KBus, val]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- Cycle 1: KBus _ cBus _ val IgnorePBus[p]; }; ALUOp: PROC [p: Ports.Port, Eval: REProc, op: Dragon.ALUOps, opL, opR, res: CARD, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE] ~ { lAd: NAT = 1; rAd: NAT = 3; 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]]]; 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]; 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 p[EUCondSel2AB].c _ 0; p[EUCondition2B].b _ FALSE; p[EUCondition2B].d _ none; p[DShOut].d _ none; Ignore[p, KBus]; Expect[p, DPData, res]; DoPh[p, Eval, A]; -- 2A: PBus _ r2B p[EUAluOp2AB].c _ 0; }; FUOp: PROC [p: Ports.Port, Eval: REProc, leftW, rightW, mask, shift: CARD, insert: BOOL _ FALSE] ~ { fd: NAT _ ((IF insert THEN 1 ELSE 0)*64+mask)*64+shift; res: CARD _ 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 Ignore[p, KBus]; Expect[p, DPData, res]; DoPh[p, Eval, A]; -- 2A: PBus _ r2B }; AllTests: RosemaryUser.TestProc = { TerminalIO.PutRope["Starting AllTests"]; ZeroAndOne[cellType, p, Eval]; SanityCheck[cellType, p, Eval]; WiresTest[cellType, p, Eval]; DBusTest[cellType, p, Eval]; ALUTest[cellType, p, Eval]; FUTest[cellType, p, Eval]; RamTest[cellType, p, Eval]; TerminalIO.PutRope["Finished with AllTests"]; }; ZeroAndOne: RosemaryUser.TestProc = { TerminalIO.PutRope["Starting ZeroAndOne"]; Initialize[p, cellType.public]; FromPtoK[p, Eval,000000000H]; FromPtoK[p, Eval,0FFFFFFFFH]; FromPtoK[p, Eval,05555AAAAH]; TerminalIO.PutRope["Finished with ZeroAndOne"]; }; SanityCheck: RosemaryUser.TestProc = { FromPtoP2: PROC [val: CARD] ~ { Force[p, KBus, PackK[st3AisC: TRUE]]; -- st3A _ cBus on next PhA ReadPBus[p]; Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: dataIn _ val Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st3A _ cBus _ dataIn (val) Force[p, KBus, PackK[]]; WritePBus[p]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 1B: PBus _ st3A = val ??? Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: just for sync. }; FromPtoP4: PROC [val: CARD] ~ { Force[p, KBus, PackK[st2A: 2]]; -- st2A _ cBus on next PhA ReadPBus[p]; Force[p, DPData, val]; DoPh[p, Eval, B]; -- 0B: dataIn _ val Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 1A: st2A _ cBus _ val Force[p, KBus, PackK[]]; IgnorePBus[p]; Force[p, DPData, 01234567H]; -- to eliminate old (good) value on PBus DoPh[p, Eval, B]; -- 1B: st2B _ st2A Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: st3A _ st2B Force[p, KBus, PackK[]]; WritePBus[p]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 2B: PBus _ st3A = val ??? Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 3A: just for sync. }; TerminalIO.PutRope["Starting SanityCheck"]; 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]; TerminalIO.PutRope["Finished with SanityCheck"]; }; RamTest: RosemaryUser.TestProc = { Val: PROC [i: NAT] RETURNS [val: CARD] ~ { val _ 0137FA00H+i; }; CheckRamBlock: PROC [from, to: NAT] ~ { FOR i: NAT IN [from..to) DO WriteInRam[p, Eval, i, 0137FA00H+i]; ENDLOOP; FOR i: NAT IN [from..to) DO ReadFromRam[p, Eval, i, 0137FA00H+i]; WriteInRam[p, Eval, i, 0FEC8500H+0FFH-i]; ENDLOOP; FOR i: NAT IN [from..to) DO ReadFromRam[p, Eval, i, 0FEC8500H+0FFH-i]; ENDLOOP; }; TerminalIO.PutRope["Starting RamTest"]; Initialize[p, cellType.public]; CheckRamBlock[stackAdr, junkAdr]; CheckRamBlock[junkAdr+1, constAdr]; -- avoid euJunk, since it should not exist CheckRamBlock[constAdr+4, bogusAdr]; ReadFromRam[p, Eval, constAdr, 0]; ReadFromRam[p, Eval, constAdr+1, 1]; ReadFromRam[p, Eval, constAdr+2, 2]; ReadFromRam[p, Eval, constAdr+3, 3]; TerminalIO.PutRope["Finished with RamTest"]; }; ALUTest: RosemaryUser.TestProc = { ResetCarry: PROC ~ {TestALU[LAdd, 0, 0, 0]}; SetCarry: PROC ~ {TestALU[UAdd, 0FFFFFFFFH, 000000001H, 0]}; TestALU: PROC [op: Dragon.ALUOps, opL, opR, res: CARD, cc: Dragon.CondSelects _ False, cond: BOOL _ FALSE] ~ { ALUOp[p, Eval, op, opL, opR, res, cc, cond]; }; 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[]; }; TerminalIO.PutRope["Starting ALUTest"]; Initialize[p, cellType.public]; TerminalIO.PutF["New Test\n"]; ResetCarry[]; TestALU[UAdd, 07FFFFFFFH, 000000001H, 080000000H, OvFl, TRUE]; ResetCarry[]; TestALU[UAdd, 07FFFFFFFH, 000000000H, 07FFFFFFFH, OvFl, FALSE]; ResetCarry[]; TestALU[BndChk, 000000000H, 000000001H, 000000000H, BC, FALSE]; ResetCarry[]; TestALU[BndChk, 000000002H, 000000001H, 000000002H, BC, TRUE]; ResetCarry[]; TestALU[BndChk, 000000000H, 000000001H, 000000000H, NotBC, TRUE]; ResetCarry[]; TestALU[BndChk, 000000002H, 000000001H, 000000002H, NotBC, FALSE]; 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]; ResetCarry[]; 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]; 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]; 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]; TerminalIO.PutRope["Finished with ALUTest"]; }; FUTest: RosemaryUser.TestProc = { TestFU: PROC [leftW, rightW, mask, shift: CARD, insert: BOOL _ FALSE] ~ { FUOp[p, Eval, leftW, rightW, mask, shift, insert]; }; TerminalIO.PutRope["Starting FUTest"]; 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]; TerminalIO.PutRope["Finished with FUTest"]; }; EUTest: RosemaryUser.TestProc = { }; c1: CARD = 00137FFFFH; c2: CARD = 0FEC80000H; R3BNormal: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR3B[p, Eval, val, PackK[st3AisC: TRUE]];-- 2B: r3B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 3A: st3A _ val Force[p, KBus, PackK[]]; WritePBus[p]; Expect[p, DPData, val]; DoPh[p, Eval, B]; -- 3B: PBus _ st3A = val ??? Ignore[p, KBus]; IgnorePBus[p]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 4A: just for sync. }; R3BReject: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR3B[p, Eval, val, PackK[], TRUE];-- 2B: r3B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 3A: ram[marAdr] _ cBus _ val (reject) ReadFromRam[p, Eval, marAdr, val]; -- check marAdr }; R2BtoLeft: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR2B[p, Eval, val, PackK[b: constAdr, aluL: 1]]; -- 1B: r2B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: left _ r2B _ val; right _ 0 OpAndCheck[p, Eval, val, 0]; }; R2BtoRight: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR2B[p, Eval, val, PackK[a: constAdr, aluR: 1]]; -- 1B: r2B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: right _ r2B _ val; left _ 0 OpAndCheck[p, Eval, val, 0]; }; R2BtoSt2A: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR2B[p, Eval, val, PackK[a: constAdr, st2A: 1]]; -- 1B: r2B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: st2A _ r2B _ val CheckSt2A[p, Eval, val]; }; CBustoLeft: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR3B[p, Eval, val, PackK[b: constAdr, aluL: 2]]; -- 1B: r3B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: left _ r2B _ val; right _ 0 OpAndCheck[p, Eval, val, 0]; }; CBustoRight: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR3B[p, Eval, val, PackK[a: constAdr, aluR: 2]]; -- 1B: r3B _ val Ignore[p, KBus]; Ignore[p, DPData]; DoPh[p, Eval, A]; -- 2A: right _ r2B _ val; left _ 0 OpAndCheck[p, Eval, val, 0]; }; WiresTest: RosemaryUser.TestProc = { TryAllPaths: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { FromPtoK[p, Eval, val]; -- 4 evals R3BNormal[p, Eval, val]; -- 24 evals R3BReject[p, Eval, val]; -- 24 evals R2BtoLeft[p, Eval, val]; -- 12 evals R2BtoRight[p, Eval, val]; -- 12 evals R2BtoSt2A[p, Eval, val]; -- 16 evals CBustoLeft[p, Eval, val]; -- 16 evals CBustoRight[p, Eval, val]; -- 16 evals }; TerminalIO.PutRope["Starting WiresTest"]; TryAllPaths[p, Eval, c1]; TryAllPaths[p, Eval, c2]; TerminalIO.PutRope["Finished with WiresTest"]; }; DBusTest: RosemaryUser.TestProc = { TerminalIO.PutRope["Starting DBusTest"]; Initialize[p, cellType.public]; ReadR2BWithDBus[p, Eval, 0A123456FH]; TerminalIO.PutRope["Finished with DBusTest"]; }; ReadR2BWithDBus: PROC [p: Ports.Port, Eval: REProc, val: CARD] ~ { PutValInR2B[p, Eval, val, PackK[a: constAdr, aluR: 2]]; -- 1B: r2B _ val Ignore[p, KBus]; Ignore[p, DPData]; p[DStAd].c _ 7; -- EUUtils.r2BRow p[DShRd].b _ TRUE; p[DShWt].b _ FALSE; Eval[]; -- read the register: shiftReg _ reg[regAd] p[DShRd].b _ FALSE; p[DShWt].b _ FALSE; FOR i: NAT IN [0..32) DO bitOut: BOOL _ BitOps.EBFD[val, i]; p[DShOut].d _ expect; p[DShOut].b _ bitOut; p[DShB].b _ TRUE; Eval[]; -- _ ; shOut _ new value p[DShOut].d _ none; p[DShB].b _ FALSE; Eval[]; -- latched; shOut tristate p[DShIn].b _ FALSE; p[DShA].b _ TRUE; Eval[]; -- _ ; shIn is sampled p[DShA].b _ FALSE; p[DShB].b _ FALSE; Eval[]; -- latched ENDLOOP; p[DShRd].b _ FALSE; p[DShWt].b _ FALSE; p[DHold].b _ FALSE; p[DStAd].c _ 0; Eval[]; DoPh[p, Eval, A]; -- A: for synch }; Register: PROC [usingTester: BOOL] ~ { IF usingTester THEN { -- for IMS tester ICTest.RegisterTestProc[euTest, "ZeroAndOne", ZeroAndOne]; ICTest.RegisterTestProc[euTest, "Sanity Check", SanityCheck]; ICTest.RegisterTestProc[euTest, "RamTest", RamTest]; ICTest.RegisterTestProc[euTest, "ALUTest", ALUTest]; ICTest.RegisterTestProc[euTest, "FUTest", FUTest]; } ELSE { -- for Rosemary simulation RosemaryUser.RegisterTestProc["AllTests", AllTests]; RosemaryUser.RegisterTestProc["ZeroAndOne", ZeroAndOne]; RosemaryUser.RegisterTestProc["Sanity Check", SanityCheck]; RosemaryUser.RegisterTestProc["RamTest", RamTest]; RosemaryUser.RegisterTestProc["ALUTest", ALUTest]; RosemaryUser.RegisterTestProc["FUTest", FUTest]; RosemaryUser.RegisterTestProc["WiresTest", WiresTest]; RosemaryUser.RegisterTestProc["DBusTest", DBusTest]; }; }; euTest: ROPE = "EU4 Test"; opName: ARRAY Dragon.ALUOps OF Rope.ROPE; 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"; END. LEUSim.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet July 31, 1985 3:03:17 pm PDT Last edited by Bertrand Serlet June 8, 1986 5:21:11 pm PDT Barth, April 16, 1986 3:05:40 pm PST Louis Monier June 19, 1986 11:54:42 pm PDT Last Edited by: Louis Monier April 24, 1987 1:49:58 pm PDT Test of EU -- Invariants -- On PhA the chip always drives the PBus, so we check that the tester is not driving -- appropriate clock up -- both clocks down -- Utility, not a test in itself -- Gets value through the KBus and computes OR[ct0, val] -- Gets value through the KBus and computes OR[ct0, val], then moves it down by two latches -- k is the value on the kBus in the last PhB -- Checks whether st2A=val -- Computes OP(left, right) and checks that the result is equal to val -- From PBus to dataIn to cBus to KBus -- This test uses the field register to hold the field descriptor -- Test procs -- The combination of all the test procs [cellType: Core.CellType, p: Ports.Port, Eval: PROC [...]] -- The absolute minimum expected from a chip -- The minimum expected from a chip -- Test the entire RAM -- Read constants in ROM -- may generates a carry -- may generates a carry -- OvFl _ (Cout XOR opL[0] XOR opR[0]) XOR res[0], so we need a carry out; BC _ ~Cout -- LZ _ Cout XOR opL[0] XOR opR[0], so we need a carry out; GE _ ~ LZ -- LE _ EZ OR LZ IL _ all 3 high-order bits equal EZ _ zero, found after a sub at the top of the CLA tree Check integrity of aluLeft-> r2B-> pDriver path Logic operations All additions All subtractions Constant Conditions -- Testing the shifter (no masking) -- Testing the mask generator (no shifting) -- General Shift and Mask test -- With insert -- Try to put a zero and a 1 through every path in the EU -- I use an asymetric pattern to detect flips in buses -- I use the bus names defined in the schematics of the datapath -- Test the tristate driver r3B on the cBus; normal case -- Test the tristate driver r3B on the cBus; reject case -- Bypass from r2B to left -- Bypass from r2B to right -- Bypass from r2B to st2A -- Bypass from r3B to left Κ– "cedar" style˜codešœ ™ Jšœ Οmœ1™ -- [cellType: Core.CellType, p: Ports.Port, Eval: PROC [...]]š‘œ˜#KšΠck:™:Kšœ(˜(Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ-˜-Kšœ˜—K™Kš ,™,š‘ œ˜%Kšœ*˜*Kšœ˜KšΟf˜Kš₯˜Kš₯˜Kšœ/˜/Kšœ˜—K™Kš #™#š‘ œ˜&š‘ œžœžœ˜Kšœžœ ˜@Kšœ ˜ šœ˜Jšœ ’ ˜-—Kšœ˜Kšœ˜šœ˜Jšœ ’ ˜;—Kšœ˜Kšœ ˜ šœ˜Jšœ ’ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ’ ˜/—K˜—š‘ œžœžœ˜Kšœ  ˜:Kšœ ˜ šœ˜Jšœ ’ ˜-—Kšœ˜Kšœ˜šœ˜Jšœ ’ ˜2—Kšœ˜Kšœ˜šœ (˜EJšœ ’  ˜,—Kšœ˜Kšœ˜šœ˜Jšœ ’  ˜,—Kšœ˜Kšœ ˜ šœ˜Jšœ ’ ˜6—Kšœ˜Kšœ˜šœ˜Jšœ ’ ˜/—K˜Kšœ+˜+Kšœ˜Kšœ ₯ œ ₯ œ ₯ ˜DKšœ ₯ œ ₯ ˜-Kšœ ₯ œ ₯ œ ₯ ˜DKšœ ₯ œ ₯ ˜-Kš₯<˜Kšœ ₯œ˜ Kš₯œ₯&œ₯¦₯˜?—šžœ™ Kšœ ₯œ˜ Kš₯œ₯&ž₯¦₯˜?Kšœ ₯œ˜ Kš₯œ₯&ž₯¦₯˜>Kšœ ₯œ˜ Kš₯œ₯&œ₯¦₯˜AKšœ ₯œ˜ Kš₯œ₯&œ₯¦₯˜B—š E™EKšœ ₯œ˜ Kš₯œ₯&ž₯¦₯˜Kšœ8 ’  ˜HKšœ˜šœ˜Jšœ ’ ˜<—Kšœ˜K˜—K˜K˜š‘ œ˜$š‘ œžœ‘œžœ˜>Kšœ  ˜#Kšœ  ˜%Kšœ  ˜%Kšœ  ˜%Kšœ  ˜%Kšœ  ˜%Kšœ  ˜&Kšœ  ˜&K˜—Kšœ)˜)Kšœ˜Kšœ˜Kšœ.˜.Kšœ˜K˜—š‘œ˜#Kšœ(˜(Kšœ˜Kšœ₯˜%Kšœ-˜-Kšœ˜—K˜š‘œžœ‘œžœ˜BKšœ8 ’  ˜HKšœ˜Kšœ˜Kšœ ˜#Kšœ žœ˜Kšœ žœ˜Jšœ  +˜8Kšœ žœ˜Kšœ žœ˜šžœžœžœ ž˜Kšœžœ žœ ˜#K˜Kšœ˜Kšœ˜Kšœ žœ˜Jšœ   ˜-K˜Kšœ˜Kšœ žœ˜Jšœ  ˜+K˜Kšœ žœ˜Kšœ žœ˜Jšœ  ˜+K˜Kšœ žœ˜Kšœ žœ˜Jšœ  ˜K˜Kšžœ˜—K˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ˜šœ˜Jšœ ’  ˜)—K˜—K˜š‘œžœžœ˜&šžœ žœ ˜'Kšœ:˜:Kšœ=˜=Kšœ4˜4Kšœ4˜4Kšœ2˜2Kšœ˜—šžœ ˜!Kšœ5˜5Kšœ9˜9Kšœ<˜