====== CASE Statement ====== ===== Fundamentals ===== 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. ===== CASE Statement: Example ===== 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/ ===== CASE Statement: Latch! ===== 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. **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." ===== Defining Ranges ===== | 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.