diff --git a/vram/MemArbiter.bsv b/vram/MemArbiter.bsv index 0387d01..8ff741f 100644 --- a/vram/MemArbiter.bsv +++ b/vram/MemArbiter.bsv @@ -25,6 +25,7 @@ function Bool mem_ops_conflict(Maybe#(MemArbiterOp#(addr)) a, Maybe#(MemArbiterO endfunction // A MemArbiterServer receives requests and emits grants. +(* always_ready *) interface MemArbiterServer#(type addr); method Action request(MemArbiterOp#(addr) req); method Bool grant(); @@ -71,6 +72,7 @@ interface MemArbiter#(numeric type num_clients, type addr); // MemArbiter intances are Connectable: mkConnection(a, b) gives // conflict priority to a. That is, b only grants requests that // don't conflict with a's grant. + (* always_ready *) method Action conflict(MemArbiterOp#(addr) conflict); method MemArbiterOp#(addr) granted_op(); endinterface @@ -130,13 +132,13 @@ module mkPriorityMemArbiter(MemArbiter#(num_clients, addr)) endmodule typedef struct { - Bool granted; Vector#(n, Bool) grant_vec; - UInt#(TLog#(n)) selected; Maybe#(MemArbiterOp#(addr)) granted_op; } GrantResult#(numeric type n, type addr) deriving (Bits, Eq, FShow); -// select_grant computes which one entry of requests should be granted. +// select_grant computes which one entry of requests should be +// granted. Priority order is descending starting from +// requests[hipri]. function GrantResult#(n, addr) select_grant(Vector#(n, Maybe#(MemArbiterOp#(addr))) requests, UInt#(TLog#(n)) hipri, Maybe#(MemArbiterOp#(addr)) conflict) @@ -152,11 +154,9 @@ function GrantResult#(n, addr) select_grant(Vector#(n, Maybe#(MemArbiterOp#(addr Tuple2#(UInt#(TLog#(n)), Maybe#(MemArbiterOp#(addr))) next); match {.idx, .mreq} = next; - if (mreq matches tagged Valid .req &&& !acc.granted &&& !mem_ops_conflict(conflict, mreq)) + if (mreq matches tagged Valid .req &&& acc.granted_op matches tagged Invalid &&& !mem_ops_conflict(conflict, mreq)) return GrantResult{ - granted: True, grant_vec: onehot(idx), - selected: idx, granted_op: tagged Valid req }; else @@ -167,9 +167,7 @@ function GrantResult#(n, addr) select_grant(Vector#(n, Maybe#(MemArbiterOp#(addr let in = zip(map(fromInteger, genVector()), requests); let rot = rotateBy(in, fromInteger(valueOf(n)-1)-hipri+1); let seed = GrantResult{ - granted: False, grant_vec: replicate(False), - selected: 0, granted_op: tagged Invalid }; return foldl(do_fold, seed, rot); @@ -201,13 +199,10 @@ module mkRoundRobinMemArbiter(MemArbiter#(num_clients, addr)) let res = select_grant(in, high_prio, conflict_in.wget()); grants <= res.grant_vec; - if (res.granted) - if (res.selected == fromInteger(valueOf(num_clients)-1)) - high_prio <= 0; - else - high_prio <= res.selected+1; - if (res.granted_op matches tagged Valid .op) + if (res.granted_op matches tagged Valid .op) begin granted_op_out.wset(op); + high_prio <= validValue(findElem(True, rotateR(res.grant_vec))); + end endrule Vector#(num_clients, MemArbiterServer#(addr)) _ifcs = newVector();