# VHDL: Are if-else and case statements supposed to synthesize the same hardware?

The if-else and case statements are equivalent. The later maybe easier to read when we have a lot of possibilities being checked.

A conditional is supposed to infer mux in hardware. However, there is different between having a chain of 2-to-1 mux and a big n-to-1 mux doing the same thing in terms of propagation delay.

Is the if-else statement and case statement supposed to infer the same hardware? Or is there some difference in how they would be synthesized?

• yes... there is a "bug" in APA synthesis such that a large if/elseif/... will produce a massive cascaded AND network to achieve this, eating LUT & increased propogation delay. Why not use a case statement if you have a lot of possibilities to check – JonRB Oct 22 '17 at 23:19
• Just look under the "RTL view" after you've synthesized. It will show you how the compiler put it together. – Harry Svensson Oct 23 '17 at 8:58
• Contrary to what you might read below, a synthesis vendor can do anything which conforms to the simulation semantics of the language; their output will then, by definition, be correct, period. Having said that, when I taught this stuff I told students to expect a mux in one case and a priority encoder/chain in the other. – EML Nov 2 '17 at 14:31

## 2 Answers

No: if-else is sequential; case is concurrent. A single if followed by an else will be equivalent to a two input multiplexer. An if followed by if else statements is equivalent to a series of two input multiplexers like this: This is because the order you check the conditions of the if-else matters, i.e. you have priority.

A case statement, on the other hand is concurrent. Everything happens at the same time.

• I would just add a note that multiplexers themselves are not really a thing in an FPGA, LUTs are, so a schematic rendering multiplexers is not particularly diagnostic of what will be actually be done in terms of space utilisation on the FPGA fabric. Modern FPGAs often have 6 input LUTs so the above will in fact collapse to two LUTs in all probability. – Dan Mills Oct 23 '17 at 11:28
• @DanMills I agree in general. However, modern FPGAs can have as few as 4 inputs to their LUTs, e.g. MAX 10, Cyclone V. Additionally, it is good practice to write code that scales. Every code standard I’ve seen requires you to use cases where priority is not required. There is simply no need to use if-else in most cases. You also need to consider what happens when you change hardware or go for an ASIC implementation. – user110971 Oct 23 '17 at 11:43
• Case is not a concurrent statement... The concurrent version of case is a with/select "statement". The real name is selected signal assignment. It's a special case that if/elsif/else and case statements are inferred as multiplexers. It's only true if the same output is assigned in the branches or in the choices of a case statement. The difference between if and case is that if can create a priority logic, whereas choices in a case a equally weighted. – Paebbels Oct 23 '17 at 19:12

Neither statement necessarily maps to a multiplexer.

The HDL code is compiled to an intermediate form, which is optimized both by simplifying statements (e.g. eliminating tautologies) and by finding an optimal mapping to actual hardware that also takes propagation delays into account.

For example

if(input)
then
output <= '1';
end if;


will probably be optimized to output <= '1'; by the compiler, because the initial state is undefined, and a fixed value uses the least resources. Place&Route then takes this further and configures the output driver for the fixed value, so not even a single register is used.

Propagation delays need to be factored into your design where interfaces expect data to arrive on a particular clock edge, so it should have been part of the interface specification already.

For example, when I build an FIR filter, I also generate a valid signal that is set when steady state is reached after a reset, and a marker signal that is simply a delay on input markers. The obvious implementation generates valid $N_{taps}$ after reset, and the marker delay is $\frac{N_{taps}}{2}$, but that is not guaranteed in the interface. If I can get better pipelining behavior by adding more register stages in the middle, I can do so without breaking any connected components, and the logic is almost always simply optimized out when the compiler determines that the total delay is fixed at compile time.

• Given your example and no further assignment to output will result in a latch... Incomplete assignment descriptions result in memory elements. – Paebbels Oct 23 '17 at 3:58
• @Paebbels Only true in a combinational context. It's just a code snippet, it's pointless to nitpick. – jalalipop Oct 23 '17 at 12:09
• @Paebbels, yes, if you don't run the optimizer over the design. The optimizer will see that there is a latch with a state that is either '1' or 'U', simplifies that to '1', propagates the fixed value through to the output buffer and eliminates the latch, the table in front of it, and the interconnect to the output buffer. – Simon Richter Oct 23 '17 at 15:33
• @Paebbels, signals do not have default values in synthesis. Thet's why you need an explicit reset signal. – Simon Richter Oct 23 '17 at 20:07
• @Paebbels, tested on Quartus Prime 16.1, compiling for EP4CE22E22C8 with this test code: the RTL viewer shows 'output' being hardwired to 1h. This remains true even if I extend this with a local signal that is initialized to '0'. – Simon Richter Oct 24 '17 at 0:44