@jbush001 Thanks for the verilog link.
'base' is a one hot signal indicating the first request that should be considered for a grant.
Huh ? And why ~(double_req-base) ?
request = 3;in edaplayground simulation ,
base=1;do not really affect the
grantsignal result. Why ?
The index must be delivered in one-hot format for this implementation.
To accomplish this, generate it from a round-robin shift register.
If this is not possible, it needs a one-hot decoder.
@jbush001 Someone told me the following explanation :
base is an indication of where you want your priority to start from. In a round robin arbiter, you want to keep your
base the previous winner left shifted by one.
a & ~(a - b) gives you a one hot vector - that marks the position in which the first time you hit a
a if you start walking left from the position where
b is set.
Here is an example. For simplicity let's consider
WIDTH = 4. Let's say
base = 'b0010. Let's say
req = 'b1001. You would expect a round robin arbiter to output
'b1000. Now let's see how that works.
double_req = 'b10011001. double_req & ~(double_req - base) = 'b10011001 & ~('b10011001 - 'b0010) = 'b10011001 & ~('b10010111) = 'b10011001 & 'b01101000 = 'b1000.
double_req ? Try working this out with
req= 'b0001 and
base = 'b0100.
double_req just helps you with the wrap around.
Other corner cases:
req = 'b0010, base = 'b0010, you'd get 'b0010. req = 'b0011, base = 'b0010, you should get 'b0010 again. req = 'b0110, base = 'b0010, you should get 'b0010. req = 'b0101, base = 'b0010, you get 'b0100.
always_comb begin : convert index = 0; for (int oh_index = 0; oh_index < NUM_SIGNALS; oh_index++) begin if (one_hot[oh_index]) begin if (DIRECTION == "LSB0") index |= oh_index[INDEX_WIDTH - 1:0]; // Use 'or' to avoid synthesizing priority encoder else index |= ~oh_index[INDEX_WIDTH - 1:0]; end end end
if (one_hot[oh_index]) // one_hot == 1 index |= ~oh_index[INDEX_WIDTH - 1:0]; // ~000 == 111
one_hot = 5'b00001, then we will arrive at output
index = 3'b111which is not the correct output