0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Priority Encoder: Syntax and Example

A priority encoder in Verilog is a combinational circuit that outputs the binary code of the highest priority active input. You can write it using always @* block with if-else statements checking inputs from highest to lowest priority. The output is the index of the first input found active.
📐

Syntax

The priority encoder uses an always @* block to check inputs in order of priority. It sets the output to the index of the highest priority input that is active (logic 1). If no inputs are active, the output can be set to zero or a default value.

Key parts:

  • input [N-1:0] in: input signals to encode
  • output reg [M-1:0] out: binary output representing highest priority input
  • always @*: combinational logic block
  • if-else: checks inputs from highest to lowest priority
verilog
module priority_encoder(
    input  [3:0] in,
    output reg [1:0] out
);

always @* begin
    if (in[3])
        out = 2'd3;
    else if (in[2])
        out = 2'd2;
    else if (in[1])
        out = 2'd1;
    else if (in[0])
        out = 2'd0;
    else
        out = 2'd0; // default if no input active
end

endmodule
💻

Example

This example shows a 4-to-2 priority encoder. It outputs the binary index of the highest priority input bit that is set to 1. Inputs are checked from bit 3 (highest priority) down to bit 0 (lowest priority).

verilog
module test_priority_encoder;
    reg [3:0] in;
    wire [1:0] out;

    priority_encoder uut(.in(in), .out(out));

    initial begin
        $monitor("Input = %b, Output = %b", in, out);

        in = 4'b0000; #10;
        in = 4'b0001; #10;
        in = 4'b0010; #10;
        in = 4'b0100; #10;
        in = 4'b1000; #10;
        in = 4'b1010; #10;
        in = 4'b0110; #10;
        $finish;
    end
endmodule

module priority_encoder(
    input  [3:0] in,
    output reg [1:0] out
);

always @* begin
    if (in[3])
        out = 2'd3;
    else if (in[2])
        out = 2'd2;
    else if (in[1])
        out = 2'd1;
    else if (in[0])
        out = 2'd0;
    else
        out = 2'd0;
end

endmodule
Output
Input = 0000, Output = 00 Input = 0001, Output = 00 Input = 0010, Output = 01 Input = 0100, Output = 10 Input = 1000, Output = 11 Input = 1010, Output = 11 Input = 0110, Output = 10
⚠️

Common Pitfalls

Common mistakes when writing a priority encoder include:

  • Not checking inputs in correct priority order, which causes wrong output.
  • Not covering the case when no inputs are active, leading to undefined output.
  • Using blocking assignments (=) incorrectly in sequential logic (should use non-blocking <= in clocked blocks, but here combinational uses blocking).
  • Forgetting to declare output as reg when assigned inside always block.
verilog
/* Wrong: priority order reversed, output wrong */
always @* begin
    if (in[0])
        out = 2'd0;
    else if (in[1])
        out = 2'd1;
    else if (in[2])
        out = 2'd2;
    else if (in[3])
        out = 2'd3;
    else
        out = 2'd0;
end

/* Right: highest priority first */
always @* begin
    if (in[3])
        out = 2'd3;
    else if (in[2])
        out = 2'd2;
    else if (in[1])
        out = 2'd1;
    else if (in[0])
        out = 2'd0;
    else
        out = 2'd0;
end
📊

Quick Reference

  • Use always @* for combinational priority encoder logic.
  • Check inputs from highest to lowest priority using if-else.
  • Declare output as reg if assigned inside always block.
  • Set a default output value when no inputs are active.

Key Takeaways

Check inputs in descending priority order inside an always @* block.
Declare outputs as reg when assigned in always blocks.
Always provide a default output for no active inputs.
Use blocking assignments (=) for combinational logic inside always @*.
Test with multiple input patterns to verify priority behavior.