DIRECTORY Arbiter, BitOps, Core, CoreClasses, CoreCreate, CoreProperties, FIFOQueue, DynaBusInterface, Ports, Rosemary, RosemaryUser; ArbiterImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, FIFOQueue, Ports, Rosemary EXPORTS Arbiter = BEGIN DReq, Reset, Clock, DGrant, Vdd, Gnd: NAT _ LAST[NAT]; ROPE: TYPE = Core.ROPE; Port: TYPE = Ports.Port; Cmd: TYPE = DynaBusInterface.Cmd; reqBits: CARDINAL = 2; reqIdle: CARDINAL = 3; seize: CARDINAL = 2; reqTwo: CARDINAL = 1; reqFive: CARDINAL = 0; Reply2: ATOM = $Reply2; Reply5: ATOM = $Reply5; maxRequestsPend: CARDINAL _ 3; requestsPend: CARDINAL _ 0; grantCycles: CARDINAL _ 0; grantDelay: CARDINAL _ 0; busLocked: BOOL _ FALSE; queue: FIFOQueue.Queue _ NIL; currentReq: ATOM _ NIL; prevClock: BOOL _ FALSE; Create: PUBLIC PROC RETURNS [ct: Core.CellType] = { ct _ CoreClasses.CreateUnspecified[ public: CoreCreate.WireList[LIST[CoreCreate.Seq["DReq", reqBits], "Reset", "Clock", "DGrant", "Vdd", "Gnd"], "Arbiter", NIL], name: arbiterName ]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: arbiterName]; InitPortIndicies[ct]; [] _ Ports.InitPorts[ct, b, force, "DGrant"]; [] _ Ports.InitPorts[ct, b, none, "Reset", "Clock"]; [] _ Ports.InitPorts[ct, c, none, "DReq"]; }; Init: Rosemary.InitProc = { queue _ FIFOQueue.Create[]; }; Simple: Rosemary.EvalProc = { IF prevClock=p[Clock].b THEN RETURN; --edge sensitive prevClock _ p[Clock].b; IF NOT p[Clock].b THEN RETURN; --filter falling edge IF p[Reset].b THEN { requestsPend _ 0; grantCycles _ 0; grantDelay _ 0; busLocked _ FALSE; queue _ FIFOQueue.Create[]; currentReq _ NIL; prevClock _ FALSE; }; SELECT p[DReq].c FROM reqIdle => busLocked _ FALSE; reqTwo => { FIFOQueue.Include[queue, Reply2]; requestsPend _ requestsPend+1; IF requestsPend > maxRequestsPend THEN ERROR; }; reqFive => { FIFOQueue.Include[queue, Reply5]; requestsPend _ requestsPend+1; IF requestsPend > maxRequestsPend THEN ERROR; }; seize => busLocked _ TRUE; ENDCASE => ERROR; IF currentReq=NIL AND NOT FIFOQueue.IsEmpty[queue] THEN { currentReq _ NARROW[FIFOQueue.Remove[queue]]; grantCycles _ IF currentReq=Reply2 THEN 2 ELSE 5; grantDelay _ 5; --a very simple arbiter delay model }; IF currentReq#NIL AND grantDelay=0 THEN { IF grantCycles#0 THEN { p[DGrant].b _ TRUE ; grantCycles _ grantCycles-1; } ELSE { p[DGrant].b _ FALSE; currentReq _ NIL; requestsPend _ requestsPend-1; }; }; IF grantDelay#0 THEN grantDelay _ grantDelay-1; }; InitPortIndicies: PROC [ct: Core.CellType] = { [DReq, Reset, Clock, DGrant, Vdd, Gnd] _ Ports.PortIndexes[ct.public, "DReq", "Reset", "Clock", "DGrant", "Vdd", "Gnd"]; }; BusIsLocked: PUBLIC PROC RETURNS [BOOL] = { RETURN[busLocked]; }; arbiterName: ROPE = Rosemary.Register[roseClassName: "Arbiter", init: Init, evalSimple: Simple]; END.  ArbiterImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Gasbarro April 3, 1987 9:44:13 am PST --PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY _ NIL]-- --PROC [p: Ports.Port, stateAny: REF ANY]-- ΚF˜šœ™Icodešœ Οmœ1™