ArbGroupsImpl.mesa
Copyright c 1987 by Xerox Corporation. All rights reserved.
E. McCreight, May 26, 1987 5:02:18 pm PDT
Last Edited by: McCreight September 28, 1987 10:42:39 am PDT
DIRECTORY
Arbiter, BitOps, Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, Rosemary, RosemaryUser;
ArbGroupsImpl: CEDAR PROGRAM
IMPORTS Arbiter, BitOps, CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, Rosemary
EXPORTS Arbiter
=
BEGIN OPEN CoreCreate, Arbiter;
SimplestArbCT: PUBLIC PROC RETURNS [ct: CoreCreate.CellType] = {
inst: CellInstance;
instances: CellInstances ← LIST[];
publics: Wire = WireList[LIST[
Seq["DReq00", 2],
"DGrant00",
"BDHi0",
"BDLong0",
"DOwner00",
"SysOwner",
"DShared00",
"SysShared",
"DStop00",
"SysStop",
Seq["DBus", 7],
Seq["DPriority", 9],
"Ck", "Vdd", "Gnd"
]];
internals: Wire = WireList[LIST[
Seq["DReq01", 2],
"DGrant01",
Seq["DReq02", 2],
"DGrant02",
"StartGrant",
"Busy",
"DOwner01",
"DOwner02",
"BOwner",
"DShared01",
"DShared02",
"BShared0",
"DStop01",
"DStop02",
"BStop0",
"nDynaBusBusy", "nHolding",
Seq["ArbNo", 3],
]];
arbCT: Core.CellType = CoreFlat.CellTypeCutLabels[on: Arbiter.ArbExceptDBusCodeCT[], l1: "TopLevel"];
reqDevCT: Core.CellType ← CoreFlat.CellTypeCutLabels[on: Arbiter.ArbRandReq[], l1: "TopLevel"];
inst ← InstanceList[
type: arbCT,
pas: LIST[
[public: CoreOps.FindWire[arbCT.public, "DReq"][0], actual: "DReq00"],
[public: CoreOps.FindWire[arbCT.public, "DReq"][1], actual: "DReq01"],
[public: CoreOps.FindWire[arbCT.public, "DReq"][2], actual: "DReq02"],
[public: CoreOps.FindWire[arbCT.public, "DGrant"][0], actual: "DGrant00"],
[public: CoreOps.FindWire[arbCT.public, "DGrant"][1], actual: "DGrant01"],
[public: CoreOps.FindWire[arbCT.public, "DGrant"][2], actual: "DGrant02"],
[public: CoreOps.FindWire[arbCT.public, "DOwner"][0], actual: "DOwner00"],
[public: CoreOps.FindWire[arbCT.public, "DOwner"][1], actual: "DOwner01"],
[public: CoreOps.FindWire[arbCT.public, "DOwner"][2], actual: "DOwner02"],
[public: CoreOps.FindWire[arbCT.public, "BOwnerOut"], actual: "BOwner"],
[public: CoreOps.FindWire[arbCT.public, "BOwnerIn"], actual: "BOwner"],
[public: CoreOps.FindWire[arbCT.public, "DShared"][0], actual: "DShared00"],
[public: CoreOps.FindWire[arbCT.public, "DShared"][1], actual: "DShared01"],
[public: CoreOps.FindWire[arbCT.public, "DShared"][2], actual: "DShared02"],
[public: CoreOps.FindWire[arbCT.public, "BSharedOut"], actual: "BShared"],
[public: CoreOps.FindWire[arbCT.public, "BSharedIn"][0], actual: "BShared"],
[public: CoreOps.FindWire[arbCT.public, "DStop"][0], actual: "DStop00"],
[public: CoreOps.FindWire[arbCT.public, "DStop"][1], actual: "DStop01"],
[public: CoreOps.FindWire[arbCT.public, "DStop"][2], actual: "DStop02"],
[public: CoreOps.FindWire[arbCT.public, "BStopOut"], actual: "BStop"],
[public: CoreOps.FindWire[arbCT.public, "BStopIn"][0], actual: "BStop"],
[public: CoreOps.FindWire[arbCT.public, "BdVersion"][0],
actual: CoreOps.FindWire[publics, "DHybridSel"][0]],
[public: CoreOps.FindWire[arbCT.public, "BdVersion"][1],
actual: CoreOps.FindWire[publics, "DHybridSel"][5]]
],
name: "Arb0"];
instances ← CONS[inst, instances];
inst ← InstanceList[
type: reqDevCT,
pas: LIST [
[public: "DReq", actual: "DReq01"],
[public: "DGrant", actual: "DGrant01"],
[public: "DOwner", actual: "DOwner01"],
[public: "DShared", actual: "DShared01"],
[public: "DStop", actual: "DStop01"],
[public: "DHybridSel", actual: CoreOps.FindWire[publics, "DHybridSel"][13]],
[public: "nDReset", actual: CoreOps.FindWire[publics, "DBus"][nDReset]]
],
name: "RandomReq1"];
instances ← CONS[inst, instances];
inst ← InstanceList[
type: reqDevCT,
pas: LIST [
[public: "DReq", actual: "DReq02"],
[public: "DGrant", actual: "DGrant02"],
[public: "DOwner", actual: "DOwner02"],
[public: "DShared", actual: "DShared02"],
[public: "DStop", actual: "DStop02"],
[public: "DHybridSel", actual: CoreOps.FindWire[publics, "DHybridSel"][14]],
[public: "nDReset", actual: CoreOps.FindWire[publics, "DBus"][nDReset]]
],
name: "RandomReq2"];
instances ← CONS[inst, instances];
ct ← CoreCreate.Cell[public: publics, onlyInternal: internals, instances: instances,
name: "SimpleArbSys" ];
};
SimplestArbInit: PUBLIC PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC [memory: BOOLTRUE], dBusInit: DBusInitList ← NIL ] = {
DAShift: PROC [ val: BitOps.BitWord ] = {
p[DBus][DAddress].b ← TRUE;
DDShift[16, val];
p[DBus][DAddress].b ← FALSE;
};
DDShift: PROC [ size: [1..16], val: BitOps.BitWord ] = {
FOR i: NAT IN [0..size) DO
p[DBus][DSerialIn].b ← BitOps.EBFW[val, i, size];
p[DBus][DShiftCK].b ← FALSE;
Eval[];
p[DBus][DShiftCK].b ← TRUE;
Eval[];
ENDLOOP;
};
DDShiftCheck: PROC [ size: [1..16], valIn: BitOps.BitWord, valOut: BitOps.BitWord ] = {
FOR i: NAT IN [0..size) DO
p[DBus][DSerialIn].b ← BitOps.EBFW[valIn, i, size];
p[DBus][DShiftCK].b ← FALSE;
p[DBus][DSerialOut].b ← BitOps.EBFW[valOut, i, size];
p[DBus][DSerialOut].d ← expect;
Eval[];
p[DBus][DSerialOut].d ← none;
p[DBus][DShiftCK].b ← TRUE;
Eval[];
ENDLOOP;
};
DBus: NAT = CoreOps.GetWireIndex[cellType.public, "DBus"];
prioritiesArray: ARRAY [0..5) OF CARDINAL;
priorities: BitOps.BitMWord;
a: NAT ← 0; -- arbiter number
TRUSTED { priorities ← DESCRIPTOR[prioritiesArray] };
FOR i: NAT IN [DShiftCK..DSerialIn] DO
p[DBus][i].d ← force;
ENDLOOP;
p[DBus][DSerialOut].d ← none;
p[DBus][DExecute].b ← FALSE;
p[DBus][nDFreeze].b ← TRUE;
p[DBus][nDReset].b ← FALSE;
DAShift[08000H+1000H*a]; -- check arbiter signature
DDShiftCheck[16, 0, 5041H];
DAShift[08000H+1000H*a+2]; -- load arbiter number
DDShift[3, a];
DDShiftCheck[3, a, a];
DAShift[08000H+1000H*a+1];
FOR d: Devices IN Devices DO
BitOps.ICIM[2*16+9*2+1, priorities, 9*d, 9, 8*9];
high type: priority 1, short
low type: priority 4, long
disable length FIFO
ENDLOOP;
FOR dil: DBusInitList ← dBusInit, dil.rest WHILE dil # NIL DO
di: REF DBusInitItem = NARROW[dil.first];
IF di.addr = CARDINAL[08000H+1000H*a+1] THEN
BitOps.ILIM[di.container, priorities, di.offset, di.containerWidth, 8*9];
ENDLOOP;
DAShift[08000H+1000H*a+1];
FOR i: NAT IN [0..8) DO
DDShift[9, BitOps.ECFM[priorities, 9*i, 9, 8*9]];
ENDLOOP;
};
SanityName: Core.ROPE = Rosemary.Register[roseClassName: "Sanity", init: SanityInit, evalSimple: SanitySimple];
SanityPublic: Wire = WireList[LIST[
Seq["ArbRovers6s", maxArbiters, Seq[size: 8, protoChild: Seq[size: 3]]],
Seq["nDGrants", maxArbiters, Seq[size: maxDevices]], -- radial lines
"nDReset",
"Ck", "Vdd", "Gnd"
]];
CreateSanity: PUBLIC PROC RETURNS [ct: CoreCreate.CellType] = {
arbRovers6s: NAT;
ct ← CoreOps.CreateCellType[
class: CoreClasses.unspecifiedCellClass,
public: SanityPublic,
name: "Sanity"
];
arbRovers6s ← Ports.PortIndex[ct.public, "ArbRovers6s"];
FOR a: Arbiters IN Arbiters DO
FOR pr: Priority IN Priority DO
[] ← Ports.InitPort[ct.public[arbRovers6s][a][pr], c, aggregate, none];
ENDLOOP;
ENDLOOP;
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: SanityName];
};
SanityState: TYPE = REF SanityStateRec ← NIL;
SanityStateRec: TYPE = RECORD [
ArbRovers6s, nDGrants, nDReset, Ck: NATLAST[NAT]
];
SanityInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANYNIL, steady: BOOLFALSE ] RETURNS [ stateAny: REF ANYNIL ] -- Rosemary.InitProc -- = {
st: SanityState ← NEW[SanityStateRec];
[st.ArbRovers6s, st.nDGrants, st.nDReset, st.Ck] ←
Ports.PortIndexes[cellType.public, "ArbRovers6s", "nDGrants", "nDReset", "Ck"];
stateAny ← st;
};
SanitySimple: PROC [ p: Ports.Port, stateAny: REF ANY, clockEval: BOOLFALSE ] -- Rosemary.EvalProc -- = {
st: SanityState = NARROW[stateAny];
IF NOT clockEval AND NOT p[st.Ck].b AND p[st.nDReset].b THEN {
grantCount: NAT ← 0;
FOR a: Arbiters IN Arbiters DO
FOR d: Devices IN Devices DO
IF NOT p[st.nDGrants][a][d].b -- low-active -- THEN grantCount ← grantCount+1;
ENDLOOP;
ENDLOOP;
IF grantCount > 1 THEN ERROR;
FOR pr: Priority IN Priority DO
FOR a: Arbiters IN Arbiters DO
a2: Arbiters = (a+1) MOD maxArbiters;
ra: Arbiters = (p[st.ArbRovers6s][a][pr].c-a+maxArbiters) MOD maxArbiters;
ra2: Arbiters = (p[st.ArbRovers6s][a2][pr].c-a2+maxArbiters) MOD maxArbiters;
IF ra # ra2 THEN ERROR;
ENDLOOP;
ENDLOOP;
};
};
END.