2

请注意,这个问题不是关于如何更改下面的代码以使其工作;相反,我正在寻找一些关于为什么编译器会发现这个赋值模棱两可的见解:

entity assignment_to_aggregates is
end;

architecture example of assignment_to_aggregates is
    type vowel_type is (a, e, i, o, u);
    type consonant_type is (b, c, d, f, g);
    type vowel_consonant_pair is record
        vowel: vowel_type;
        consonant: consonant_type;
    end record;

    signal my_vowel: vowel_type;
    signal my_consonant: consonant_type;
begin
    (my_vowel, my_consonant) <= (a, b); -- Doesn't work: "Ambiguous types in signal assignment statement."
end;

我已经使用 Modelsim Altera 10.1b 和 GHDL 0.29.1 对其进行了测试,我看到以下错误消息:

VCOM: (vcom-1349) Ambiguous types in signal assignment statement
    Possible target types are:
        vowel_consonant_pair
        ieee.std_logic_1164.STD_ULOGIC_VECTOR
        std.STANDARD.TIME_VECTOR
        std.STANDARD.REAL_VECTOR
        std.STANDARD.INTEGER_VECTOR
        std.STANDARD.BIT_VECTOR
        std.STANDARD.BOOLEAN_VECTOR
        std.STANDARD.STRING

GHDL: type of waveform is unknown, use type qualifier

当然,如果我明确声明一个新类型(示例代码中的vowel_consonant_pair)并使用类型限定,它可以正常工作:

(my_vowel, my_consonant) <= vowel_consonant_pair'(a, b); -- Works fine

但是,如果绝对没有其他类型可以匹配赋值右侧的聚合,为什么这是必要的?这是工具问题,还是 VHDL 语义问题?如果是后者,有人可以提供 LRM 参考吗?

4

1 回答 1

0

Quoted from my answer to the previous question:

IEEE Std 1076-1993, 8.4 Signal assignment statement (see -2008, 10.5/10.5.2.1):

If the target of the signal assignment statement is in the form of an aggregate, then the type of the aggregate must be determinable from the context, excluding the aggregate itself but including the fact that the type of the aggregate must be a composite type.

Add a bit more:

-1993, 0.2 Structure and terminology of this document (see -2008, 1.3/1.3.1:

Additionally, the word "must" is used to indicate mandatory weight. This word is preferred over the more common "shall," as "must" denotes a different meaning to different readers of this standard.

It's a semantic restriction, 'must' carries a mandatory weight, a condition that must be met will otherwise generate and error in VHDL. The type of the aggregate isn't known without qualification. Note 'that' must has been supplanted by 'shall' in the 2008 version of the standard.

The type in question here is of the target (the left hand side). We're bound by to the requirement in the section on sequential signal assignment for the concurrent signal assignment statement by the first sentence of the section on concurrent signal assignment, IEEE Std 1076-2008:

11.6 Concurrent signal assignment statements

A concurrent signal assignment statement represents an equivalent process statement that assigns values to signals.

(Also found in -1993, 9.5).

Type is generally carried as an attribute on a name, but the aggregate isn't a named object. It's possible to get the type from the right hand side except it's an aggregate too:

(my_vowel, my_consonant) <= (a, b);

Nick Gasson's VHDL analyzer/simulator nvc points a little more elegantly to where to fix the problem:

nvc -a assignment_to_aggregate.vhdl  
** Error: no composite type in context
      File assignment_to_aggregate.vhdl, Line 11  
        (my_vowel, my_consonant) <= (a,b);  
                                    ^^^^^

(Following a fix for an elaboration 'crash' caused by a missing semantic check found using a previous stackoverflow VHDL question).

How can you type the right hand side?

From IEEE Std 1076-1993:

7.3.4 Qualified expressions

A qualified expression is a basic operation (see the introduction to Section 3)that is used to explicitly state the type, and possibly the subtype, of an operand that is an expression or an aggregate.

 qualified_expression ::=
        type_mark ' ( expression )
      | type_mark ' aggregate

The operand must have the same type as the base type of the type mark. The value of a qualified expression is the value of the operand. The evaluation of a qualified expression evaluates the operand and checks that its value belongs to the subtype denoted by the type mark.

NOTE--Whenever the type of an enumeration literal or aggregate is not known from the context, a qualified expression can be used to state the type explicitly.

There isn't a glossary definition of 'context' in any of the VHDL standard versions. A working definition might include the notion that the declaration for something is visible, which isn't the case for the type of an aggregate without qualification.

I wrote the answer to the previous question and I introduced the record type declaration specifically to address the lack of ability to decorate the aggregate with a type mark in a qualified expression. Note that there is no subtype (signal and) declared as a vowel_consonant_pair record. The type declaration was needed, not an actual record.

Also note I submitted a bug on ghdl-0.31 which has been fixed source tree but there hasn't been an actual release since - ghdl barfs when it can't discern the type of an aggregate. A newer version of ghdl won't crash if you don't qualify the expression.

Questions on stackoverflow generally make a wonderful contribution to improving open source VHDL tools.

I keep the standards handy and usually am able to cite chapter and verse. It can be a lot of work, there's very little you can't find out about VHDL by a thorough reading of the standard although there isn't a permuted index and you have to be inculcated in the terminology to understand the significance of what you read.

Like the answer to your current question a reference in the standard can lead to another part of the standard.

The comp.lang.vhdl FAQ quoted by Jim Lewis in a recent answer is a wonderful reference but sometimes lacks authoritative emphasis, using references to the -1993 standard sparingly.

See the FAQ, 4.2.18 How to Resolve Type Ambiguities in Expressions.

Your confusion seems to stem from the Modelsim error messages suggesting 'possible' types needed to resolve ambiguity. Note the first sentence in the 4.2.18:

VHDL is a strongly typed language. Hence, the compiler does not perform any implicit type conversions or attempt to "guess" the type of an expression.

And an aggregate is an expression (See 7.3.2/9.3.3 Aggregates, -1993/-2008).

Most of the possible type declarations provided by the vcom errror message are not accurate for the aggregate which is comprised of two disparate type elements - a is an enumeration name for a value of vowel_type and b is an enumeration for a value of consonant_type.

The types provided with the vcom error appear to be all the composite types made visible by local declaration (vowel_consonant_pair) or context clause (std_ulogic_vector, real_vector, integer_vector, bit_vector, boolean_vector, string, collectively found in ieee.std_logic_1164 or std.standard).

Of that bunch only one would be valid (vowel_consonant_pair). Notice the VHDL analyzer didn't guess, instead requiring the correct type to be made available from context as an object decoration (type qualification) as a result of a semantic rule (Signal assignment statement 8.4/10.5.2.1, "...the type of the aggregate must be determinable from the context, excluding the aggregate itself but including the fact that the type of the aggregate must be a composite type"). The rule giving the list of possible candidates, available composite types while disallowing guessing ("excluding the aggregate itself").

于 2014-06-10T22:51:51.887 回答