When multiple clients wish to share a resource, an arbiter is required. An arbiter decides which requester should be serviced.
Arbiter circuits may be synchronous or asynchronous.
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.
Complex disciplines involve dynamic priorites based on use history that 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.
Exercise: Give the RTL code for a round-robin, non-preemptive version of the 3-input arbiter.