Skip to main content
Logo image

Section 6.5 Case statements

An if-then-else construction is used for two-alternative choices or, nested, for hierarchical choices, where the second decision depends on the outcome of the first. There are many uses for multi-alternative choices, which are “flat” rather than hierarchical. For these, an if-then-else can be inelegant and inefficient. A pure truth table is another example of a multi-alternative flat choice. VHDL provides the case construction for these situations.
Here is a video that summarizes the use of the case statement. Watch it (up to 9:18) before or after you read this section.
For a working example, consider the four-bit binary coded decimal (BCD) to seven-segment decoder. The truth table is shown below:
x(3..0) segs(0...6)
\(0000\) \(1111110\)
\(0001\) \(0110000\)
\(0010\) \(1101101\)
\(0011\) \(1111001\)
\(0100\) \(0110011\)
\(0101\) \(1011011\)
\(0110\) \(1011111\)
\(0111\) \(1110000\)
\(1000\) \(1111111\)
\(1001\) \(1110011\)
Figure 6.5.1. Truth table for a BCD to seven-segment decoder. Outputs are high-true.
This is easily translated into VHDL with the case statement:
-- x is std_logic(3 downto 0)
-- segs is std_logic(0 to 6)

sevenseg: process(x)
begin
   case x is
      when x"0" =>   segs <= "1111110";   -- abcdefg
      when x"1" =>   segs <= "0110000";
      when x"2" =>   segs <= "1101101";
      when x"3" =>   segs <= "0110000";
      when x"4" =>   segs <= "0110000";
      when x"5" =>   segs <= "0110000";
      when x"6" =>   segs <= "0110000";
      when x"7" =>   segs <= "0110000";
      when x"8" =>   segs <= "0110000";
      when x"9" =>   segs <= "1110011";            
      when others => segs <= "1001001";   -- bar stack for invalid
   end case;
end process sevenseg;
Listing 6.5.2. VHDL model for a BCD to seven-segment decoder, implementing the truth table in Figure 6.5.1. The input values are written in hexadecimal, for readability. The last line, “when others”, covers the invalid cases, x"a" through x"f", making a stack of three horizontal bars, .
It is sometimes necessary to drive a seven-segment display with low-true signals, sinking current rather than sourcing. In this case, it is preferable to preserve the high-true nature of the table and simply invert segs before sending it to the output, e.g., with a statement like segs_l <= not(segs);.

Checkpoint 6.5.3.

Extend the truth table and VHDL model from BCD to hexadecimal, including the cases x"a" through x"f"
You now have what you need to model any combinational digital system with VHDL.

Exercises Exercises

1.

Use a case statement to write a model for a four-to-one multiplexer (two select bits, four inputs, one output).
Answer.
-- s is std_logic_vector(1 downto 0)

mux4to1: process(a, b, c, d, s)
begin
   case s is
      when x"0" =>   y <= a;   
      when x"1" =>   y <= b;
      when x"2" =>   y <= c;
      when x"3" =>   y <= d; 
      when others => null;       -- "null" means "do nothing"
   end case;
end process mux4to1;

2.

Use a case statement to write a model for a two-to-four one-hot decoder. For added challenge, include an enable (EN) input.
Hint.
It is OK to mix if-then-else and case statements
Answer.
-- x is std_logic_vector(1 downto 0)

dec2to4_en: process(x, en)
begin
    if en='0' then                      -- disabled, all off
       y <= "0000";
    else                                -- enabled
       case x is
          when x"0" =>   y <= "0001";   
          when x"1" =>   y <= "0010";
          when x"2" =>   y <= "0100";
          when x"3" =>   y <= "1000"; 
          when others => y <= "0000";   -- all off, if illegal input
       end case;
    end if;
end process dec2to4_en;