Electrical – Priority encoder and normal encoder

encoderverilog

I would like to ask some questions about inferring the priority and normal encoder using Verilog on the FPGA.

I've used the example codes from the book "advanced chip design practical examples in Verilog"

Code for pri_encoder

module pri_encoder
(D0, D1, D2, D3, D4, D5, D6, D7,
Q2Q1Q0);

input D0, D1, D2, D3, D4, D5, D6, D7;
output [2:0] Q2Q1Q0;
reg    [2:0] Q2Q1Q0;

always @*
  begin
    Q2Q1Q0 = 3'b000;
      if(D0) Q2Q1Q0 = 3'b000;
      else if(D1) Q2Q1Q0 = 3'b001;
      else if(D2) Q2Q1Q0 = 3'b010;
      else if(D3) Q2Q1Q0 = 3'b011;
      else if(D4) Q2Q1Q0 = 3'b100;
      else if(D5) Q2Q1Q0 = 3'b101;
      else if(D6) Q2Q1Q0 = 3'b110;
      else if(D7) Q2Q1Q0 = 3'b111;
  end
endmodule

Code for normal encoder

module encoder
(D0, D1, D2, D3, D4, D5, D6, D7,
Q2Q1Q0);

input D0, D1, D2, D3, D4, D5, D6, D7;
output [2:0] Q2Q1Q0;
reg    [2:0] Q2Q1Q0;

always @*
  begin
    Q2Q1Q0 = 3'b000;
    case (1'b1)
      D0: Q2Q1Q0 = 3'b000;
      D1: Q2Q1Q0 = 3'b001;
      D2: Q2Q1Q0 = 3'b010;
      D3: Q2Q1Q0 = 3'b011;
      D4: Q2Q1Q0 = 3'b100;
      D5: Q2Q1Q0 = 3'b101;
      D6: Q2Q1Q0 = 3'b110;
      D7: Q2Q1Q0 = 3'b111;
    endcase
  end
endmodule 

The first question is about the constant expression in the switch case. It seems that constant expression can be located inside the switch (exp) and the element that has 1'b1 can be picked. Does it infer the priority encoder or just normal encoder?

At the first glance, it seems like the case with constant expression will work like a priority encoder, but when I synthesize the above code on the Vivado platform, the synthesized schematic seems like below.

enter image description here

The second question is how can we know if the synthesized design is priority encoder or normal encoder if they are constructed using the LUTs? When I look at the Q2Q1Q02 and Q2Q1Q0[1] it seems that all the data D0 ~ D7 are connected to LUTs only one time. However, for the Q2Q1Q0[0] two LUT6 are connected to generate an output and some data inputs are connected to two LUTs.

Best Answer

Your if-else and case(1'b1) are both priority encoders. A normal encoder would look like the following:

always @*
  begin
    Q2Q1Q0 = 3'b000;
    case ({D7,D6,D5,D4,D3,D2,D1,D0})
      8'h01: Q2Q1Q0 = 3'b000;
      8'h02: Q2Q1Q0 = 3'b001;
      8'h04: Q2Q1Q0 = 3'b010;
      8'h08: Q2Q1Q0 = 3'b011;
      8'h10: Q2Q1Q0 = 3'b100;
      8'h20: Q2Q1Q0 = 3'b101;
      8'h40: Q2Q1Q0 = 3'b110;
      8'h80: Q2Q1Q0 = 3'b111;
    endcase
  end

A normal encoder considers the whole input expression and only one bit must be one. If more bits are one then no conditions are meet (default and/or error condition depending it is coded).

Priority encoders have precedence to bits if two more more bits are high. If the input is 8'h12 then either 1 or 5 (depending on the priority order) will be returned. A normal encoder will return 0 (and/or an error) because the input is not one-hot. See the true table below.

$$ \begin{array}{r|lcr|lcr|l} \ \text{Normal} &&& \text{Priority (LSB)} &&& \text{Priority (MSB)} \\ 00000001 & 000 && ???????1&000 && 00000001 & 000 \\ 00000010 & 001 && ??????10&001 && 0000001? & 001 \\ 00000100 & 010 && ?????100&010 && 000001?? & 010 \\ 00001000 & 011 && ????1000&011 && 00001??? & 011 \\ 00010000 & 100 && ???10000&100 && 0001???? & 100 \\ 00100000 & 101 && ??100000&101 && 001????? & 101 \\ 01000000 & 110 && ?1000000&110 && 01?????? & 110 \\ 10000000 & 111 && 10000000&111 && 1??????? & 111 \\ \color{blue}{\text{otherwise}} & - \color{red}{\text{ [error]}} && 00000000 & - \color{red}{\text{ [error]}} && 00000000 & - \color{red}{\text{ [error]}} \\ \end{array} $$

The syntax case(1'b1) compares a value to a list a variables and executes the first match. Where as typical case statements compares a variable to a list for values and executes the first match. By default case(1'b1) infers a priority encoder. However, the synthesizer may choose to use a normal encoder if it can determine the input is guaranteed to be one-hot and if it satisfies timing and resource requirements. Most synthesizer have pragmas that allows to user force the type. Pragma commands are not universal so you will need to refer to the manual. Note pragmas are for experts, only use them when required.