0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Priority Arbiter: Syntax and Example

A priority arbiter in Verilog grants access to the highest priority request among multiple inputs. It uses conditional checks to assign the grant signal to the first active request in priority order. The arbiter outputs a grant vector and a valid signal indicating if any request is granted.
📐

Syntax

The priority arbiter module typically has inputs for requests and outputs for grants and a valid signal. It checks requests in priority order and assigns the grant to the first active request.

  • req: Input request signals (vector)
  • grant: Output grant signals (vector)
  • valid: Output signal indicating if any request is granted
verilog
module priority_arbiter(
    input  wire [3:0] req,  // 4 request lines
    output reg  [3:0] grant, // 4 grant lines
    output reg        valid  // grant valid signal
);

always @(*) begin
    grant = 4'b0000;
    valid = 1'b0;
    if (req[0]) begin
        grant = 4'b0001;
        valid = 1'b1;
    end else if (req[1]) begin
        grant = 4'b0010;
        valid = 1'b1;
    end else if (req[2]) begin
        grant = 4'b0100;
        valid = 1'b1;
    end else if (req[3]) begin
        grant = 4'b1000;
        valid = 1'b1;
    end
end

endmodule
💻

Example

This example shows a 4-input priority arbiter where request 0 has the highest priority and request 3 the lowest. The arbiter outputs the grant for the highest priority active request and sets valid high if any request is active.

verilog
module test_priority_arbiter;
    reg [3:0] req;
    wire [3:0] grant;
    wire valid;

    priority_arbiter arb(
        .req(req),
        .grant(grant),
        .valid(valid)
    );

    initial begin
        $display("Req  Grant  Valid");
        req = 4'b0000; #10;
        $display("%b   %b    %b", req, grant, valid);

        req = 4'b0001; #10;
        $display("%b   %b    %b", req, grant, valid);

        req = 4'b0010; #10;
        $display("%b   %b    %b", req, grant, valid);

        req = 4'b0011; #10; // Both req[1] and req[0] active
        $display("%b   %b    %b", req, grant, valid);

        req = 4'b0100; #10;
        $display("%b   %b    %b", req, grant, valid);

        req = 4'b1000; #10;
        $display("%b   %b    %b", req, grant, valid);

        $finish;
    end
endmodule

module priority_arbiter(
    input  wire [3:0] req,
    output reg  [3:0] grant,
    output reg        valid
);

always @(*) begin
    grant = 4'b0000;
    valid = 1'b0;
    if (req[0]) begin
        grant = 4'b0001;
        valid = 1'b1;
    end else if (req[1]) begin
        grant = 4'b0010;
        valid = 1'b1;
    end else if (req[2]) begin
        grant = 4'b0100;
        valid = 1'b1;
    end else if (req[3]) begin
        grant = 4'b1000;
        valid = 1'b1;
    end
end

endmodule
Output
Req Grant Valid 0000 0000 0 0001 0001 1 0010 0010 1 0011 0001 1 0100 0100 1 1000 1000 1
⚠️

Common Pitfalls

Common mistakes when writing a priority arbiter include:

  • Not resetting the grant and valid signals before checking requests, causing latches.
  • Checking requests in wrong priority order, which breaks the priority logic.
  • Using blocking assignments (=) in sequential always blocks instead of non-blocking (<=), which can cause simulation mismatches.
  • Not handling the case when no requests are active, leaving valid undefined.

Example of a wrong approach and the correct fix:

verilog
/* Wrong: grant and valid not reset, may infer latch */
always @(*) begin
    if (req[0]) grant = 4'b0001;
    else if (req[1]) grant = 4'b0010;
    // valid not assigned if no request
end

/* Correct: reset grant and valid first */
always @(*) begin
    grant = 4'b0000;
    valid = 1'b0;
    if (req[0]) begin
        grant = 4'b0001;
        valid = 1'b1;
    end else if (req[1]) begin
        grant = 4'b0010;
        valid = 1'b1;
    end
end
📊

Quick Reference

Tips for writing a priority arbiter in Verilog:

  • Always initialize outputs at the start of the combinational block.
  • Check requests in strict priority order using if-else chains.
  • Use a valid signal to indicate if any request is granted.
  • Keep the arbiter combinational to avoid clock dependencies unless explicitly needed.

Key Takeaways

A priority arbiter grants the highest priority active request using if-else checks in priority order.
Always reset grant and valid outputs at the start of the combinational block to avoid latches.
Use a valid signal to indicate when a grant is active.
Check requests from highest to lowest priority to maintain correct arbitration.
Keep the arbiter logic combinational for simple and predictable behavior.