This is the way I make arbiters:
// Concise priority arbiter input [26:0] req; // Bit zero is highest priority wire [26:0] gnt = req & -req; // Isolate least significant set bit
Since this method uses fast carry logic, it's quite fast- the best win is in FPGAs, where the carry chain is much faster than regular routing. If you can do a 32-bit add in one cycle, you can certainly do a 27-bit priority arbiter. With ASICs or fully custom, you can pick the carry lookahead method of your choice. Notice also that it is very easy to parameterize.
It's not hard to make a full round-robin arbiter out of this:
reg [26:0] prev; // Previous winner (saved from last cycle) wire [26:0] req1 = req & ~((prev - 1) | prev); // Mask off previous winners wire [26:0] gnt1 = req1 & -req1; // Select new winner wire [26:0] winner = |gnt1 ? gnt1 : gnt; // Start from bit zero if none
// Save previous winner always @(posedge clk) if (winner) prev