Reputation: 605
I have just found out this problem.
Suppose I use a Arbiter to arbitrate the output of a bus driver from multiple parallel transaction initiators. The bus and initiators use DecoupledIO. It is known that Arbiter prioritizes in(0) over in(1). Considering this case:
clock 1: in(0).valid = 0, in(1).valid = 1 -> out === in(1) out.valid = 1 out.ready = 0
clock 2: in(1).valid = 1, in(1).valid = 1 -> out === in(0) out.valid = 1 out.ready = 1
So both clock 1 and 2 have bus.valid === 1 If a client on this bus cannot response in the same cycle but the next cycle, the out.ready driven by this client is actually corresponding to in(1) NOT in(0) in clock 2.
I would expect the arbiter to choose in(0) if in(0) and in(1) become valid at the same clock cycle, but if in(1) turns valid before in(0), the arbiter keeps selecting in(1) until in(1) is fired.
In this case, LockingArbiter, RRArbiter all have the same behaviour, that higher priority input can always preempt lower priority input before the lower input is locked (when count == 1, there is no lock at all).
I am kind of seeing this non-stable output as a bug-like issue of Arbiter. Is there a work-around for this?
Upvotes: 0
Views: 288
Reputation: 605
A "needsHold" parameter is added to all arbiters to enable this hold requirement. This feature is disabled by default. This is included in Chisel by commit 18ecaf8de4a5.
Upvotes: 1