[vhdl-200x-ft] FT-24 Don't care is case statements has been updated.

From: John Ries <johnr_at_.....>
Date: Fri Mar 11 2005 - 10:19:15 PST
The proposal to allow for a case statement that correctly
handles don't cares has been updated to reflect
that strength reduction will be done, i.e. '1' = 'H'.
Also text was added to show that restrict the
select expression to not contain don't cares is
sufficient to insure mutually exclusive choices.


-- 
-- mailto: johnr@model.com     phone: (503)685-0864
--   http://www.model.com        fax: (503)685-0921
--


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
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: bit, std_ulogic and one dimensional arrays of either
bit or std_ulogic.  For bit 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'      F     F     F     F     F     F     F     F     F
'X'      F     F     F     F     F     F     F     F     F
'0'      F     F     T     F     F     F     T     F     T
'1'      F     F     F     T     F     F     F     T     T
'Z'      F     F     F     F     F     F     F     F     F
'W'      F     F     F     F     F     F     F     F     F
'L'      F     F     T     F     F     F     T     F     T
'H'      F     F     F     T     F     F     F     T     T
'-'      F     F     T     T     F     F     T     T     T

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.

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; 
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? statement alternative.

If a label appears at the end of CASE? statement, it must repeat the
CASE? 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  SELECT? is defined as

concurrent_signal_assignment_statement ::=
  [ label :] [ POSTPONED] conditional_signal_assignment
 | [ label :] [POSTPONED] selected_signal_assignment
 | [ label :] [POSTPONED] select?ed_signal_assignment

select?_signal_assignment ::=
  WITH expression SELECT?
     target <= options selected waveform;

select_waveform ::=
   { waveform WHEN choices, }
     waveform WHEN choices


Note there are other Fasttrack items that change restrictions on case statements, if they
are accepted then this proposal should be updated to match.

Proof that if we disallow - in the select expression add do not allow any choices
to return true when compared using the ?=, then the select expression cannot
match more than one choice.  Make A the select expression, B and C to choices.
By definition (B ?= C) = FALSE.  Then if  (A ?= B ) = TRUE can 
(A ?= C) = TRUE also be valid.  Assume that A, B, C all have
the same length and same index constraints.  For A?=B to
be true the A(i)?=B(i) must be true for all values of i.
The same is true for B?=C and A?=C.  For A(i) ?= B(i) to be true
then B(i) must either be A(i) or '-'.  If A(i)?=C(i) is also
to be true then C(i) must either A(i) or '-'.  If we do
B(i) ?= C(i),  this must be 
  A(i) ?= A(i)
  A(i) ?= '-'
  '-'  ?= A(i)
  '-'  ?= '-'
For all values of i.  Since all four case are true then
B?=C must be true which is in conflict with our condition that
B?=C must be false.
Note we ignore strength reduction to simplify the proof but it doesn't
effect the proofs.

Analysis:
----------------------------
[To be performed by the 200X Fast Track Working Group]


Resolution:
----------------------------
[To be performed by the 200X Fast Track Working Group]
Received on Fri Mar 11 10:23:51 2005

This archive was generated by hypermail 2.1.8 : Fri Mar 11 2005 - 10:23:53 PST