<> <> <> <> 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: NAT _ LAST[NAT] ]; SanityInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL, steady: BOOL _ FALSE ] RETURNS [ stateAny: REF ANY _ NIL, 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: BOOL _ FALSE ] 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 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: NAT _ LAST[NAT] ]; WireAndInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL, steady: BOOL _ FALSE ] RETURNS [ stateAny: REF ANY _ NIL, 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: BOOL _ FALSE ] 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: NAT _ LAST[NAT] ]; PluralInit: PROC [ cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL, steady: BOOL _ FALSE ] RETURNS [ stateAny: REF ANY _ NIL, 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: BOOL _ FALSE ] 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.