IEEE 200X Fast Track Change Proposal ID: FT-24 Proposer: John Ries email: johnr@model.com Status: Open Proposed: 04/20/04 Modified 02/16/05 03/21/05 04/15/05 Analyzed: Date Resolved: Date Enhancement Summary: Allow for don't care in case statements. Related issues: Relevant LRM section: 8.8 3.1 Enhancement Detail: --------------------------- The current case statement applies the implicit equality operator to select which choice is to be used. This limits the usefulness of case selectors of a 1-dimension arrays. Types like std_logic_vector that have don't cares require all possible choices to be explicitly listed. If the don't care was allowed in a choice and treated as "match anything", more compact choice lists can be generated for things like instruction decoders. For example: VARIABLE selectvar : std_logic_vector( 3 downto 0 ); ... CASE selectvar IS WHEN "0001" | "0011" | "0101" | "0111" | "1001" | "1011" | "1101" | "1111" => -- all choices have low bit set WHEN "0010" => -- more work WHEN "0000" => -- more work WHEN OTHERS => -- default action END CASE; If '-' denotes don't care then the above code could be written CASE? selectvar IS WHEN "---1" => -- all choices have low bit set WHEN "0010" => -- more work WHEN "0000" => -- more work WHEN OTHERS => -- default action END CASE?; There are several issues to consider if this enhancement is to be provided. Issues are 1) Currently choices are mutually exclusive, with don't care values choices could overlap. 2) If the don't care character is part of the element type, we need to worry about the selector containing the don't care value. If this is allowed then even if the choices are mutually exclusive, the selector could match multiple choices. 3) Current CASE statements must work as is. 4) A concurrent version of the don't care CASE statement must also be provided. 5) Is the don't care part of the element type or is it a Meta value. The Meta value would be nice, this would allow for don't cares for any type. The Meta value would have to be a character so it can be easily used in choices. But all characters are used for type CHARACTER so having the meta value that is a character would cause conflicts for at least the type CHARACTER. It would also cause confusion with types like std_ulogic which already have a don't care defined. It also has problems how do we get the don't care value into a literal. Currently, a literal must in valid for its type. It would also prevent having expression that produce the don't care value. If the don't care is a member of the type, then how do which know which member it is? We could restrict this feature to just std_logic_1164 and make '-' don't care by definition. This solution seems to restrictive. 6) Strength reduction. STD_LOGIC combine logic values with drive strengths as a result '1' and 'H' have the same logic value but a strong and resistive drive strength respectively. It would be nice if his drive strength could be ignore for comparison purposes. This does have a problem in when won specifies 'H' in a choice it is obvious that the logic value and the drive strength should match. If a '1' appears in the choice, should the drive strength, strong, match along with the logic value or not? I think we should do strength reduction in the comparison. Define a new operator "?=" [ TYPE, TYPE RETURN Boolean ] which has the same precedence as the "=" operator and is implicitly defined for the following types: boolean, bit, std_ulogic and one dimensional arrays of either boolean, bit or std_ulogic. For boolean, bit one-dimensional arrays of boolean, and one-dimensional arrays of bit, the ?= operator is the same as the implicit "=" operator. For std_ulogic the operator "?=" is defined in the following table. Right Left 'U' 'X' '0' '1' 'Z' ' W' 'L' 'H' '-' 'U' U U U U U U U U 1 'X' U X X X X X X X 1 '0' U X 1 0 X X 1 0 1 '1' U X 0 1 X X 0 1 1 'Z' U X X X X X X X 1 'W' U X X X X X X X 1 'L' U X 1 0 X X 1 0 1 'H' U X 0 1 X X 0 1 1 '-' 1 1 1 1 1 1 1 1 1 For vector operands, the left and right operands must be the same length and the scalar "?=" operand is applied element-wise and the results are ANDed together using the AND function symantics defined in ieee.std_logic_1164. If the ?? is defined the CASE? should be considered a context to which the ?? is applied. It should be considered an error if the select expression type is std_ulogic or a vector of std_ulogic and the ?? operator defined in ieee.std_logic is not visible. The CASE? is a sequential statement defined as follows case?_statement ::= [case?_label :] CASE? expression IS case?_statement_alternative { case?_statement_alternative} END CASE? [ case?_label]; case?_alternative ::= when choices => sequence_of_statements In the case?_statement, to match is defined as the implicit operator "?=" returns TRUE the two items in question. Ranges are not allowed for choices in case? statements. The expression must be of a bit or ieee.std_logic_1164.std_logic type, or a one-dimensional array of these types. The base type of the expression must have the implicit "?=" operator defined. This type must be determinable independent of the context in which the expression occurs, but using the fact that the expression must be of a discrete type or a one-dimensional character array type. Each choice in a CASE? statement alternative must be of the same type as the expression; the list of choices specifies for which values of the expression the alternative is chosen. If the expression is of type bit or a one-dimensional array of bit, the CASE? is treated as if it was CASE statement. If the expession is of type std_ulogic or a one-dimensional array of std_ulogic the following restrictions apply. It is an error if the expression is of type std_ulogic and has the value '-' or is an one-dimensional array of std_ulogic and one or more elements is '-'. When the expression is a one-dimensional array, then it must be an expression given in the list in section 8.8 for case statement expressions. If the expression is a locally static scalar subtype or and one-dimensional array of std_ulogic, then each value of the subtype, excluding values that contain the '-' must match at most one non-OTHERS case?_statement alternative. The match is determine using the ?= operator. If the expression is a one-dimensional character array type, then the expression must be one of the following: -- The name of an object whose subtype is locally static -- An indexed name whose prefix is one of the members of the list and whose indexing expressions are locally static expressions -- A slice name whose prefix is one of the members of this list and whose discrete range is a locally static discrete range -- A function call whose return type_mark denotes a locally static subtype -- A qualified expression or type conversion whose type mark denotes a locally static subtype. -- a expression in parens that is in this list. ( This should also be added to section 8.8) In such a case, each choice appearing in any of the CASE? statement alternatives must be a locally static expression who's value is of the same length as that of the case select expression. It is an error if the element subtype of the one-dimensional character array type is not a locally static subtype. For other forms of expression, each value of the (base)type, excluding those values containing the don't care value, of the expression must be match one and only one choice using the implicit "?=" operator. Each choice, except the OTHERS choice, must match at least valid value of the expression. The simple expression given as choices in a case statement must be locally static. The choice others is only allowed for the last alternative and as its only choice; The others choice stands for all values (possibly none) not given in the choices of previous alternatives. An element simple name (see 7.3.2) is not allowed as a choice of a CASE? statement. The restrictions that the case expression cannot contian '-' and that each choice, excluding the the others choice, must be not match any other choice when compared with the ?= operator, is sufficient to insure that at most one choice will be selected. To prove this, assume the following. That A, B, and C be are std_logic_vectors( N-1 downto 0). A is the case expression. B and C are two choice expressions. For more than one choice to be selected there must values of A, B, and C such that (B ?= C) /= '1', (A ?= B) = '1' and (A ?= C) = '1'. For A ?= B to be '1', then each element (A(i) ?= B(i) ) = '1'. If A(i) has a value of 'U', 'X', 'W', or 'Z' then B(i) must be '-'. If A(i) is '0' or 'L' then B(i) must be '0', 'L', or '-'. Similarly if A(i) is '1' or 'H' then B(i) must be '1', 'H', or '-'. Similarly the possible values of C(i). So for each element we have the following cases value of A(i) B(i) C(i) 'U','X', 'W', 'Z' '-' '-' '0', 'L' '0', 'L', '-' '0', 'L', '-' '1', 'H' '1', 'H', '-' '1', 'H', '-' For each possible value of A(i) the expression (B(i) ?= C(i) ) = '1', is also true. As a result, (B ?= C) = '1' which conflicts with the requirement that (B(i) ?= C(i)) /= '1'. Therefore there exists no values for A, B, C such that (B ?= C) /= '1', (A ?= B) = '1' and (A ?= C) = '1'. Analysis: ---------------------------- [To be performed by the 200X Fast Track Working Group] Resolution: ---------------------------- [To be performed by the 200X Fast Track Working Group]