<> <> <> <> DIRECTORY AMTypes, Arbiter, BitOps, CedarProcess, Core, CoreOps, FS, IO, Ports, PrintTV, Rope, Rosemary, RosemaryUser; ArbQuickTests: CEDAR MONITOR IMPORTS AMTypes, BitOps, CedarProcess, CoreOps, FS, IO, Ports, PrintTV, Rope, Rosemary, RosemaryUser = BEGIN OPEN Arbiter; <<>> ArbWires: TYPE = { OtherArbIn, nBusyIn, nStopAct, nRequestOut, nOwnerOut, nBOwnerIn, nSharedOut, nBSharedIn, nSStopOut, nBSStopIn, DBus, SlotNo, BdVersion, Clock, nLongGrant, nHiPGrant, nGrant, ArbReqOut, nBusyOut, nStartGrant, nBOwnerOut, nOwnerIn, nBSharedOut, nSharedIn, nBSStopOut, nSStopIn, nBdSel, nDHybridSel, CKOut, TInv, TRec2V, TIOBus }; ArbWireNames: ARRAY ArbWires OF IO.ROPE _ ALL[NIL]; GetNames: PROC [ ] = { IF ArbWireNames[LAST[ArbWires]] = NIL THEN { st: IO.STREAM _ IO.ROS[]; PrintTV.PrintType[type: AMTypes.UnderType[CODE[ArbWires]], put: st, depth: 4, width: 40000]; st _ IO.RIS[IO.RopeFromROS[st]]; WHILE st.GetChar[] # '{ DO ENDLOOP; FOR w: ArbWires IN ArbWires DO ArbWireNames[w] _ st.GetTokenRope[].token; ENDLOOP; }; }; State: TYPE = REF StateRec _ NIL; StateRec: TYPE = RECORD [ cellType: Core.CellType _ NIL, p: Ports.Port _ NIL, eval: PROC [memory: BOOL _ TRUE, clockEval: BOOL _ FALSE, checkPorts: BOOL _ TRUE] _ NIL, pi: ARRAY ArbWires OF NAT _ ALL[0], -- indexes in cellType.public s: IO.STREAM _ NIL, cycle: INT _ 0 ]; st: State _ NIL; GetAllState: PROC [cellType: Core.CellType, p: Ports.Port, eval: PROC [memory: BOOL _ TRUE, clockEval: BOOL _ FALSE, checkPorts: BOOL _ TRUE]] RETURNS [ st: State ] = { st _ NEW[StateRec _ []]; st.cellType _ cellType; st.p _ p; TRUSTED { st.eval _ eval }; GetNames[]; FOR aw: ArbWires IN ArbWires DO [st.pi[aw]] _ Ports.PortIndexes[st.cellType.public, ArbWireNames[aw]]; ENDLOOP; }; PortToStream: PROC [ p: Ports.Port ] = { PutBool: PROC [ b: BOOL, d: Ports.Drive ] = { st.s.PutRope[(SELECT d FROM < none => (IF b THEN "H" ELSE "L"), none => "X", <= force => (IF b THEN "T" ELSE "F"), ENDCASE => (IF b THEN "1" ELSE "0") )]; }; PutLevel: PROC [ l: Ports.Level, d: Ports.Drive ] = { st.s.PutRope[(SELECT d FROM < none => (SELECT l FROM H => "H", L => "L", ENDCASE => "X"), none => "X", <= force => (SELECT l FROM H => "T", L => "F", ENDCASE => "X"), ENDCASE => (SELECT l FROM H => "1", L => "0", ENDCASE => "X") )]; }; IF p.levelType=composite THEN FOR i: NAT IN [0..p.size) DO PortToStream[p[i]]; ENDLOOP ELSE { SELECT p.levelType FROM l => PutLevel[p.l, p.d]; ls => FOR i: NAT IN [0..p.ls.size) DO PutLevel[p.ls[i], (IF p.driveType=aggregate THEN p.d ELSE p.ds[i])]; ENDLOOP; b => PutBool[p.b, p.d]; bs => FOR i: NAT IN [0..p.bs.size) DO PutBool[p.bs[i], (IF p.driveType=aggregate THEN p.d ELSE p.ds[i])]; ENDLOOP; c => FOR i: NAT IN [p.fieldStart..16) DO PutBool[BitOps.EBFW[p.c, i], p.d]; ENDLOOP; lc => FOR i: NAT IN [p.fieldStart..32) DO PutBool[BitOps.EBFW[p.lc, i], p.d]; ENDLOOP; q => FOR i: NAT IN [p.fieldStart..64) DO PutBool[BitOps.EBFW[p.q[i/16], (i MOD 16)], p.d]; ENDLOOP; ENDCASE => ERROR; }; }; makeOtherVectors: BOOL _ FALSE; Openem: PROC [ name: IO.ROPE _ NIL ] = { IF makeOtherVectors THEN { st.s _ FS.StreamOpen[fileName: IO.PutFR["%s.av", IO.rope[IF name.Length = 0 THEN "ArbQuikT" ELSE name]], accessOptions: $create]; st.s.PutF[" %g\n", IO.time[]]; FOR aw: ArbWires IN ArbWires DO st.s.PutF[" %g [%g]\n", IO.rope[ArbWireNames[aw]], IO.int[CoreOps.WireBits[st.cellType.public[st.pi[aw]]]]]; ENDLOOP; st.s.PutRope["\n\n"]; }; }; Closem: PROC = { IF st.s # NIL THEN { st.s.Close[]; st.s _ NIL; }; }; Eval: PROC [ ignoreX: BOOL _ FALSE ] = { ENABLE Rosemary.Stop => IF ignoreX AND (reason = $BoolWireHasX) THEN RESUME ELSE REJECT; st.p[st.pi[CKOut]].d _ expect; st.p[st.pi[CKOut]].b _ st.p[st.pi[Clock]].b; st.p[st.pi[nBusyIn]].b _ st.p[st.pi[nBusyOut]].b; st.eval[clockEval: TRUE]; st.eval[clockEval: FALSE]; IF makeOtherVectors AND (st.s # NIL) THEN { FOR aw: ArbWires IN ArbWires DO PortToStream[st.p[st.pi[aw]]]; ENDLOOP; st.s.PutF["\n"]; }; }; EvalIgnoreX: PROC = { Eval[ignoreX: TRUE]; }; DoClk: PROC [ cycles: INT _ 1, ignoreX: BOOL _ FALSE ] = { FOR i: INT IN [0..cycles) DO st.p[st.pi[Clock]].b _ FALSE; Eval[ignoreX]; st.p[st.pi[Clock]].b _ TRUE; Eval[ignoreX]; st.cycle _ st.cycle+1; ENDLOOP; }; DoClkIgnoreX: PROC [ cycles: INT _ 1 ] = { DoClk[cycles, TRUE]; }; DAShift: PROC [ val: BitOps.BitWord ] = { st.p[st.pi[DBus]].bs[DAddress] _ TRUE; EvalIgnoreX[]; DDShift[16, val]; st.p[st.pi[DBus]].bs[DAddress] _ FALSE; EvalIgnoreX[]; }; DDShift: PROC [ size: [1..16], val: BitOps.BitWord ] = { FOR i: NAT IN [0..size) DO st.p[st.pi[DBus]].bs[DSerialIn] _ BitOps.EBFW[val, i, size]; st.p[st.pi[DBus]].bs[DShiftCK] _ FALSE; EvalIgnoreX[]; st.p[st.pi[DBus]].bs[DShiftCK] _ TRUE; EvalIgnoreX[]; ENDLOOP; }; DDShiftCheck: PROC [ size: [1..16], valIn: BitOps.BitWord, valOut: BitOps.BitWord ] = { FOR i: NAT IN [0..size) DO st.p[st.pi[DBus]].bs[DSerialIn] _ BitOps.EBFW[valIn, i, size]; st.p[st.pi[DBus]].bs[DShiftCK] _ FALSE; st.p[st.pi[DBus]].bs[DSerialOut] _ BitOps.EBFW[valOut, i, size]; st.p[st.pi[DBus]].ds[DSerialOut] _ expect; EvalIgnoreX[]; st.p[st.pi[DBus]].ds[DSerialOut] _ none; st.p[st.pi[DBus]].bs[DShiftCK] _ TRUE; EvalIgnoreX[]; ENDLOOP; }; nCheckBits: NAT = 8; checkBits: BitOps.BitWord = 05AH; DRCheck: PROC [ width: NAT ] = { FOR i: NAT IN [0..width+nCheckBits) DO in: BitOps.BitWord = IF i> DAShift[1000H*sn+1]; -- check DevPriority DRCheck[72]; DAShift[1000H*sn+2]; -- load arbiter number DRCheck[4]; DDShift[4, 2*a+1]; -- decoded hybrid select DAShift[1000H*sn+300H]; -- address hybrid 3 st.p[st.pi[nDHybridSel]].d _ expect; st.p[st.pi[nDHybridSel]].c _ 01FH-4; -- decoded EvalIgnoreX[]; st.p[st.pi[nDHybridSel]].d _ none; DAShift[1000H*sn+2]; -- load arbiter number DDShift[4, 2*a]; -- now encoded DAShift[08000H+1000H*a+300H]; -- address hybrid 3 st.p[st.pi[nDHybridSel]].d _ expect; st.p[st.pi[nDHybridSel]].c _ 01FH-6; -- encoded, 5 bits EvalIgnoreX[]; st.p[st.pi[nDHybridSel]].d _ none; st.p[st.pi[BdVersion]].c _ 2; DAShift[1000H*sn+400H]; -- address hybrid 4 DDShift[1, 0]; -- load BdVersion shadow DAShift[1000H*sn+3H]; -- read the board version DDShiftCheck[2, 0, 2]; st.p[st.pi[BdVersion]].c _ 1; DAShift[1000H*sn+400H]; -- address hybrid 4 DDShift[1, 0]; -- load BdVersion shadow DAShift[1000H*sn+3H]; -- read the board version DDShiftCheck[2, 0, 1]; ENDLOOP; }; RunLocalGrantTest: PROC = { sn: NAT _ 1; a: Arbiters _ (sn+3) MOD 8; stopCycle: INT; Setup[]; st.p[st.pi[SlotNo]].c _ sn; DAShift[1000H*sn+1]; -- load DevPriority FOR d: Devices IN Devices DO DDShift[9, 031H]; -- all the same priority ENDLOOP; DAShift[1000H*sn+2]; -- load arbiter number DDShift[4, 2*a+1]; -- decoded hybrid select DoClkIgnoreX[5]; st.p[st.pi[DBus]].bs[nDReset] _ TRUE; -- end of main reset DoClk[5]; st.p[st.pi[nStopAct]].b _ TRUE; -- end of arbiter reset DoClk[10]; FOR d: Devices IN Devices DO st.p[st.pi[nRequestOut]][d].c _ 0; -- high request ENDLOOP; DoClk[6]; FOR d: Devices IN Devices DO st.p[st.pi[nRequestOut]][d].c _ 1; -- low request ENDLOOP; DoClk[6]; FOR d: Devices IN Devices DO st.p[st.pi[nRequestOut]][d].c _ 3; -- no request ENDLOOP; stopCycle _ st.cycle+30; WHILE stopCycle > st.cycle DO DoClk[1]; IF NOT st.p[st.pi[nStartGrant]].b THEN stopCycle _ st.cycle+30; ENDLOOP; }; RunGlobalGrantTest: PROC = { sn: NAT _ 1; a: Arbiters _ (sn+3) MOD 8; stopCycle: INT; Setup[]; st.p[st.pi[SlotNo]].c _ sn; DAShift[1000H*sn+1]; -- load DevPriority FOR d: Devices IN Devices DO DDShift[9, 031H]; -- all the same priority ENDLOOP; DAShift[1000H*sn+2]; -- load arbiter number DDShift[4, 2*a+1]; -- decoded hybrid select DoClkIgnoreX[5]; st.p[st.pi[DBus]].bs[nDReset] _ TRUE; -- end of main reset DoClk[5]; st.p[st.pi[nStopAct]].b _ TRUE; -- end of arbiter reset DoClk[10]; FOR oa: OtherArbiters IN OtherArbiters DO st.p[st.pi[OtherArbIn]][oa].c _ 0; -- high priority request ENDLOOP; st.p[st.pi[nRequestOut]][0].c _ 0; -- high request DoClk[6]; st.p[st.pi[nRequestOut]][0].c _ 1; -- low request DoClk[6]; st.p[st.pi[nRequestOut]][0].c _ 3; -- no request DoClk[80]; FOR oa: OtherArbiters IN OtherArbiters DO st.p[st.pi[OtherArbIn]][oa].c _ 1; -- in-between priority request ENDLOOP; stopCycle _ st.cycle+10; WHILE stopCycle > st.cycle DO DoClk[1]; IF NOT st.p[st.pi[nStartGrant]].b THEN stopCycle _ st.cycle+10; ENDLOOP; FOR oa: OtherArbiters IN OtherArbiters DO st.p[st.pi[OtherArbIn]][oa].c _ 4; -- low priority request ENDLOOP; DoClk[50]; FOR oa: OtherArbiters IN OtherArbiters DO st.p[st.pi[OtherArbIn]][oa].c _ 5; -- very low priority request ENDLOOP; stopCycle _ st.cycle+10; WHILE stopCycle > st.cycle DO DoClk[1]; IF NOT st.p[st.pi[nStartGrant]].b THEN stopCycle _ st.cycle+10; ENDLOOP; }; ArbDBus: ENTRY RosemaryUser.TestProc = { ENABLE UNWIND => Closem[]; st _ GetAllState[cellType, p, Eval]; Openem[]; CedarProcess.DoWithPriority[priority: background, action: RunDBusTest]; Closem[]}; LocalGrants: ENTRY RosemaryUser.TestProc = { ENABLE UNWIND => Closem[]; st _ GetAllState[cellType, p, Eval]; CedarProcess.DoWithPriority[priority: background, action: RunLocalGrantTest]; Openem[]; Closem[]}; GlobalGrants: ENTRY RosemaryUser.TestProc = { ENABLE UNWIND => Closem[]; st _ GetAllState[cellType, p, Eval]; CedarProcess.DoWithPriority[priority: background, action: RunGlobalGrantTest]; Openem[]; Closem[]}; RosemaryUser.RegisterTestProc["ArbDBus", ArbDBus]; RosemaryUser.RegisterTestProc["LocalGrants", LocalGrants]; RosemaryUser.RegisterTestProc["GlobalGrants", GlobalGrants]; END.