# A Better Priority Arbiter

A priority arbiter is a useful building block, but the usual manual implementations using `case` statements or chains of `assign` statements are hard to follow, and must be manually adjusted each time the number of requestors changes. For reference, see Section 3 of Matt Weber's Arbiters: Design Ideas and Coding Styles, which is dated and very ASIC-centric, but contains useful diagrams and discussion.

A better description of a priority arbiter comes from Henry S. Warren Jr.'s Hacker's Delight, which describes many, many techniques using integer arithmetic extended with Boolean operations (and vice-versa) to create branch-free implementations of common and not-so-common operations. By being branch-free, these implementations map well to hardware, and by using integer arithmetic, provide a compact, clear way to express calculations across the bits of a word via the arithmetic carry bits.

In Chapter 2 ("Basics", available on his website), he shows how a subtraction followed by a bitwise AND isolates the right-most (Least Significant) bit set, or returns zero if none set. For example:

```00000 --> 00000
01101 --> 00001
01100 --> 00100
```

If we take the bits, right-to-left, as requests of higest-to-lowest priority, we can use this simple operation to describe a priority arbiter. And since we express it as integer arithmetic and Booleans, it will map quite naturally to the adder carry-chain and LUT logic of an FPGA. The carry-chain provides a high-speed right-to-left connection between each bit in the word. Wrapping that one line of code into a module indicates its meaning, and allows trivial parameterization to any number of requestors.

```// Simple priority arbiter.
// Returns the LSB set, where bit 0 has highest priority

`default_nettype none

module Priority_Arbiter
#(
parameter       WORD_WIDTH          = 0
)
(
input   wire    [WORD_WIDTH-1:0]    requests,
output  reg     [WORD_WIDTH-1:0]    grant
);

initial begin
grant = 0;
end

always @(*) begin
grant = requests & -requests;
end

endmodule
```

fpgacpu.ca