Verilog Code for Arbiter: Syntax, Example, and Tips
An arbiter in Verilog controls access to a shared resource by granting requests one at a time. Use
always blocks with priority logic or round-robin schemes to decide which request gets granted. The arbiter outputs grant signals based on input requests and a clock or enable signal.Syntax
An arbiter module typically has input request signals, output grant signals, and a clock or enable input. Inside, always blocks with if-else or case statements decide which request to grant based on priority or fairness.
- input req: Request signals from clients.
- output grant: Grant signals to clients.
- clk: Clock signal for synchronous operation.
- reset: Optional reset to clear grants.
verilog
module arbiter(
input wire clk,
input wire reset,
input wire [3:0] req,
output reg [3:0] grant
);
always @(posedge clk or posedge reset) begin
if (reset) begin
grant <= 4'b0000;
end else begin
casez (req)
4'b???1: grant <= 4'b0001; // Grant to req[0]
4'b??10: grant <= 4'b0010; // Grant to req[1]
4'b?100: grant <= 4'b0100; // Grant to req[2]
4'b1000: grant <= 4'b1000; // Grant to req[3]
default: grant <= 4'b0000; // No request
endcase
end
end
endmoduleExample
This example shows a simple 4-client priority arbiter. It grants the lowest numbered request first if multiple requests come at once. The grant output signals which client is allowed access.
verilog
module arbiter(
input wire clk,
input wire reset,
input wire [3:0] req,
output reg [3:0] grant
);
always @(posedge clk or posedge reset) begin
if (reset) begin
grant <= 4'b0000;
end else begin
casez (req)
4'b???1: grant <= 4'b0001;
4'b??10: grant <= 4'b0010;
4'b?100: grant <= 4'b0100;
4'b1000: grant <= 4'b1000;
default: grant <= 4'b0000;
endcase
end
end
endmodule
// Testbench
module tb_arbiter();
reg clk = 0;
reg reset;
reg [3:0] req;
wire [3:0] grant;
arbiter uut(.clk(clk), .reset(reset), .req(req), .grant(grant));
always #5 clk = ~clk; // 10 time units clock period
initial begin
reset = 1; req = 4'b0000;
#10 reset = 0;
req = 4'b0001; #10;
$display("req=0001 grant=%b", grant);
req = 4'b0101; #10;
$display("req=0101 grant=%b", grant);
req = 4'b1000; #10;
$display("req=1000 grant=%b", grant);
req = 4'b0000; #10;
$display("req=0000 grant=%b", grant);
$finish;
end
endmoduleOutput
req=0001 grant=0001
req=0101 grant=0001
req=1000 grant=1000
req=0000 grant=0000
Common Pitfalls
Common mistakes when writing arbiters include:
- Not handling multiple simultaneous requests properly, causing multiple grants.
- Forgetting to reset the grant signals, leading to stale grants.
- Using combinational logic without clock, which can cause glitches.
- Not prioritizing requests clearly, causing unpredictable grants.
Always use synchronous logic and clear priority or fairness rules.
verilog
/* Wrong: combinational grant without reset and priority */ module wrong_arbiter( input wire [3:0] req, output reg [3:0] grant ); always @(*) begin grant = req; // Grants all requests at once - wrong end endmodule /* Right: synchronous with priority and reset */ module right_arbiter( input wire clk, input wire reset, input wire [3:0] req, output reg [3:0] grant ); always @(posedge clk or posedge reset) begin if (reset) grant <= 4'b0000; else if (req[0]) grant <= 4'b0001; else if (req[1]) grant <= 4'b0010; else if (req[2]) grant <= 4'b0100; else if (req[3]) grant <= 4'b1000; else grant <= 4'b0000; end endmodule
Quick Reference
- Use synchronous
always @(posedge clk)blocks for stable grants. - Implement clear priority or round-robin logic to avoid conflicts.
- Reset grant signals to avoid stale outputs.
- Use
casezorif-elseto check requests in priority order. - Test with multiple simultaneous requests to verify correct arbitration.
Key Takeaways
Always use synchronous logic with clock and reset for arbiter grants.
Implement clear priority or fairness rules to decide which request to grant.
Reset grant outputs to avoid stale or multiple grants.
Test arbiter behavior with multiple simultaneous requests.
Avoid combinational grants that can cause glitches or multiple grants.