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
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
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:
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:
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:
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
Observe the latch marked in the schematic.
Now if we remove the comment then the RTL will be like in the image below.
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 !!!”