//# A Round-Robin Arbiter (Weighted) // Returns a one-hot grant bitmask selected from one of the raised request // bits in a word, in round-robin order, going from least-significant bit // (highest priority) to most-significant bit (lowest priority), and back // around. *A grant is held until the request is released.* // Unset request bits are skipped, which avoids wasting time. Requests can be // raised or dropped before their turn comes, but this must be done // synchronously to the clock. *Grants are calculated combinationally from the // requests*, so pipeline as necessary. //## Usage // A common use-case for an arbiter is to drive a [one-hot // multiplexer](./Multiplexer_One_Hot.html) to select one of multiple senders // requesting for one receiver, or one of multiple receivers requesting from // one sender. This arrangement requires that the requestors can raise and // hold a `requests` bit, wait until they receive the correspondig `grant` bit // to begin their transaction, and to drop their `requests` bit only once they // are done. This is very similar to a ready/valid handshake, except that the // transaction cannot be interrupted, else the granted access is lost. //## Fairness `default_nettype none module Arbiter_Round_Robin_Weighted #( parameter INPUT_COUNT = 5, parameter WEIGHT_WIDTH = 8, // Do not set at instantiation (except in IPI) parameter WEIGHT_WIDTH_TOTAL = WEIGHT_WIDTH * INPUT_COUNT ) ( input wire clock, input wire clear, input wire [INPUT_COUNT-1:0] requests, input wire [WEIGHT_WIDTH_TOTAL-1:0] grant_fraction_numerator, input wire [WEIGHT_WIDTH_TOTAL-1:0] grant_fraction_denominator, output wire [INPUT_COUNT-1:0] grant ); generate genvar i; wire [INPUT_COUNT-1:0] weight_mask; wire [INPUT_COUNT-1:0] grant_previous; for(i=0; i multiply/divide .pulses_in (grant [i]), .pulses_out (weight_mask [i]), // verilator lint_off PINCONNECTEMPTY .multiply_overflow () // verilator lint_on PINCONNECTEMPTY ); end endgenerate Arbiter_Round_Robin #( .INPUT_COUNT (INPUT_COUNT) ) Arbiter_Round_Robin ( .clock (clock), .clear (clear), .requests (requests), .requests_mask (~weight_mask), // Set to all-ones if unused. .grant_previous (grant_previous), .grant (grant) ); endmodule