ISAC: [Fwd: Vector concatenation issue] IR2126

From: Chuck Swart - MTI <cswart_at_.....>
Date: Wed Dec 19 2007 - 11:18:18 PST
I am forwarding an email which I sent to the customer outlining my
opinion on this issue. We can use this email and its follow up as
a starting point for analysis.

Chuck Swart

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


attached mail follows:


THE ISSUE:

A customer (Tim McBrayer from Mathworks) reports a problem with
our compiler on the following code:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY badconcat IS
    PORT ( in_0 : IN unsigned(1 DOWNTO 0);
           in_1 : IN unsigned(1 DOWNTO 0);
           in_2 : IN unsigned(1 DOWNTO 0);
           out1 : OUT std_logic_vector(5 DOWNTO 0));
END badconcat;

ARCHITECTURE arch OF badconcat IS
    TYPE bad_type IS ARRAY (0 to 99) of unsigned(1 to 1000);
BEGIN
    out1 <= std_logic_vector(in_0 & in_1 & in_2);
END arch;

Modelsim fails to compile this code, complaining about the type
conversion std_logic_vector(...).

Modelsim claims that there is an ambiguous type in trying to interpret
the operand type of the type conversion.

The two possible types and accompanying interpretations are:
 1) bad_type
    (in_0, in_1 and in_2 are interpreted as elements whose result type 
is bad_type,
     ie &(element_type of T, element-type of T) return T where T is 
"bad_type")

and 2) unsigned
    (in_0, in_1 and in_2 are interpreted as the resulting array type,
    ie &(T,T) return T where T is "unsigned")

Modelsim engineers argue that all visible operators are examined.  The
customer argues that the &(element,element) return T case should not
be considered because of two statements in the LRM.

Clause 7.3.5, "Type conversions", states:

"The type of the operand of a type conversion must be determinable
independent of the context (in particular, independent of the target
type)."

and Clause 7.2.4, "Adding operators", states for the  &(element,element) 
return T case:

"If both operands are of the same type and it is the element type of
some one-dimensional array type, the type of the result must be known
from the context and is this one-dimensional array type."

So who's right?

ANALYSIS:

RELEVANT REFERENCES TO "CONTEXT":

There are only a few places in which expressions are evaluated
"independent of context." They are:

3.2.1.1 "Index constraints and discrete ranges"
        
which states that if both bounds of the discrete range are not of type
universal integer, then both bounds must be of the same type and "this
type must be determined independently of the context, but using the
fact that the type must be discrete and that both bounds must have the
same type."

7.3.5 "Type conversions"

the area under discussion, described above.

8.8 "Case statement"

which states that the type of the case expression "must be
determinable independently 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."

No other references mention type determination independent of context.

Several parts of the LRM mention the use of context to determine meaning:
These include:
4.2 "Subtype declarations"
6.4 "Indexed names"
7.2.4 "Adding operators" (under discussion)
7.2.4 "Adding operators" (example of use of context to disambiguate 
concatenation)
7.3.2.2 "Array aggregates" (types and bounds of aggregates containing 
"others")
7.3.3 "Function calls"
7.3.4 "Qualified expressions" (use of qualified expression to 
disambiguate an ambiguous
      expression)
7.3.5 "Type conversions" (under discussion)
7.3.5 "Type conversions" (implicit conversion of universal operands)

Several clauses mention use of context with some restrictions and 
additional rules: These are:
7.3.1 "Literals" (Type of a string or bit string literal is determined 
by context
    without examining the literal itself, but using the fact that the 
type is
    a one-dimensional array of a character type)
7.3.2 "Array aggregates" (Type of an aggregate is determined by context
    without examining the aggregate itself but using the fact that the 
type is a composite type)
7.3.6 "Allocators" ("The type of the access value returned by an
    allocator must be determinable solely from the context, but using
    the fact that the value returned is of an access type having the
    named designated type.")
8.4 "Signal assignment statement" (Rules when the target is an aggregate 
similar to 7.3.2)
8.5 "Variable assignment statement" (Rules when the target is an 
aggregate similar to 7.3.2)

Of particular interest is clause 7.1, "Expressions", which states:

"The type of an expression depends only upon the types of its
operands and of the operators applied; for an overloaded operand or
operator, the determination of the operand type, or the identification
of the overloaded operator, depends on the context."

Finally, Clauses 10.3, "Visibility", and 10.5, "The context of overload 
resolution",
give detailed rules about determining the meaning of expressions and 
statements.

OUR INTERPRETATION:

To begin, lets confine our analysis to the simplified expression:

    ...std_logic_vector(in_0 & in_1)...

This deals with the essential problem. We will discuss the more
complicated expression later.

First, we believe that, in clause 7.2.4, "Adding operators", the mention
of context for the &(element,element) return T case is redundant. This
rule is already covered by the general rule in clause 7.1 given
above. It is not present in the original Ada Reference Manual. We
believe that its inclusion was intended to call attention to the
existing overload resolution rules, not to change the semantics of
overload resolution by adding a restriction.

Second, all three references in the LRM to determining types
independent of context give additional or specific rules which
indicate intent. In the case of type conversions, the statement that
the type of the operand must be determinable "independent of the
operand type" gives the intent of the restriction. This is intended to
imply, among other things, that you can't use the fact that the target
type is an array type to disambiguate the operand type (In Ada 95 this
particular restriction has been lifted.).

Our interpretation is that the rules of Clause 10.5 are applied within
the operand expression to determine the type of the expression, but
that no information in the context outside of the expression is used
in this determination. We believe that this is the only reasonable
interpretation, otherwise, there are no criteria to determine which
rules of 10.5 to apply. For example, 10.5 states "At such a place, all
visible declarations are considered." If this rule doesn't apply, then
how do we decide which declarations are to be considered?

Consequently, we believe that our interpretation is correct, that the
expression is ambiguous, and that a qualified expression must be used
to remove the ambiguity.

COMMENT ON THE ORIGINAL CASE OF TWO & OPERATORS

We believe that the original case presented by the customer is
ambiguous, even if you accept the customer's argument that the
element,element case does not apply to the expression:

    ...std_logic_vector(in_0 & in_1)...

In the original expression:

    ...std_logic_vector(in_0 & in_1 & in_2)...

the subexpression:

    in_0 & in_1

must be resolved, and there is ambiguity caused by two possible 
interpretations.

The first interpretation is

   &(element,element) return T

where T is "bad_type".

The second interpretation is

   &(T,T) return T

where T is "unsigned".


The first interpretation would cause the ...& in_2 operator to be
interpreted as the &(T,element) return T operator, where T is
"bad_logic", while the second interpretation would use the &(T,T) return
T operator, where T is "unsigned".


WHERE DO WE GO FROM HERE?

The submitter might not accept our interpretation. If so, then we
propose that either we or the customer submit an IR to the VHDL ISAC
to get this issue officially resolved. I will be happy to submit this
on behalf of the customer.

Chuck Swart
Received on Wed Dec 19 11:18:45 2007

This archive was generated by hypermail 2.1.8 : Wed Dec 19 2007 - 11:18:48 PST