<> <> <> <> <> <> <> <<>> DIRECTORY Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, Dragon, EU2Utils, Rope, Rosemary, RosemaryUser, Ports, TerminalIO; OldEU2Sim: CEDAR PROGRAM IMPORTS EU2Utils, Rosemary, RosemaryUser, Ports, TerminalIO = BEGIN OPEN Core, EU2Utils; <> Vdd, Gnd, PadVdd, PadGnd, PhA, PhB, VRef, DPRejectB, DPData, -- 32 bits KBus, -- 32 bits <<-- Phase-multiplexed on KBus>> <> <> <> <> <> <> <> EURdFromPBus3AB, EUWriteToPBus3AB, EUAluOp2AB, -- 4 bits Dragon.ALUOps EUCondSel2AB, -- 4 bits Dragon.CondSelects EUCondition2B, DShA, DShB, DShRd, DShWt, DShIn, DShOut, DHold, DStAd: NAT; testName: ROPE = "EU2Test"; allOnes: LONG CARDINAL _ LOOPHOLE[LONG[-1]]; Initialize: PROC [public: Wire] = { Vdd _ PortIndex[public, "Vdd"]; Gnd _ PortIndex[public, "Gnd"]; PadVdd _ PortIndex[public, "PadVdd"]; PadGnd _ PortIndex[public, "PadGnd"]; PhA _ PortIndex[public, "PhA"]; PhB _ PortIndex[public, "PhB"]; VRef _ PortIndex[public, "VRef"]; DPRejectB _ PortIndex[public, "DPRejectB"]; DPData _ PortIndex[public, "DPData"]; KBus _ PortIndex[public, "KBus"]; EURdFromPBus3AB _ PortIndex[public, "EURdFromPBus3AB"]; EUWriteToPBus3AB _ PortIndex[public, "EUWriteToPBus3AB"]; EUAluOp2AB _ PortIndex[public, "EUAluOp2AB"]; EUCondSel2AB _ PortIndex[public, "EUCondSel2AB"]; EUCondition2B _ PortIndex[public, "EUCondition2B"]; DShA _ PortIndex[public, "DShA"]; DShB _ PortIndex[public, "DShB"]; DShRd _ PortIndex[public, "DShRd"]; DShWt _ PortIndex[public, "DShWt"]; DShIn _ PortIndex[public, "DShIn"]; DShOut _ PortIndex[public, "DShOut"]; DHold _ PortIndex[public, "DHold"]; DStAd _ PortIndex[public, "DStAd"]; }; ExerciseRose: PUBLIC PROC [eu2: CellType] RETURNS [sim: Rosemary.Simulation] = { public: Wire _ eu2.public; Initialize[public]; [] _ Rosemary.SetFixedWire[public[Vdd], H]; [] _ Rosemary.SetFixedWire[public[Gnd], L]; [] _ Rosemary.SetFixedWire[public[PadVdd], H]; [] _ Rosemary.SetFixedWire[public[PadGnd], L]; [] _ Rosemary.SetFixedWire[public[VRef], H]; [] _ 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[DShOut], none]; [] _ Ports.InitTesterDrive[public[DHold], force]; [] _ Ports.InitPort[public[DStAd], c]; [] _ Ports.InitTesterDrive[public[DStAd], force]; sim _ RosemaryUser.TestProcedureViewer[ cellType: eu2, testButtons: LIST[testName], name: testName, displayWires: RosemaryUser.DisplayCellTypePortLeafWires[eu2], flatten: TRUE, cutSets: LIST["AlpsCell", "EU2Ram"]]; }; EU2Test: RosemaryUser.TestProc = { constAdr: NAT _ EU2Utils.constAdr; junkAdr: NAT _ EU2Utils.junkAdr; 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; }; Phase: TYPE = {A, B}; DoPh: PROC [ph: Phase] = { p[PhA].b _ ph=A; p[PhB].b _ ph=B; Eval[]; p[DPData].d _ none; p[PhA].b _ FALSE; p[PhB].b _ FALSE; Eval[ ! Ports.CheckError => RESUME]; }; LoadRam: PROC [ad: NAT, val: LONG CARDINAL] ~ { p[KBus].lc _ PackK[aluR: 3]; DoPh[B]; -- load address p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[Or]]; p[KBus].lc _ val; DoPh[A]; -- right _ val p[KBus].lc _ PackK[]; DoPh[B]; -- OR p[KBus].lc _ 0; DoPh[A]; -- PBus _ val; r3A _ val; p[KBus].lc _ PackK[c: ad]; DoPh[B]; -- r3B _r3A p[KBus].lc _ 0; DoPh[A]; -- ram[c] _ val; }; DoubleLoadRam: PROC [ad1, ad2: NAT, val1, val2: LONG CARDINAL] ~ { p[KBus].lc _ PackK[aluR: 3]; DoPh[B]; -- load junk addresses p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[Or]]; p[KBus].lc _ val1; DoPh[A]; -- right _ val1 p[KBus].lc _ PackK[aluR: 3]; DoPh[B]; -- OR p[KBus].lc _ val2; DoPh[A]; -- PBus _ val1; r3A _ val1; p[KBus].lc _ PackK[c: ad1]; DoPh[B]; -- r3B _r3A p[KBus].lc _ 0; DoPh[A]; -- ram[ad1] _ val2; p[KBus].lc _ PackK[c: ad2]; DoPh[B]; -- r3B _r3A p[KBus].lc _ 0; DoPh[A]; -- ram[ad2] _ val2; }; DoALUOp: PROC [a, b, res: LONG CARDINAL, op: Dragon.ALUOps, condSel: Dragon.CondSelects _ False, cond: BOOL _ FALSE] ~ { DoubleLoadRam[0, 1, a, b]; p[KBus].lc _ PackK[a: 0, b: 1]; DoPh[B]; -- load operands addresses p[EUAluOp2AB].c _ ORD[op]; p[KBus].lc _ 0; DoPh[A]; -- left _ a; right _ b p[EUCondition2B].b _ FALSE; p[EUCondSel2AB].c _ ORD[condSel]; p[EUCondition2B].b _ cond; p[KBus].lc _ PackK[]; DoPh[B]; -- op p[KBus].lc _ 0; p[DPData].lc _ res; p[EUCondSel2AB].c _ 0; p[EUCondition2B].b _ FALSE; p[DPData].d _ expect; DoPh[A]; -- PBus _ res; check PBus }; DoFUOp: PROC [leftW, rightW, res, mask, shift: LONG CARDINAL, insert: BOOL] ~ { fd: NAT _ ((IF insert THEN 1 ELSE 0)*64+mask)*64+shift; LoadRam[fieldAdr, LONG[fd]]; -- field_fd DoubleLoadRam[0, 1, leftW, rightW]; -- ram[0]_leftW; ram[1]_rightW p[KBus].lc _ PackK[a: 0, b: 1, aluR: 4]; -- right_field; left_leftW; st2A_rightW DoPh[B]; -- load operand addresses p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[FOP]]; p[KBus].lc _ 0; DoPh[A]; p[KBus].lc _ PackK[]; DoPh[B]; -- field unit is active p[KBus].lc _ 0; p[DPData].lc _ res; p[DPData].d _ expect; DoPh[A]; -- PBus _ res; check PBus }; <<-- Initial values>> Initialize[cellType.public]; p[DPRejectB].b _ FALSE; p[DShA].b _ TRUE; -- hack to clean up the ShReg. p[DShB].b _ TRUE; p[DShRd].b _ FALSE; p[DShWt].b _ FALSE; p[DShIn].b _ FALSE; p[DHold].b _ FALSE; p[DStAd].c _ 0; p[EUCondSel2AB].c _ 0; -- false p[EUAluOp2AB].c _ ORD[Dragon.ALUOps[Or]]; p[EURdFromPBus3AB].b _ FALSE; -- don't (fetch) read data from PBus p[EUWriteToPBus3AB].b _ TRUE; -- (store) and don't write onto PBus during PhB p[EUAluOp2AB].c _ 0; -- OR <<-- Purge the pipeline>> TerminalIO.WriteRope["Purging the pipe\n"]; p[DPData].d _ none; FOR c: NAT IN [0..3) DO p[KBus].lc _ PackK[]; DoPh[B ! Ports.CheckError => RESUME; Rosemary.Stop => RESUME]; p[KBus].lc _ 0; DoPh[A ! Ports.CheckError => RESUME; Rosemary.Stop => RESUME]; ENDLOOP; <<>> <<-- Test starts here (commented out code already works)>> <<>> -- Carry Test TerminalIO.WriteRope["Testing LAdd\n"]; -- the only op which sets but doesn't use carry DoALUOp[12, 73, 85, LAdd]; -- sets the carry to 0 TerminalIO.WriteRope["Testing SAdd\n"]; DoALUOp[12, 73, 85, SAdd]; -- uses the carry (now 0) -- Condition Test TerminalIO.WriteRope["Testing VSub, negative result\n"]; DoALUOp[2, 3, allOnes, VSub, LZ, TRUE]; DoALUOp[2, 2, 0, VSub, EZ, TRUE]; <<-- Field Unit Test>> TerminalIO.WriteRope["Insert\n"]; DoFUOp[leftW: 1, rightW: 632B, res: 602B, mask: 2, shift: 6, insert: TRUE]; TerminalIO.WriteRope["Testing simple Shift\n"]; DoFUOp[leftW: 2, rightW: 1, res: 16, mask: 20, shift: 3, insert: FALSE]; TerminalIO.WriteRope["Testing simple Masking\n"]; DoFUOp[leftW: 15, rightW: 1, res: 7, mask: 3, shift: 0, insert: FALSE]; TerminalIO.WriteRope["Shift and Mask\n"]; DoFUOp[leftW: 6, rightW: allOnes, res: 23, mask: 5, shift: 3, insert: FALSE]; -- ALU Test TerminalIO.WriteRope["Testing VAdd\n"]; DoALUOp[12, 73, 85, VAdd]; TerminalIO.WriteRope["Testing VSub\n"]; DoALUOp[47, 31, 16, VSub]; TerminalIO.WriteRope["Testing VSub, negative result\n"]; DoALUOp[2, 3, allOnes, VSub]; TerminalIO.WriteRope["Testing Or\n"]; DoALUOp[10, 3, 11, Or]; TerminalIO.WriteRope["Testing And\n"]; DoALUOp[10, 3, 2, And]; TerminalIO.WriteRope["Testing Xor\n"]; DoALUOp[10, 3, 9, Xor]; <<>> }; RosemaryUser.RegisterTestProc[testName, EU2Test]; END.