Case and Conditional Statements Synthesis CAUTION !!!

Case and Conditional Statements are available in both VHDL and Verilog. These are considered as significant features of behavioral modelling, be it in VHDL or Verilog. Behavioral modelling provides high level abstraction so that the circuit can be designed by programming its functionality.

Let’s say, we have to design a circuit that selects a particular input line to be transmitted to the output at a particular instant. To be more specific, let’s consider we have four input lines ‘a’,’b’,’c’,’d’ and and the circuit would decide which input line goes to the output. Now if you are spontaneous enough and you know digital a little bit then you will jump and say its a 4:1 MUX. Good enough; but now leave the MUX aside and look at the functionality.

There are two ways to code it in behavioral modelling – “conditional statements If and else” and “multiway branching case. Lets use both in Verilog to construct the above circuit.

Code (A) Use of Conditional Statements

module MUX_4_1 (out,sel,a,b,c,d);

input a,b,c,d;
input [1:0] sel;
output reg out;

always @ (a,b,c,d,sel)
  begin
    if (sel==2'b00) // Use of conditional statement
      out=a;
    else if (sel==2'b01)
      out=b;
    else if (sel==2'b10)
      out=c;
    else
      out=d;
  end
endmodule

The RTL schematic implemented by the above code using Quartus II

Image (a)

Code (B) Use of case Statement

module MUX_4_1_case (out,sel,a,b,c,d);

  input a,b,c,d;
  input [1:0] sel;
  output reg out;

  always @ (a,b,c,d,sel)
    begin
      case (sel)
        2'b00 : out = a;
        2'b01 : out = b;
        2'b10 : out = c;
        default : out = d;
      endcase
    end

endmodule

The RTL schematic implemented by the above code using Quartus II

Image (b)

Let’s compare both the schematics from an electronic engineer point of view.

If we compare these two hardware, we can observe that the image (a) has unnecessary comparators and two multiplexers are joined like priority mux which is not a good design as it adds combinational delay to the design, while in image (b) it is a conventional multiplexer with very less delay. Then for obvious reason design (b) would be preferred over design (a).


To get the better feel of the comparison, let’s add schematics of 8:1 MUX for both the design styles:

8:1 MUX functionality structure : A schematic inferred by using conditional statements

8_1 mux edited

8:1 MUX functionality structure : A schematic inferred by using case statements

The difference can be easily observed.Now if you synthesize it on any other tool lets say ISE, you may probably get a mux for both, as tools are intelligent enough to figure out that this a non overlapping full case or if, but it doesn’t mean that you can go with it especially in an ASIC design.


If you forget to cover all the conditions that means if you forget to write “default” in a “case” or “else” condition in a “if” then the tool will infer a latch for that signal, now latches are not preferred for design if not implemented intentionally as they cause serious timing issues.

For eg. consider the following code:

module MUX_8_1_case (out,sel,a,b,c,d,e,f,g,h);

input a,b,c,d,e,f,g,h;
input [2:0] sel;
output reg out;

always @ (a,b,c,d,e,f,g,h,sel)
  begin
    case (sel)
       3'b000 : out = a;
       3'b001 : out = b;
       3'b010 : out = c;
       3'b011 : out = d;
       3'b100 : out = e;
       3'b101 : out = f;
       3'b110 : out = g;
    endcase //Default statement absent
  end
endmodule

The schematic inferred by the above code is as below:
Mux_latch_edited

Same happens when a “else” is absent in conditional statements as described in the following code:

module MUX_4_1 (out,sel,a,b,c,d,en);

input a,b,c,d,en;
input [1:0] sel;
output reg out;

always @ (a,b,c,d,sel,en)
  begin
    if (sel==2'b00 && en)
      out=a;
    else if (sel==2'b01 && en)
      out=b;
    else if (sel==2'b10 && en)
      out=c;
    else if (sel==2'b11 && en) //else statement absent
      out=d;
  end
endmodule

It implements this structure:

if_latch_edited

Even the synthesis toll will give you a warning for this. You may achieve the functionality that you want, but it may not be always correct; for example in the above code if the en pin is high the circuit works fine but when it is low it will latch the previous value instead of resetting the output to 0.


Also, when you have multiple outputs its important to cover each output in every condition of the code otherwise a latch will get inferred. For example look at the following code.

module MUX_4_1_case (out1,out2,sel,a,b,c,d,en);

  input a,b,c,d,en;
  input [1:0] sel;
  output reg out1,out2;

  always @ (a,b,c,d,sel,en)
    begin
       case ({sel,en})
          3'b001 : begin
             out1 = a;
             out2 = d;
          end
          3'b011 : begin
             out1 = b;
             out2 = c;
          end
          3'b101 : begin
             out1 = c;
           //out2 = b; // comment out this line for output 2
          end
          3'b111 : begin
            out1 = d;
            out2 = a;
          end
          default : begin
            out1 = 0;
            out2 = 0;
          end
       endcase
    end
endmodule

Look at the RTL it gives as a result

Latch_for_out2Observe the latch marked in the schematic.

Now if we remove the comment then the RTL will be like in the image below.

Dual_Mux


 

So these are some of the small concepts regarding the use of “Case” an “If” statements which should be taken care while designing. If not considered, the design may show proper functionality but would fail when a critical condition or timing mismatch happens.

5 comments for “Case and Conditional Statements Synthesis CAUTION !!!

Leave a Reply

Your email address will not be published. Required fields are marked *