When multiple clients wish to share a resource, an arbiter is required. An arbiter decides which requester should be serviced.
Typical shared resources are busses, memories and multipliers.
There are two main arbitration disciplines:
Another major policy variation is preemptive or not: can a granted resource be deassigned while the request is still asserted.
Arbiter circuits may be synchronous or asynchronous.
Complex disciplines involve dynamic priorites based on use history and to avoid starvation or might implement 'best matchings' between a number of requesters and a number of resources.
RTL implementation of synchronous, static priority arbiter with preemption.
module arbiter(clk, reset, reqs, grants); input clk, reset; input [2:0] reqs; output reg [2:0] grants; always @(posedge clk) if (reset) grants <= 0; else begin grants <= reqs; // Highest static priority grants <= reqs && !(reqs); grants <= reqs && !(reqs || reqs); end
Exercise: Give the RTL code for a non-preemptive version of the 3-input arbiter..par
Exercise: Give the RTL code for a round-robin, non-preemptive version of the 3-input arbiter.