[vhdl-200x-ft] proof of mutual exclusive choices in case?

From: John Ries <johnr_at_.....>
Date: Mon Apr 18 2005 - 09:43:10 PDT
FT24, allowing for don't cares in case statements has been updated to
provide a proof showing that only one choice of a CASE? can be selected
at a time.

Regards,
   John

-- 
-- 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
              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]
Received on Mon Apr 18 09:48:19 2005

This archive was generated by hypermail 2.1.8 : Mon Apr 18 2005 - 09:48:34 PDT