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 December 28, 1987 4:37:49 pm PST
DIRECTORY
Arbiter, Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, IO, Ports, Rosemary, RosemaryUser;
ArbGroupsImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreCreate, CoreFlat, CoreOps, IO, Ports, Rosemary
EXPORTS Arbiter
=
BEGIN OPEN Arbiter, CoreCreate;
logicCutSet: Core.ROPE = "Logic"; -- should be Logic.logicCutSet, actually
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["nGrants", 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, force];
ENDLOOP;
ENDLOOP;
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: SanityName];
};
SanityState: TYPE = REF SanityStateRec ← NIL;
SanityStateRec: TYPE = RECORD [
ArbRovers6s, nGrants, nDReset, Ck: NATLAST[NAT]
];
SanityInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANYNIL, steady: BOOLFALSE ] RETURNS [ stateAny: REF ANYNIL, stateValue: Ports.LevelSequence ← NIL ] -- Rosemary.InitProc -- = {
st: SanityState ← NEW[SanityStateRec];
[st.ArbRovers6s, st.nGrants, st.nDReset, st.Ck] ←
Ports.PortIndexes[cellType.public, "ArbRovers6s", "nGrants", "nDReset", "Ck"];
stateAny ← st;
};
SanitySimple: PROC [ p: Ports.Port, stateAny: REF ANY, clockEval: BOOLFALSE ] RETURNS [ stateValue: Ports.LevelSequence ← NIL ]-- 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.nGrants][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;
};
FOR a: Arbiters IN Arbiters DO
FOR pr: Priority IN Priority DO
p[st.ArbRovers6s][a][pr].c ← 0;
ENDLOOP;
ENDLOOP;
};
WireAndName: Core.ROPE = Rosemary.Register[roseClassName: "WireAnd", init: WireAndInit, evalSimple: WireAndSimple];
WireAndPublic: Wire = WireList[LIST[
"I",
"X", "Vdd", "Gnd"
]];
CreateWireAnd: PUBLIC PROC RETURNS [ct: CoreCreate.CellType] = {
ct ← CoreOps.CreateCellType[
class: CoreClasses.unspecifiedCellClass,
public: WireAndPublic,
name: "WireAnd"
];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: WireAndName];
[] ← CoreFlat.CellTypeCutLabels[ct, logicCutSet];
Ports.InitPorts[ct, l, none, "I", "X"];
};
WireAndState: TYPE = REF WireAndStateRec ← NIL;
WireAndStateRec: TYPE = RECORD [
I, X: NATLAST[NAT]
];
WireAndInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANYNIL, steady: BOOLFALSE ] RETURNS [ stateAny: REF ANYNIL, stateValue: Ports.LevelSequence ← NIL ] -- Rosemary.InitProc -- = {
st: WireAndState ← NEW[WireAndStateRec];
[st.I, st.X] ← Ports.PortIndexes[cellType.public, "I", "X"];
stateAny ← st;
};
WireAndSimple: PROC [ p: Ports.Port, stateAny: REF ANY, clockEval: BOOLFALSE ] RETURNS [ stateValue: Ports.LevelSequence ← NIL ]-- Rosemary.EvalProc -- = {
st: WireAndState = NARROW[stateAny];
SELECT p[st.I].l FROM
L => {
p[st.X].d ← drive;
p[st.X].l ← L;
};
H => {
p[st.X].d ← driveWeak;
p[st.X].l ← H;
};
ENDCASE -- X -- => {
p[st.X].d ← driveMediumWeak;
p[st.X].l ← X;
};
};
PluralName: Core.ROPE = Rosemary.Register[roseClassName: "Plural", init: PluralInit, evalSimple: PluralSimple];
CreatePlural: PUBLIC PROC [ b: NAT ] RETURNS [ct: CoreCreate.CellType] = {
ct ← CoreOps.CreateCellType[
class: CoreClasses.unspecifiedCellClass,
public: WireList[LIST[
Seq["I", b],
"X", "Vdd", "Gnd"
]],
name: IO.PutFR["Plural-%d", IO.int[b]]
];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: PluralName];
[] ← CoreFlat.CellTypeCutLabels[ct, logicCutSet];
Ports.InitPorts[ct, ls, none, "I"];
Ports.InitPorts[ct, l, drive, "X"];
};
PluralState: TYPE = REF PluralStateRec ← NIL;
PluralStateRec: TYPE = RECORD [
I, X: NATLAST[NAT]
];
PluralInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANYNIL, steady: BOOLFALSE ] RETURNS [ stateAny: REF ANYNIL, stateValue: Ports.LevelSequence ← NIL ] -- Rosemary.InitProc -- = {
st: PluralState ← NEW[PluralStateRec];
[st.I, st.X] ← Ports.PortIndexes[cellType.public, "I", "X"];
stateAny ← st;
};
PluralSimple: PROC [ p: Ports.Port, stateAny: REF ANY, clockEval: BOOLFALSE ] RETURNS [ stateValue: Ports.LevelSequence ← NIL ]-- Rosemary.EvalProc -- = {
st: PluralState = NARROW[stateAny];
count: NAT ← 0;
FOR i: NAT IN [0..p[st.I].ls.size) DO
SELECT p[st.I].ls[i] FROM
L => NULL;
H => {
count ← count+1;
IF count >1 THEN {
p[st.X].l ← H;
RETURN;
};
};
ENDCASE -- X -- => {
p[st.X].l ← X;
RETURN;
};
ENDLOOP;
p[st.X].l ← L;
};
END.