courses:system_design:vhdl_language_and_syntax:sequential_statements:case_statement

CASE Statement

case EXPRESSION is
 
 when VALUE_1 =>
       -- sequential statements
 
 when VALUE_2 | VALUE_3 =>
       -- sequential statements
 
 when VALUE_4 to VALUE_N =>
        -- sequential statements
 
 when others =>
       -- sequential statements
 
end case;
  • Choice options must not overlap
  • All choice options have to be covered
    • Single values
    • Value range
    • Selection of values (“|” means “or”)
    • “when others” covers all remaining choice options

Notes

While the priority of each branch is set by means of the query’s order in the if case, all branches are equal in priority when using a case statement. Therefore it is obvious that there must not be any overlaps. On the other hand, all possible values of the case expression must be covered. For covering all remaining, i.e. not yet covered, cases, the keyword ’others’ may be used.

entity CASE_STATEMENT is
  port (A, B, C, X         : in  integer range 0 to 15;
        Z                  : out integer range 0 to 15);
end CASE_STATEMENT;
 
architecture EXAMPLE of CASE_STATEMENT is
begin
  process (A, B, C, X)  -- combinational logic: complete sensitivity list
  begin
    case X is
      when 0 =>
         Z <= A;
      when 7 | 9 =>
         Z <= B;
      when 1 to 5 =>
         Z <= C;
      when others =>
         Z <= 0;        -- default case for the X values 6, 8 and 10 to 15 for complete CASE statement
    end case;
  end process;
end EXAMPLE;

Notes

The type of the expression in the head of the case statement has to match the type of the query values. Single values of expression can be grouped together with the ’|’ symbol, if the consecutive action is the same. Value ranges allow to cover even more choice options with relatively simple VHDL code.

Test Formatiertes VHDL hier: http://slexy.org/

entity CASE_STATEMENT is
  port (A, B, C, X         : in  integer range 0 to 15;
        Z                  : out integer range 0 to 15);
end CASE_STATEMENT;
 
architecture EXAMPLE of CASE_STATEMENT is
begin
  process (A, B, C, X)
  begin
                      -- no default signal assignment for Z +
    case X is
      when 0 =>
         Z <= A;
      when 7 | 9 =>
         Z <= B;
      when 1 to 5 =>
         Z <= C;
                      -- Z not assigned for all possible values of X +
      when others =>
                      -- "when others" present, but empty: ➔ a LATCH gets inferred, yuck!
    end case;
  end process;
end EXAMPLE;

Notes

If there is no default signal assignment or a signal is not assigned in every case, a latch is implied!

This especially happens, if the “when others ➜” statement is present (no synthesis complaint), but empty.

VHDL RTL-Synthesis Standard (IEEE 1076.6:1999)

8.8.8 Case statement

“If a signal or variable is assigned values in some branches of a case statement, but not in all cases, then level-sensitive storage elements may result (see 6.2). This is true only if the assignment does not occur under the control of a clock edge.”

entity RANGE_1 is
port (A,B: in integer range 0 to 15;
      C,X: in integer range 0 to 15;
      Z : out integer range 0 to 15);
end RANGE_1;
architecture EXAMPLE of RANGE_1 is
begin
   process (A, B, C, X)
   begin
      case X is
         when 0 =>
            Z <= A;
         when 7 | 9 =>
            Z <= B;
         when 1 to 5 =>
            Z <= C;
         when others =>
            Z <= 0;
      end case;
   end process;
end EXAMPLE;
entity RANGE_2 is
port(A,B: in bit_vector(3 downto 0);
     C,X: in bit_vector(3 downto 0);
     Z  : out bit_vector(3 downto 0));
end RANGE_2;
architecture EXAMPLE of RANGE_2 is
begin
   process (A, B, C, X)
   begin
      case X is
         when "0000" =>
            Z <= A;
         when "0111" | "1001" =>
            Z <= B;
         when "0001" to "0101"=> -- wrong
            Z <= C;
         when others =>
            Z <= 0;
      end case;
   end process;
end EXAMPLE;
The sequence of values is undefined for arrays

Notes

Ranges can be defined for data types with a fixed order, only, e.g. user defined enumerated types or integer values. This way, it can be decided whether one value is less than, equal to or greater than another value. For array types (e.g. a ’bit_vector’) there is no such order, i.e. the ’range “0000” to “0100”’ is undefined and therefore not admissible.


Chapters of System Design > VHDL Language and Syntax > Sequential Statements