DIRECTORY Arbiter, Atom, Commander, CommandTool, Convert, Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, IO, Ports, Random, Rope, Rosemary; ArbRandReq: CEDAR PROGRAM IMPORTS Atom, Commander, CommandTool, Convert, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, IO, Ports, Random, Rosemary EXPORTS Arbiter = BEGIN OPEN Arbiter, CoreCreate; logicCutSet: Rope.ROPE = "Logic"; -- should be Logic.logicCutSet, actually ArbRandReqName: Rope.ROPE = Rosemary.Register[roseClassName: "ArbRandReq", init: ArbRandReqInit, evalSimple: ArbRandReqSimple, scheduleIfClockEval: TRUE]; ArbRandReqInterface: Wire = WireList[LIST[ Seq["nRequestOut", 2], -- radial lines "nGrant", "nLongGrant", -- bussed lines "nHiPGrant", "nStartGrant", "nOwnerOut", "nOwnerIn", "nSharedOut", "nSharedIn", "nSStopOut", "nSStopIn", "nDReset", "nDynaBusBusy", "nHolding", "Ck", "Vdd", "Gnd" ]]; ArbRandReq: PUBLIC PROC [ pre: PRE _ DefaultPriority, prob: REF _ NIL ] RETURNS [ ct: CoreCreate.CellType ] = { ct _ CoreOps.CreateCellType[ class: CoreClasses.unspecifiedCellClass, public: ArbRandReqInterface, name: "ArbRandReq" ]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ArbRandReqName]; [] _ CoreFlat.CellTypeCutLabels[ct, logicCutSet]; Ports.InitPorts[ct, c, drive, "nRequestOut"]; Ports.InitPorts[ct, b, none, "nGrant", "nLongGrant", "nHiPGrant", "nStartGrant"]; Ports.InitPorts[ct, b, driveWeak, "nOwnerOut", "nSharedOut", "nSStopOut"]; Ports.InitPorts[ct, b, none, "nOwnerIn", "nSharedIn", "nSStopIn"]; Ports.InitPorts[ct, b, none, "nDynaBusBusy", "nHolding"]; Ports.InitPorts[ct, b, none, "Ck", "Vdd", "Gnd"]; ct.properties _ CoreProperties.PutProp[ct.properties, $ArbRandReqProb, prob]; ct.properties _ CoreProperties.PutProp[ct.properties, $ArbRandReqPRE, NEW[PRE _ pre]]; }; ArbRandReqState: TYPE = REF ArbRandReqStateRec _ NIL; ArbRandReqStateRec: TYPE = RECORD [ nRequestOut, nGrant, nLongGrant, nHiPGrant, nStartGrant, nOwnerOut, nOwnerIn, nSharedOut, nSharedIn, nSStopOut, nSStopIn, nDReset, nDynaBusBusy, nHolding, Ck: NAT _ LAST[NAT], pre: PRE, random: Random.RandomStream, m, s: ArbReqMSRec, lastCk: BOOL _ FALSE ]; probTable: ARRAY Arbiter.ReqCount OF INT _ [1, 4, 8, 16, 32, 64, 1]; maxCntLatency: INT _ 9; -- might be 8, certainly isn't 7 maxGrantLatency: INT _ 7; -- might be smaller defaultProbs: REF ProbabilitiesRec _ NEW[ProbabilitiesRec _ [ request: ALL[30], hold: 100 ]]; lastGenSeed: INT _ 1354117939; genRS: Random.RandomStream _ NIL; SetupSeed: PROC [ seed: INT _ 0 ] RETURNS [ IO.ROPE ] = { IF seed = 0 THEN seed _ lastGenSeed; genRS _ Random.Create[seed: seed]; lastGenSeed _ genRS.seed; RETURN[IO.PutFR["New random number seed is %d.\n", IO.int[lastGenSeed]]]; }; ArbRandReqInit: 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: ArbRandReqState _ NEW[ArbRandReqStateRec _ [ random: genRS ]]; [st.nRequestOut, st.nGrant, st.nLongGrant, st.nHiPGrant, st.nStartGrant ] _ Ports.PortIndexes[cellType.public, "nRequestOut", "nGrant", "nLongGrant", "nHiPGrant", "nStartGrant"]; [st.nOwnerOut, st.nOwnerIn, st.nSharedOut, st.nSharedIn, st.nSStopOut, st.nSStopIn] _ Ports.PortIndexes[cellType.public, "nOwnerOut", "nOwnerIn", "nSharedOut", "nSharedIn", "nSStopOut", "nSStopIn"]; [st.nDReset, st.nDynaBusBusy, st.nHolding, st.Ck] _ Ports.PortIndexes[cellType.public, "nDReset", "nDynaBusBusy", "nHolding", "Ck"]; st.pre _ NARROW[CoreProperties.GetProp[cellType.properties, $ArbRandReqPRE], REF PRE]^; stateAny _ NEW[RequesterStateRec _ [ probs: CoreProperties.GetProp[cellType.properties, $ArbRandReqProb], state: st]]; }; holdPipeLen: NAT _ 8; ArbReqMSRec: TYPE = RECORD [ reset, grant, startGrant: BOOL _ FALSE, long, prevLong: BOOL _ FALSE, grantType, prevGrantType: DevReqType, holding: BOOL _ FALSE, drc: Arbiter.DevReqCode, rqCnt: ARRAY DevReqType OF ReqCount _ ALL[0], grantCycles: INT _ 0, go: ARRAY DevReqType OF BOOL _ ALL[FALSE], delayUntilDemand: ARRAY DevReqType OF INT _ ALL[0], busBusy, busWasBusy: BOOL _ TRUE, cyclesSinceIdle: INT _ 0, lenFIFO: ARRAY ReqCount OF PacketLength _ ALL[short2], stopping, owning, sharing: BOOL _ FALSE, holdPipe: ARRAY [0..10) OF BOOL _ ALL[TRUE] ]; ArbRandReqSimple: PROC [ p: Ports.Port, stateAny: REF ANY, clockEval: BOOL ] RETURNS [ stateValue: Ports.LevelSequence _ NIL ] -- Rosemary.EvalProc -- = { ProbBool: PROC [ x: INT ] RETURNS [ b: BOOL ] = { b _ (x < never) AND (st.random.ChooseInt[1, x] <= 1); }; rs: REF RequesterStateRec = NARROW[stateAny]; st: ArbRandReqState = NARROW[rs.state]; SELECT TRUE FROM clockEval => NULL; p[st.Ck].b AND NOT st.lastCk => { -- positive clock edge st.lastCk _ TRUE; st.s _ st.m; }; NOT p[st.Ck].b => { -- Clock is low, load master latches prob: REF ProbabilitiesRec; dPriority: PriorityRec; st.lastCk _ FALSE; WITH rs.probs SELECT FROM rp: REF ProbabilitiesRec => prob _ rp; atom: ATOM => prob _ NARROW[Atom.GetProp[atom, $ArbRandReqProb]]; ENDCASE => prob _ defaultProbs; TRUSTED { dPriority _ LOOPHOLE[CARDINAL[st.pre]] }; st.m.reset _ NOT p[st.nDReset].b; st.m.grant _ NOT p[st.nGrant].b; st.m.startGrant _ NOT p[st.nStartGrant].b; st.m.long _ NOT p[st.nLongGrant].b; st.m.prevLong _ st.s.long; st.m.grantType _ (IF NOT p[st.nHiPGrant].b THEN H ELSE L); st.m.prevGrantType _ st.s.grantType; st.m.busBusy _ NOT p[st.nDynaBusBusy].b; st.m.busWasBusy _ st.s.busBusy; st.m.holding _ NOT p[st.nHolding].b; IF st.s.reset THEN { -- we're being reset st.m.rqCnt _ ALL[0]; st.m.drc _ release; st.m.grantCycles _ 0; st.m.holdPipe _ ALL[FALSE]; } ELSE { FOR drt: DevReqType IN DevReqType DO st.m.delayUntilDemand[drt] _ (SELECT TRUE FROM st.s.rqCnt[drt] = 0 => maxCntLatency, st.s.startGrant => maxGrantLatency, ENDCASE => MAX[0, st.s.delayUntilDemand[drt]-1]); IF p[st.nDReset].b AND NOT st.s.reset AND NOT st.s.busBusy AND NOT st.s.busWasBusy AND (NOT st.s.holding OR ((SELECT drt FROM H => dPriority.hiP, L => dPriority.loP, ENDCASE => ERROR) < HoldPriority)) AND (st.s.delayUntilDemand[drt] = 0) THEN ERROR; ENDLOOP; st.m.holdPipe[0] _ ProbBool[(SELECT st.s.holdPipe[0] FROM FALSE => prob.hold, TRUE => 2, ENDCASE => ERROR)]; FOR i: NAT IN [1..10) DO st.m.holdPipe[i] _ st.s.holdPipe[i-1]; ENDLOOP; st.m.stopping _ ProbBool[prob.stop]; st.m.owning _ ProbBool[prob.owner]; st.m.sharing _ ProbBool[prob.shared]; st.m.rqCnt _ st.s.rqCnt; SELECT TRUE FROM st.s.grantCycles > 1 => { IF st.s.startGrant OR NOT st.s.grant THEN ERROR; st.m.grantCycles _ st.s.grantCycles-1; }; st.s.grant => { IF NOT st.s.startGrant THEN ERROR; IF st.m.rqCnt[st.s.prevGrantType] <= 0 THEN ERROR; st.m.rqCnt[st.s.prevGrantType] _ st.s.rqCnt[st.s.prevGrantType]-1; IF NOT dPriority.nFIFOEna THEN { IF st.s.prevGrantType # L THEN ERROR; IF st.s.prevLong # (st.s.lenFIFO[0] = long5) THEN ERROR; } ELSE { expectedLong: BOOL = (SELECT TRUE FROM st.s.prevGrantType = H AND dPriority.hiLong => TRUE, st.s.prevGrantType = L AND dPriority.loLong => TRUE, ENDCASE => FALSE); IF st.s.prevLong # expectedLong THEN ERROR; }; st.m.grantCycles _ IF st.s.prevLong THEN 5 ELSE 2; }; ENDCASE => st.m.grantCycles _ 0; FOR i: ReqCount IN ReqCount DO st.m.lenFIFO[i] _ (SELECT TRUE FROM st.s.grant AND st.s.grantCycles <=1 AND i st.s.lenFIFO[i+1], st.s.grant AND st.s.grantCycles <=1 => long5, ENDCASE => st.s.lenFIFO[i]); ENDLOOP; st.m.cyclesSinceIdle _ (IF st.s.rqCnt = ALL[0] THEN 0 ELSE st.s.cyclesSinceIdle+1); FOR rType: DevReqType IN DevReqType DO st.m.go[rType] _ ProbBool[probTable[st.m.rqCnt[rType]]*prob.request[rType]]; ENDLOOP; SELECT TRUE FROM st.s.holdPipe[0] => st.m.drc _ seize; st.s.holdPipe[1] AND NOT st.s.holdPipe[0] => st.m.drc _ release; st.s.go[H] AND dPriority.nFIFOEna AND st.m.rqCnt[H] < LAST[Arbiter.ReqCount]-1 => { st.m.drc _ reqH; st.m.rqCnt[H] _ st.m.rqCnt[H]+1; }; st.s.go[H] AND NOT dPriority.nFIFOEna AND st.m.rqCnt[L] < LAST[Arbiter.ReqCount]-1 => { st.m.drc _ reqH; st.m.lenFIFO[st.m.rqCnt[L]] _ long5; st.m.rqCnt[L] _ st.m.rqCnt[L]+1; }; st.s.go[L] AND st.m.rqCnt[L] < LAST[Arbiter.ReqCount]-1 => { st.m.drc _ reqL; st.m.lenFIFO[st.m.rqCnt[L]] _ short2; st.m.rqCnt[L] _ st.m.rqCnt[L]+1; }; ENDCASE => st.m.drc _ release; }; }; -- clock low ENDCASE => NULL; p[st.nRequestOut].c _ 3-ORD[st.s.drc]; -- inverts p[st.nOwnerOut].b _ NOT st.s.owning; p[st.nOwnerOut].d _ IF p[st.nOwnerOut].b THEN driveWeak ELSE drive; p[st.nSharedOut].b _ NOT st.s.owning; p[st.nSharedOut].d _ IF p[st.nSharedOut].b THEN driveWeak ELSE drive; p[st.nSStopOut].b _ NOT st.s.stopping; p[st.nSStopOut].d _ IF p[st.nSStopOut].b THEN driveWeak ELSE drive; p[st.nDynaBusBusy].d _ IF st.s.grantCycles > 0 THEN drive ELSE driveWeak; p[st.nDynaBusBusy].b _ NOT (st.s.grantCycles > 0); p[st.nHolding].d _ IF st.s.holdPipe[holdPipeLen] THEN drive ELSE driveWeak; p[st.nHolding].b _ NOT st.s.holdPipe[holdPipeLen]; }; ArbRandReqSeedProc: PROC [ cmd: Commander.Handle ] RETURNS [ result: REF _ NIL, msg: Rope.ROPE _ NIL ] -- Commander.CommandProc -- = { seed: INT _ 0; argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd]; IF argv.argc > 1 THEN seed _ Convert.IntFromRope[ argv[1] ! Convert.Error => CONTINUE ]; cmd.out.PutRope[SetupSeed[seed]]; }; Commander.Register["ArbRandReqSeed", ArbRandReqSeedProc, "Reseeds the random number generator for the Arbiter simulation. Usage is\n ArbRandReqSeed n\n where n is an integer. 0 recovers the previous seed."]; END. ΖArbRandReq.mesa McCreight May 22, 1987 6:44:52 pm PDT Last Edited by: McCreight December 28, 1987 4:33:23 pm PST P a r a m e t e r s b has an 1-in-x chance of being true, except if x >= never Κ -˜šœ™Jšœ"Οk™%Icodešœ:™:—J˜š ˜ Jšœrœ ˜”J˜—šΟn œœ˜šœdœ˜†Jšœ˜—J˜Jšœœ˜J˜Jšœœ Οc(˜JJ˜Jšžœœ{œ˜šJ˜šžœœ˜*JšœŸ˜&Jšœ ˜ JšœŸ˜Jšœ ˜ Jšœ˜J˜ J˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ J˜J˜J˜—šž œœœœœœœ ˜o˜J˜(J˜J˜J˜—J˜HJ˜1Jšœ-˜-JšœQ˜QJšœJ˜JJšœB˜BJšœ9˜9Jšœ1˜1JšœM˜MJšœFœœ ˜VJ˜—J˜Jšœœœœ˜5šœœœ˜#šœ8˜8Jšœ@˜@Jš œ!žœœœœ˜5—Jšœœ˜ J˜J˜Jšœœ˜J˜J˜—Jšœ™˜Jšœ œœœ˜DJšœœŸ ˜8JšœœŸ˜-J˜—J˜šœœœ˜=Jšœ œ˜Jšœ ˜ Jšœ˜—J˜J˜Jšœ œ˜Jšœœ˜!J˜š ž œœ œœœœ˜9Jšœ œ˜$J˜"J˜Jšœœ*œ˜IJ˜—˜J˜—šžœœ8œœœ œœœ œœœ$œŸœ˜Ψšœœ˜0J˜ J˜—šœK˜KJšœf˜f—šœU˜UJšœp˜p—šœ3˜3JšœP˜P—Jšœ œ>œœ˜Wšœ œ˜$JšœQ˜Q—J˜—˜J˜—šœ œ˜J˜—šœ œœ˜Jšœœœ˜'Jšœœœ˜J˜%Jšœ œœ˜J˜Jšœœ œ œ˜-Jšœ œ˜Jš œœ œœœœ˜*Jš œœ œœœ˜3Jšœœœ˜!Jšœœ˜Jšœ œ œœ ˜6Jšœœœ˜(Jš œ œ œœœœ˜+J˜J˜J˜—Jšžœœœœ œœ%œŸœ˜š˜š žœœœœœ˜1Jšœ:™:Jšœœ"˜5Jšœ˜J˜—Jšœœœ ˜-Jšœœ ˜'J˜šœœ˜Jšœ œ˜šœ œœŸ˜8Jšœ œ˜Jšœ ˜ J˜—šœŸ$˜8Jšœœ˜Jšœ˜Jšœ œ˜šœ œ˜Jšœœ˜&Jšœœ œ&˜AJšœ˜—Jšœœœ ˜3Jšœ œ˜!Jšœ œ˜ Jšœœ˜*Jšœ œ˜#J˜Jš œœœœœ˜:J˜$Jšœœ˜(Jšœ˜Jšœœ˜$J˜šœ œŸ˜)Jšœ œ˜J˜J˜Jšœœœ˜J˜—šœ˜šœœ ˜$šœœœ˜.Jšœ%˜%J˜#Jšœœ#˜1J˜—š œœœ œœ ˜:šœœ˜šœœœœ˜&Jšœ˜Jšœ˜Jšœœ˜"—Jšœ"œœ˜0——šœ˜J˜——šœœ˜9Jšœ˜Jšœ˜ Jšœœ˜—šœœœ ˜J˜&Jšœ˜—Jšœ$˜$Jšœ#˜#šœ%˜%J˜—J˜šœœ˜˜Jš œœœ œœ˜0J˜&J˜—˜Jšœœœœ˜"Jšœ%œœ˜2J˜Bšœœœ˜ Jšœœœ˜%Jšœ+œœ˜8Jšœ˜—šœ˜šœœœœ˜&Jšœœœ˜4Jšœœœ˜4Jšœœ˜—Jšœœœ˜,Jšœ˜—Jšœœœœ˜2J˜—šœ˜ Jšœ˜—J˜—šœ œ ˜šœœœ˜#Jšœ œœœ ˜NJšœ œ˜-Jšœ˜—Jšœ˜J˜—Jš œœœœœ˜Sšœœ ˜&˜J˜;—Jšœ˜J˜—šœœ˜šœ˜Jšœ˜—šœœœ˜,Jšœ˜—šœ œœœ˜SJšœ˜Jšœ ˜ J˜—š œ œœœœ˜WJšœ˜Jšœ$˜$Jšœ ˜ J˜—šœ œœ˜