请注意,这个问题不是关于如何更改下面的代码以使其工作;相反,我正在寻找一些有关编译器为什么会发现这个赋值模糊不清的见解:
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参考吗?
答案 0 :(得分:0)
引述我对上一个问题的回答:
IEEE Std 1076-1993,8.4信号分配声明(见-2008,10.5 / 10.5.2.1):
如果信号赋值语句的目标是a的形式 聚合,那么聚合的类型必须是可以确定的 上下文,不包括聚合本身,但包括事实 聚合的类型必须是复合类型。
再添加一点:
-1993,0.2本文件的结构和术语(见-2008,1.3 / 1.3.1:
此外,单词&#34;必须&#34;用于表示强制性重量。 这个词比更常见的词更受欢迎&#34; shall,&#34;作为&#34;必须&#34;表示 与本标准的不同读者有不同的含义。
这是一个语义限制,必须&#39;带有强制权重,否则必须满足的条件会产生VHDL错误。没有资格,集合的类型是不可知的。注意&#39;那个&#39;必须被“应该”取代。在2008版本的标准中。
这里讨论的类型是目标(左侧)。我们受并发信号分配部分第一句关于并发信号分配语句的顺序信号分配部分的要求的约束,IEEE Std 1076-2008:
11.6并发信号分配声明
并发信号赋值语句表示等效语句 将值赋给信号的进程语句。
(也见于-1993,9.5)。
类型通常作为名称的属性携带,但聚合不是命名对象。可以从右侧获取类型,除非它也是聚合类型:
(my_vowel, my_consonant) <= (a, b);
Nick Gasson的VHDL分析器/模拟器nvc更优雅地指出了解决问题的方法:
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);
^^^^^
(修复了由于使用先前的stackoverflow VHDL问题找到的缺少语义检查而导致的详细说明&#39;崩溃)。
你怎么键入右手边?
来自IEEE Std 1076-1993:
7.3.4合格的表达
限定表达式是一项基本操作(参见介绍) 第3节)用于明确说明类型,可能还有 子类型,作为表达式或聚合的操作数。
qualified_expression ::= type_mark ' ( expression ) | type_mark ' aggregate
操作数必须与类型标记的基本类型具有相同的类型。 限定表达式的值是操作数的值。该 对限定表达式的求值将评估操作数并进行检查 它的值属于类型标记所表示的子类型。
注 - 每当枚举文字或聚合的类型不是时 从上下文中可以看出,可以使用限定表达式来表示 明确的类型。
没有关于&#39; context&#39;的词汇表定义。在任何VHDL标准版本中。 一个有效的定义可能包括某些事物的声明是可见的概念,而对于没有限定条件的聚合类型则不是这样。
我在前一个问题上写了answer,并且我专门介绍了记录类型声明,以解决在限定表达式中用类型标记装饰聚合的能力不足的问题。请注意,没有声明为vowel_consonant_pair记录的子类型(signal和)。需要类型声明,而不是实际记录。
另请注意,我提交了一个关于ghdl-0.31的错误,该错误已经修复了源代码树,但自从ghdl barfs when it can't discern the type of an aggregate以来还没有实际发布。如果你没有对表达式进行限定,那么新版本的ghdl就不会崩溃。
有关stackoverflow的问题通常会对改进开源VHDL工具做出很大贡献。
我保持标准方便,通常能够引用章节和诗句。这可能是一项很多的工作,虽然没有排他性的索引,但你很难通过彻底阅读标准来了解VHDL,你必须在术语中灌输了解你所读内容的重要性。
与您当前问题的答案一样,标准中的参考可能会导致标准的另一部分。
Jim Lewis在最近的回答中引用的comp.lang.vhdl FAQ是一个很好的参考,但有时缺乏权威的重点,谨慎使用-1993标准。
请参阅常见问题解答4.2.18 How to Resolve Type Ambiguities in Expressions。
您的困惑似乎源于Modelsim错误消息,表明可能的&#39;解决歧义所需的类型。请注意4.2.18中的第一句话:
VHDL是一种强类型语言。因此,编译器没有 执行任何隐式类型转换或尝试&#34;猜测&#34;类型 表达。
聚合是一个表达式(见7.3.2 / 9.3.3聚合,-1993 / -2008)。
vcom errror消息提供的大多数可能的类型声明对于由两个完全不同的类型元素组成的聚合不准确 - a是vowel_type值的枚举名称,b是consonant_type值的枚举
vcom错误提供的类型似乎是通过本地声明(vowel_consonant_pair)或上下文子句(std_ulogic_vector,real_vector,integer_vector,bit_vector,boolean_vector,string,在ieee.std_logic_1164或std中共同找到)可见的所有复合类型。标准)。
在那一堆中只有一个是有效的(vowel_consonant_pair)。请注意VHDL分析器没有猜测,而是要求从上下文中将正确的类型作为对象修饰(类型限定)作为语义规则的结果(信号赋值语句8.4 / 10.5.2.1,&#34) ; ...聚合的类型必须可以从上下文中确定,不包括聚合本身,但包括聚合的类型必须是复合类型的事实&#34;)。规则列出了可能的候选人,可用的复合类型,但不允许猜测(&#34;排除聚合本身&#34;)。