IEEE 200X Fast Track Change Proposal ID: FT- Proposer: John Ries email: johnr@model.com Status: Open Proposed: 04/20/04 Analyzed: Date Resolved: Date Enhancement Summary: Allow for don't care in case statements. Related issues: Relevant LRM section: 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 that all possible choices to be explicitly list. If the don't care was allowed in a choice and treated as match anything, then more compact choice list can be generator for thing 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 issue to consider if this enhancement is to be provide. 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 provide. 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 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. Having don't care as an element type how do we know which character this is. Restricting this feature to just std_logic_1164 seams to restrictive. Here is my proposal. Make the attribute named DONT_CARE special. Define a new operator "?=" which is equivalence with don't cares. Define two new statements, one sequential, CASE SELECT, and one concurrent, WITH CASE SELECT. The attribute DONT_CARE is declared in std.standard as ATTRIBUTE DONT_CARE IS CHARACTER; Then in the scope that a type is declared, then the following attribute specification would occur ATTRIBUTE DONT_CARE OF :TYPE is ; All though is a CHARACTER it must also be a valid character value for . Because the dont care character must exist in the type values for , the types BIT and BOOLEAN can't have a don't care character. When this attribute is define then the operator "?=" is implicitly declared for that type. If is also implicitly declared for array of this element type. The "?=" operator takes to operands and returns a BOOLEAN value. This operand is added to the relational operators. In the scalar case, "?=" is defined FUNCTION "?=" ( ARG1: T, ARG2: T) RETURN BOOLEAN IS CONSTANT DSTRING: STRING(1 to 1) := ( 1=>T'DONT_CARE); CONSTANT DONT_CARE_VALUE : T := T'VALUE( DSTRING); BEGIN IF ( T'POS( ARG1) = T'POS(ARG2)) OR ( DONT_CARE_VALUE = ARG1) OR ( DONT_CARE_VALUE = ARG2) THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END IF; For array types, "?=" is defined as follows FUNCTION "?=" ( ARG1: TV, ARG2: TV ) RETURN BOOLEAN IS -- bounds are not correct because 1 may not be valid -- but I don't know how to get rid of this problem ALIAS L1: TV(1 to ARG1'LENGTH) IS ARG1; ALIAS L2: TV(1 to ARG2'LENGTH) IS ARG2; BEGIN IF ( L1'LENGTH != L2'LENGTH) THEN RETURN FALSE; END IF; FOR i IN L1'RANGE LOOP IF NOT (L1(i) == L2(i)) THEN RETURN FALSE; END IF; END LOOP; RETURN TRUE; END; The CASE SELECT is a sequential statement defined as follows case_select_statement :::= [case_select_label :] CASE SELECT expression IS case_select_statement_alternative { case_select_statement_alternative} END CASE [ case_select_label]; case_select_alternative ::= when choices => sequence_of_statements In the case_select_statement, to match is defined as the implicit operator "?=" returns TRUE the two items in question. Ranges are not allow for choices. The expression must be of a discrete type, or of a one-dimensional array type whose element base type is a character type. 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 select 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. It is an error if the expression contains the character selected by the DONT_CARE attribute. If the expression is the name of object whose subtype is locally static, whether a scalar type or an array type, then each value, excluding value that contain the "dont care" value, of the subtype must be represented match one and only one case_select_statement alternative using the implicit "?=" operator. A case_select_statement_alternative choice must match at least one valid value that the expression can have, unless the choice is OTHERS. This rule is likewise applied if the expression is a qualified expression or type conversion whose type mark denotes a locally static subtype, of if the expression is a call to a function whose return type mark denotes a locally static subtype. If the expression is of 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. In such a case, each choice appearing in any of the case select 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; it 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 select statement alternative. If a label appears at the end of case select statement, it must repeat the case select label. In short, the case select alternative, with the exception of the OTHERS choice are mutually exclusive under the "?=" operator. If the expression contains the dont care character, then an error occurs. The WITH CASE SELECT is defined as concurrent_signal_assignment_statement ::= [ label :] [ POSTPONED] conditional_signal_assignment | [ label :] [POSTPONED] selected_signal_assignment | [ label :] [POSTPONED] case_selected_signal_assignment case_select_signal_assignment ::= WITH expression CASE SELECT target <= options selected waveform; select_waveform ::= { waveform WHEN choices, } waveform WHEN choices In package ieee.std_logic_1164 add the attribute ATTRIBUTE DONT_CARE OF std_ulogic: TYPE IS '-'; Analysis: ---------------------------- [To be performed by the 200X Fast Track Working Group] Resolution: ---------------------------- [To be performed by the 200X Fast Track Working Group]