VHDL Conditional Statement
VHDL is a Hardware Description Language that is used to describe at a high level of abstraction a digital circuit in an FPGA or ASIC.
When we need to perform a choice or selection between two or more choices, we can use the VHDL conditional statement.
Since the VHDL is a concurrent language, it provides two different solutions to implement a conditional statement:
- sequential conditional statement
- concurrent conditional statement
Sequential conditional statement
The sequential conditional statement can be used in
- process
- subprogram
The BNF of a conditional statement is:
if_statement ::= if condition then sequence_of_statements { elsif condition then sequence_of_statements } [ else sequence_of_statements ] end if ;
if boolean-expr-1 then sequential-statements; elsif boolean-expr-2 then sequential-statements ; elsif boolean-expr-3 then sequential-statements; else sequential-statements; end if;
Concurrent conditional statement
The concurrent conditional statement can be used in the architecture concurrent section, i.e. between the “begin-end” section of the VHDL architecture definition.
The BNF of the concurrent conditional statement is:
conditional_signal_assignment ::= target <= conditional_waveforms ; conditional_waveforms ::= { waveform when condition else } waveform Example: s <= waveform_1 when condition_1 else waveform_2 when condition_2 else else waveform_3 when condition_3 else ... waveform_n;
Conditional Statement Sequential vs Concurrent
You can use either sequential or concurrent conditional statement. It’s up to you.
There is a total equivalence between the VHDL “if-then-else” sequential statement and “when-else” statement.
Here below we can see the same circuit described using VHDL “if-then-else” or “when-else” syntax.
When you use a conditional statement, you must pay attention to the final hardware implementation.
A conditional statement can be translated into a MUX or a comparator or a huge amount of combinatorial logic.
The hardware architecture derived from a single line containing an “IF” or a “when” can be translated into something that can slow down your design or make your design not realizable.
VHDL example of Conditional Statement
Let’s see two typical example of VHDL conditional statement implementing a MUX and an unsigned comparator
Here below the VHDL code for a 2-way mux. The data input bus is a bus of N-bit defined in the generic.
As clear if the number of bits is small, the hardware required for the 2-way mux implementation is relatively small and you can use the mux output to feed your logic without any problem.
library ieee ; use ieee.std_logic_1164.all; entity mux_2 is generic( G_N integer:= 8); port( a : in std_logic_vector(G_N-1 downto 0); b : in std_logic_vector(G_N-1 downto 0); s : in std_logic; m : out std_logic_vector(G_N-1 downto 0)); end mux_2; architecture rtl of mux_2 is begin p_mux : process(a,b,s) begin if(s='0') then m <= a ; else m <= b ; end if; end process p_mux; end rtl;
2-WAY MUX VHDL code sequential implementation
library ieee ; use ieee.std_logic_1164.all; entity mux_2 is generic( G_N integer:= 8); port( a : in std_logic_vector(G_N-1 downto 0); b : in std_logic_vector(G_N-1 downto 0); s : in std_logic; m : out std_logic_vector(G_N-1 downto 0)); end mux_2; architecture rtl of mux_2 is begin m <= a when(s='0') else b; end rtl;
2-WAY MUX VHDL code concurrent implementation
If the number of bits G_N is going to become huge, the 2-way mux could, eventually, not implementable in your hardware.
The VHDL code for 2-way mux is always the same: a few lines of VHDL code can implement a small 2-way mux or a very large 2-way mux.
In this second example, we implement a VHDL signed comparator that is used to wrap around an unsigned counter.
Also, in this case, depending on the number of bit of the signed comparator, the circuit could be not implementable depending on your hardware.
Here below the sequential implementation of VHDL for a signed comparator:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity signed_comparator is generic( G_N : integer:= 8); port ( i_data_a : in std_logic_vector(G_N-1 downto 0); i_data_b : in std_logic_vector(G_N-1 downto 0); o_a_gt_b : out std_logic); end signed_comparator; architecture rtl of signed_comparator is begin p_signed_comparator : process(i_data_a,i_data_b) begin if(signed(i_data_a)>signed(i_data_b)) then o_a_gt_b <= '1'; else o_a_gt_b <= '0'; end if; end process p_signed_comparator; end rtl;
Here below the concurrent implementation of VHDL for a signed comparator:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity signed_comparator is generic( G_N : integer:= 8); port ( i_data_a : in std_logic_vector(G_N-1 downto 0); i_data_b : in std_logic_vector(G_N-1 downto 0); o_a_gt_b : out std_logic); end signed_comparator; architecture rtl of signed_comparator is begin o_a_gt_b <= '1' when (signed(i_data_a) > signed(i_data_b)) else '0'; end rtl;
For instance, you can implement a 4-bit signed comparator or a 2048-bit signed comparator just set the number of bit in the “G_N” constant.
Conclusion
Every time you write a VHDL code that needs to be implemented in a real hardware like FPGA or ASIC, you should pay attention to the final hardware implementation. In the two example above, we saw that the same simple VHDL code for a 2-way mux or unsigned counter can result in an impossible to implement hardware structures, so every time you write a single VHDL code,
Think Hardware
References:
[1] RTL HARDWARE DESIGN USING VHDL Coding for Efficiency, Portability, and Scalability
[2] VHDL Programming by Example 4th Ed Douglas – Perry
[4] http://standards.ieee.org/findstds/standard/1076-1993.html
[5] https://en.wikipedia.org/wiki/VHDL
Hello,
I’ve not understood why the sequential and concurrent statement may lead to different hardwares in both examples.
Could you elaborate one of the 2 examples in order to show why one of the implementation may lead to a design which can not be implemented in hardware whereas the other implementation can be implemented ?
Best Regards,
Thierry