ArbSysTests.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
E. McCreight, May 15, 1987 4:28:01 pm PDT
DIRECTORY
Arbiter, BitOps, CedarProcess, Core, CoreFlat, CoreProperties, IO, Ports, Rosemary, RosemaryUser;
ArbSysTests: CEDAR PROGRAM
IMPORTS BitOps, CedarProcess, CoreFlat, CoreProperties, IO, Ports, Rosemary, RosemaryUser
=
BEGIN OPEN Arbiter;
State: TYPE = REF StateRec ← NIL;
StateRec: TYPE = RECORD [
tester: RosemaryUser.Tester ← NIL,
simulation: Rosemary.Simulation ← NIL,
cellType: Core.CellType ← NIL,
p: Ports.Port ← NIL,
eval: PROC [memory: BOOLTRUE] ← NIL,
nDReqs, nDGrants, nBDHis, nBDLongs, nArbReqs,
DBus, DPriorities, ArbNos, Rsts, nDStops, SlotNos, DHybridSels, DBdSels,
nDynaBusBusy, nHolding, Ck: NAT ← 0,
..indexes in cellType.public
arbs: ARRAY Arbiters OF REFALL[NIL],
devs: ARRAY Arbiters OF ARRAY Devices OF REFALL[ALL[NIL]]
];
lastState: State ← NIL;
GetAllState: PROC [cellType: Core.CellType, p: Ports.Port, eval: PROC [memory: BOOLTRUE]] RETURNS [ st: State ] = {
GetState: PROC [ instName: IO.ROPE ] RETURNS [ ref: REF ] = {
ref ← Rosemary.GetState[
st.tester.display.simulation,
NEW[CoreFlat.FlatCellTypeRec ←
CoreFlat.ParseCellTypePath[st.cellType, instName]]
];
};
lastState ← st ← NEW[StateRec ← [
tester: NARROW[CoreProperties.GetProp[cellType.properties, $Tester]]
]];
st.simulation ← st.tester.display.simulation;
st.cellType ← st.tester.display.cellType;
st.p ← p;
TRUSTED { st.eval ← eval };
[st.nDReqs, st.nDGrants, st.nBDHis, st.nBDLongs, st.nArbReqs] ←
Ports.PortIndexes[st.cellType.public, "nDReqs", "nDGrants", "nBDHis", "nBDLongs", "nArbReqs"];
[st.DBus, st.DPriorities, st.ArbNos, st.Rsts] ← Ports.PortIndexes[st.cellType.public, "DBus", "DPriorities", "ArbNos", "Rsts"];
[st.nDStops, st.SlotNos, st.DHybridSels, st.DBdSels] ←
Ports.PortIndexes[st.cellType.public, "nDStops", "SlotNos", "DHybridSels", "DBdSels"];
[st.nDynaBusBusy, st.nHolding, st.Ck] ←
Ports.PortIndexes[st.cellType.public, "nDynaBusBusy", "nHolding", "Ck"];
FOR a: Arbiters IN Arbiters DO
st.arbs[a] ← GetState[IO.PutFR["/Arb%d/ArbiterTop", IO.int[a]]];
-- until I figure out how to do this ....
FOR d: Devices IN Devices DO
st.devs[a][d] ← GetState[IO.PutFR["/Arb%dReq%d", IO.int[a], IO.int[d]]];
ENDLOOP;
ENDLOOP;
};
WhoAmI: PROC [ ref: REF ] RETURNS [ name: IO.ROPE ] = {
FOR a: Arbiters IN Arbiters DO
IF ref = lastState.arbs[a] THEN RETURN[IO.PutFR["Arbiter %d", IO.int[a]]];
FOR d: Devices IN Devices DO
IF ref = lastState.devs[a][d] THEN RETURN[IO.PutFR["Device %d of arbiter %d", IO.int[d], IO.int[a]]];
ENDLOOP;
ENDLOOP;
name ← "Darned if I know!"
};
RunTest: PROC [ st: State, initializeAll: BOOLFALSE ] = {
Eval: PROC = {
st.eval[];
};
EvalIgnoreX: PROC = {
Eval[ ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT ];
};
ReallyRunTest: PROC = {
DoClk: PROC [ cycles: INT ← 1 ] = {
FOR i: INT IN [0..cycles) DO
st.p[st.Ck].b ← FALSE;
Eval[];
st.p[st.Ck].b ← TRUE;
Eval[];
ENDLOOP;
};
DoClkIgnoreX: PROC [ cycles: INT ← 1 ] = {
FOR i: INT IN [0..cycles) DO
st.p[st.Ck].b ← FALSE;
EvalIgnoreX[];
st.p[st.Ck].b ← TRUE;
EvalIgnoreX[];
ENDLOOP;
};
DAShift: PROC [ val: BitOps.BitWord ] = {
st.p[st.DBus][DAddress].b ← TRUE;
EvalIgnoreX[];
DDShift[16, val];
st.p[st.DBus][DAddress].b ← FALSE;
EvalIgnoreX[];
};
DDShift: PROC [ size: [1..16], val: BitOps.BitWord ] = {
FOR i: NAT IN [0..size) DO
st.p[st.DBus][DSerialIn].b ← BitOps.EBFW[val, i, size];
st.p[st.DBus][DShiftCK].b ← FALSE;
EvalIgnoreX[];
st.p[st.DBus][DShiftCK].b ← TRUE;
EvalIgnoreX[];
ENDLOOP;
};
DDShiftCheck: PROC [ size: [1..16], valIn: BitOps.BitWord, valOut: BitOps.BitWord ] = {
FOR i: NAT IN [0..size) DO
st.p[st.DBus][DSerialIn].b ← BitOps.EBFW[valIn, i, size];
st.p[st.DBus][DShiftCK].b ← FALSE;
st.p[st.DBus][DSerialOut].b ← BitOps.EBFW[valOut, i, size];
st.p[st.DBus][DSerialOut].d ← expect;
EvalIgnoreX[];
st.p[st.DBus][DSerialOut].d ← none;
st.p[st.DBus][DShiftCK].b ← TRUE;
EvalIgnoreX[];
ENDLOOP;
};
useDBus: BOOLNARROW[CoreProperties.GetProp[st.cellType.properties, $UseDBus], REF BOOL]^;
FOR i: NAT IN (DSerialOut..DShiftCK] DO
st.p[st.DBus][i].d ← drive;
ENDLOOP;
st.p[st.DBus][DSerialOut].d ← none;
FOR a: Arbiters IN Arbiters DO
st.p[st.SlotNos][a].c ← 8H+a;
ENDLOOP;
st.p[st.DBus][DExecute].b ← FALSE;
st.p[st.DBus][nDFreeze].b ← TRUE;
st.p[st.DBus][nDReset].b ← FALSE;
st.p[st.DBus][DSerialIn].b ← FALSE;
st.p[st.DBus][DShiftCK].b ← FALSE;
st.p[st.DBus][DAddress].b ← FALSE;
st.p[st.DBus][DSerialOut].b ← TRUE;
st.p[st.DBus][DSerialOut].d ← force; -- very weak
st.p[st.nDStops][0][0].b ← NOT TRUE; -- assert Stop
st.p[st.nDStops][0][0].d ← drive;
IF NOT useDBus THEN
FOR a: Arbiters IN Arbiters DO
st.p[st.Rsts][a].b ← TRUE;
st.p[st.Rsts][a].d ← drive;
ENDLOOP;
DoClkIgnoreX[6]; -- allow some X's to relax out
st.p[st.nDStops][0][0].d ← none; -- release Stop while holding Reset
st.p[st.DBus][DShiftCK].b ← TRUE;
DoClkIgnoreX[6]; -- allow more X's to relax out
IF useDBus THEN {
FOR a: Arbiters IN Arbiters DO
IF a=0 OR initializeAll THEN {
DAShift[08000H+1000H*a]; -- check arbiter signature
DDShiftCheck[16, 0, 5041H];
};
DAShift[08000H+1000H*a+2]; -- load arbiter number
DDShift[3, a];
IF a=0 OR initializeAll THEN {
DDShiftCheck[3, a, a];
DAShift[08000H+1000H*a+1];
FOR d: Devices IN Devices DO
DDShift[9, (IF d MOD 2 = 0 THEN 71H ELSE 22H)];
ENDLOOP;
DAShift[08000H+1000H*a+100H]; -- select a non-arbiter device
DDShift[1, 0]; -- load BdVersion shadow
DAShift[08000H+1000H*a+3H]; -- read the board version
DDShiftCheck[2, 0, 2];
};
ENDLOOP;
}
ELSE {
FOR a: Arbiters IN Arbiters DO
st.p[st.ArbNos][a].c ← a;
st.p[st.ArbNos][a].d ← drive;
FOR d: Devices IN Devices DO
st.p[st.DPriorities][a][d].c ← (IF d MOD 2 = 0 THEN 71H ELSE 22H);
st.p[st.DPriorities][a][d].d ← drive;
ENDLOOP;
FOR i: INT IN [0..15) DO
st.p[st.DHybridSels][a][i].b ← FALSE;
st.p[st.DHybridSels][a][i].d ← drive;
ENDLOOP;
st.p[st.DBdSels][a].b ← FALSE;
st.p[st.DBdSels][a].d ← drive;
ENDLOOP;
};
DoClkIgnoreX[6]; -- allow final X's to relax out
DoClk[1]; -- see if any X's left
st.p[st.nDStops][0][0].b ← NOT TRUE; -- assert Stop
st.p[st.nDStops][0][0].d ← drive;
st.p[st.nDynaBusBusy].b ← NOT TRUE; -- make sure no starvation errors are reported yet
st.p[st.nDynaBusBusy].d ← drive;
DoClk[5];
st.p[st.DBus][nDReset].b ← TRUE; -- release Reset
st.p[st.DBus][nDFreeze].b ← TRUE; -- release Freeze, whatever that means
DoClk[2];
IF NOT useDBus THEN
FOR a: Arbiters IN Arbiters DO
st.p[st.Rsts][a].b ← FALSE;
ENDLOOP;
DoClk[3];
st.p[st.nDStops][0][0].d ← none; -- release Stop
DoClk[15];
st.p[st.nDynaBusBusy].d ← none; -- allow starvation errors
DoClk[100000];
};
CedarProcess.DoWithPriority[priority: background, action: ReallyRunTest];
};
simHighProb: REF ProbabilitiesRec ← NEW[ProbabilitiesRec ← []];
simMediumProb: REF ProbabilitiesRec ← NEW[ProbabilitiesRec ← []];
simLowProb: REF ProbabilitiesRec ← NEW[ProbabilitiesRec ← []];
normalProb: ProbabilitiesRec ← [request: ALL[400], hold: 1000];
zeroProb: ProbabilitiesRec ← [request: ALL[10000000], hold: 10000000];
higherProb: ProbabilitiesRec ← [request: ALL[30], hold: 100];
evenHigherProb: ProbabilitiesRec ← [request: ALL[10], hold: 100];
userProb: ProbabilitiesRec ← normalProb;
GeneralArbSysTest: PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC [memory: BOOLTRUE], high, med, low: ProbabilitiesRec] = {
st: State = GetAllState[cellType, p, Eval];
FOR a: Arbiters IN Arbiters DO
FOR d: Devices IN Devices DO
rs: REF RequesterStateRec = NARROW[st.devs[a][d]];
rs.probs ← (SELECT TRUE FROM
(a = 0) AND (d = 0) => simHighProb,
(a = 0) => simMediumProb,
ENDCASE => simLowProb);
ENDLOOP;
ENDLOOP;
simHighProb^ ← high;
simMediumProb^ ← med;
simLowProb^ ← low;
RunTest[st, TRUE];
};
FullArbSysTest: PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC [memory: BOOLTRUE]] -- RosemaryUser.TestProc -- = {
GeneralArbSysTest[cellType, p, Eval, normalProb, normalProb, normalProb];
};
SingleArbiterTest: PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC [memory: BOOLTRUE]] -- RosemaryUser.TestProc -- = {
GeneralArbSysTest[cellType, p, Eval, higherProb, higherProb, zeroProb];
};
SingleRequesterTest: PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC [memory: BOOLTRUE]] -- RosemaryUser.TestProc -- = {
GeneralArbSysTest[cellType, p, Eval, evenHigherProb, zeroProb, zeroProb];
};
RosemaryUser.RegisterTestProc["FullArbSysTest", FullArbSysTest];
RosemaryUser.RegisterTestProc["SingleArbiterTest", SingleArbiterTest];
RosemaryUser.RegisterTestProc["SingleRequesterTest", SingleRequesterTest];
END.