运算符没有函数声明 [英] no function declarations for operator

查看:39
本文介绍了运算符没有函数声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到此错误消息:

testbench.vhd:16:22:运算符+"没有函数声明

testbench.vhd:16:22: no function declarations for operator "+"

在这一行:

    Z <= unsigned(X) + resize(unsigned(Y),X'length);

使用此代码:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity MCVE is
end entity MCVE;

architecture MCVE of MCVE is
  signal X, Z : std_logic_vector(15 downto 0);
  signal Y    : std_logic_vector(7 downto 0);
begin

  process    
  begin
    Z <= unsigned(X) + resize(unsigned(Y),X'length);
  end process;

end architecture MCVE;

https://www.edaplayground.com/x/2LBg

我不明白为什么.

推荐答案

虽然 Giwrgos Rizeakos 原创 question 是关于调整大小,关于运算符和函数重载可见性的问题和答案由来已久(这里没有运算符+"可见的函数声明).

While Giwrgos Rizeakos original question was on resizing, there's a long history of questions and answers on operator and function overload visibility (there no function declaration visible here for operator "+").

在搜索了这些问题和答案之后,这个答案试图提供一个问题和答案对,基于在解释流中提供权威参考,可以用来消除未来的重复问题.

After a search through those questions and answers this answer attempts to provide a question and answer pair that can be used to eliminated future duplicate questions based on providing authoritative references in an explanatory flow.

问题始于可见性:

12.3 可见性

在文本中给定位置出现标识符的含义由可见性规则定义,并且在重载声明的情况下,由重载规则定义.本节中考虑的标识符包括除保留字或表示预定义属性的属性指示符之外的任何标识符.本小节中考虑的地方是出现词法元素(例如标识符)的地方.本小节中考虑的重载声明是针对子程序和枚举文字的声明.

The meaning of the occurrence of an identifier at a given place in the text is defined by the visibility rules and also, in the case of overloaded declarations, by the overloading rules. The identifiers considered in this subclause include any identifier other than a reserved word or an attribute designator that denotes a predefined attribute. The places considered in this subclause are those where a lexical element (such as an identifier) occurs. The overloaded declarations considered in this subclause are those for subprograms and enumeration literals.

对于每个标识符和文本中的每个位置,可见性规则确定一组声明(使用此标识符),定义标识符出现的可能含义.如果根据可见性规则,声明定义了此事件的可能含义,则声明在文本中的给定位置可见.在确定此类声明的含义时会出现以下两种情况:

For each identifier and at each place in the text, the visibility rules determine a set of declarations (with this identifier) that define the possible meanings of an occurrence of the identifier. A declaration is said to be visible at a given place in the text when, according to the visibility rules, the declaration defines a possible meaning of this occurrence. The following two cases arise in determining the meaning of such a declaration:

——可见性规则最多确定一种可能的含义.在这种情况下,可见性规则足以确定定义标识符出现的含义的声明,或者在没有此类声明的情况下,确定在给定点的出现是不合法的.
— 可见性规则决定了不止一种可能的含义.在这种情况下,当且仅当给定上下文中的重载规则只能接受一个可见声明或所有可见声明表示相同的命名实体时,标识符的出现此时才是合法的.

— The visibility rules determine at most one possible meaning. In such a case, the visibility rules are sufficient to determine the declaration defining the meaning of the occurrence of the identifier, or in the absence of such a declaration, to determine that the occurrence is not legal at the given point.
— The visibility rules determine more than one possible meaning. In such a case, the occurrence of the identifier is legal at this point if and only if exactly one visible declaration is acceptable for the overloading rules in the given context or all visible declarations denote the same named entity.

涉及重载子程序:

4.5.2 运算符重载

指定符为运算符符号的函数声明用于重载运算符.运算符符号的字符序列应是 9.2 中定义的运算符类中的运算符之一.

The declaration of a function whose designator is an operator symbol is used to overload an operator. The sequence of characters of the operator symbol shall be one of the operators in the operator classes defined in 9.2.

一元运算符的子程序规范应具有单个参数,除非子程序规范是受保护类型的方法(参见 5.6.2).在后一种情况下,子程序规范应该没有参数.二元运算符的子程序规范应具有两个参数,除非子程序规范是受保护类型的方法,在这种情况下,子程序规范应具有单个参数.如果一个二元运算符的子程序规范有两个参数,对于这个运算符的每次使用,第一个参数与左操作数相关联,第二个参数与右操作数相关联.

The subprogram specification of a unary operator shall have a single parameter, unless the subprogram specification is a method (see 5.6.2) of a protected type. In this latter case, the subprogram specification shall have no parameters. The subprogram specification of a binary operator shall have two parameters, unless the subprogram specification is a method of a protected type, in which case, the subprogram specification shall have a single parameter. If the subprogram specification of a binary operator has two parameters, for each use of this operator, the first parameter is associated with the left operand, and the second parameter is associated with the right operand.

运算符重载定义为子程序并使用子程序重载规则:

Operator overloads are defined as subprograms and use subprogram overloading rules:

4.5 子程序重载

4.5.1 概述

当且仅当它们具有相同数量的参数,并且如果在每个参数位置对应的参数具有相同的基类型,则称两个形式参数列表具有相同的参数类型配置文件.当且仅当两个子程序具有相同的参数类型配置文件,并且如果两者都是具有相同结果基类型的函数或两者都不是函数,则称两个子程序具有相同的参数和结果类型配置文件.

Two formal parameter lists are said to have the same parameter type profile if and only if they have the same number of parameters, and if at each parameter position the corresponding parameters have the same base type. Two subprograms are said to have the same parameter and result type profile if and only if both have the same parameter type profile, and if either both are functions with the same result base type or neither of the two is a function.

作为 segue 子程序可以用签名来描述为速记:

As a segue subprograms can be described in terms of signatures as a shorthand:

4.5.3 签名

签名根据参数和结果类型配置文件区分重载子程序和重载枚举文字.签名可用于子程序实例化声明、属性名称、实体指示符或别名声明.

A signature distinguishes between overloaded subprograms and overloaded enumeration literals based on their parameter and result type profiles. A signature can be used in a subprogram instantiation declaration, attribute name, entity designator, or alias declaration.

signature ::= [ [ type_mark { , type_mark } ] [ return type_mark ] ]

signature ::= [ [ type_mark { , type_mark } ] [ return type_mark ] ]

(请注意,开头和结尾的括号是签名语法的一部分,并不表示产生式的整个右侧都是可选的.)签名被认为与参数和结果类型配置文件相匹配一个给定的子程序当且仅当以下所有条件都成立:

(Note that the initial and terminal brackets are part of the syntax of signatures and do not indicate that the entire right-hand side of the production is optional.) A signature is said to match the parameter and the result type profile of a given subprogram if, and only if, all of the following conditions hold:

——保留字返回之前的类型标记的数量,如果有的话,匹配子程序的形参数量.
— 在每个参数位置,签名的类型标记所表示的基类型与子程序对应的形参的基类型相同.
— 如果存在保留字return,则子程序为函数且签名中保留字后的类型标记的基类型与函数返回类型的基类型相同,或者保留字return为不存在并且子程序是一个过程.

— The number of type marks prior to the reserved word return, if any, matches the number of formal parameters of the subprogram.
— At each parameter position, the base type denoted by the type mark of the signature is the same as the base type of the corresponding formal parameter of the subprogram.
— If the reserved word return is present, the subprogram is a function and the base type of the type mark following the reserved word in the signature is the same as the base type of the return type of the function, or the reserved word return is absent and the subprogram is a procedure.

这里是示例:

Z <= unsigned(X) + resize(unsigned(Y),X'length);

可以用签名来描述.

Z 被声明为 std_logic_vector 类型."+" 的左操作数是 X,它是主题类型转换为无符号(9.3.6 中给出的规则,两种数组类型,相同的元素类型).右操作数是通过重载解析在包 numeric_std 中找到的带有 [unsigned, natural, return unsigned] 签名的调整大小的结果:

Z is declared as type std_logic_vector. The left operand to "+" is X which is subject type conversion to unsigned (rules given in 9.3.6, both array types, same element type). The right operand is the result of resize with a signature of [unsigned, natural, return unsigned] found in package numeric_std by overload resolution:

12.5 重载解析的上下文

重载是为名称、子程序和枚举文字定义的.

Overloading is defined for names, subprograms, and enumeration literals.

...

在考虑对完整上下文的可能解释时,唯一考虑的规则是语法规则、范围和可见性规则,以及如下形式的规则:

When considering possible interpretations of a complete context, the only rules considered are the syntax rules, the scope and visibility rules, and the rules of the form as follows:

a) 要求名称或表达式具有特定类型或与另一个名称或表达式具有相同类型的任何规则.
b) 任何要求名称或表达式的类型为某个类的类型的规则;类似地,任何要求特定类型为离散、整数、浮点、物理、通用或字符类型的规则.
...
e) 为解决重载子程序调用而给出的规则;用于通用表达式的隐式转换;用于解释具有通用类型边界的离散范围;用于解释前缀表示子程序的扩展名称;并且对于在子程序实例化声明中命名的子程序来表示未实例化的子程序.
...

a) Any rule that requires a name or expression to have a certain type or to have the same type as another name or expression.
b) Any rule that requires the type of a name or expression to be a type of a certain class; similarly, any rule that requires a certain type to be a discrete, integer, floating-point, physical, universal, or character type.
...
e) The rules given for the resolution of overloaded subprogram calls; for the implicit conversions of universal expressions; for the interpretation of discrete ranges with bounds having a universal type; for the interpretation of an expanded name whose prefix denotes a subprogram; and for a subprogram named in a subprogram instantiation declaration to denote an uninstantiated subprogram.
...

并且通过使用使 numeric_std 中的声明可见的 use 子句使函数可见:

And the function made visible through the use of use clause making the declarations in numeric_std visible:

12.4 使用子句

use 子句实现了通过选择可见的声明的直接可见性.

A use clause achieves direct visibility of declarations that are visible by selection.

对未找到函数声明的示例执行相同的重载决议.没有找到+"[unsigned, unsigned return std_logic_vector] 的函数声明,其中返回值必须匹配类型 std_logic_vector(上面的 a)规则).

The same overload resolution is performed on the example where no function declaration is found. No function declaration is found for "+" [unsigned, unsigned return std_logic_vector] where the return value must match type std_logic_vector (the a) rule above).

正如 Matthew Taylor 指出的,您可以通过类型转换为 std_logic_vector 来改变赋值右手表达式:

And as Matthew Taylor points out you can alter the assignment right hand expression by type conversion to std_logic_vector:

Z <= std_logic_vector(unsigned(X) + resize(unsigned(Y),X'length));

为什么不需要调整大小函数调用可以通过引用在 IEEE 包 numeric_std 中找到的+"`[unsigned, unsigned return unsigned] 的函数声明来权威地显示,(在 numeric_std-body.vhdl,在 1076-2008 downloads.z​​ip 这是 -2008 标准的一部分):

And why the resize function call is not needed can authoritatively be shown by referencing the function declaration for "+" `[unsigned, unsigned return unsigned] found in IEEE package numeric_std, (found in numeric_std-body.vhdl, in the 1076-2008 downloads.zip which is part of the -2008 standard):

  -- Id: A.3R
  function "+" (L : UNRESOLVED_UNSIGNED; R : STD_ULOGIC)
    return UNRESOLVED_UNSIGNED
  is
    variable XR : UNRESOLVED_UNSIGNED(L'length-1 downto 0) := (others => '0');
  begin
    XR(0) := R;
    return (L + XR);
  end function "+";

权威性地解释需要在 numeric_std.vhdl 中声明 unsigned (也可以在上述相同的 zip 文件中找到):

Interpreting that authoritatively requires the the declaration for unsigned in numeric_std.vhdl (also found in the same above zip file):

   type UNRESOLVED_UNSIGNED is array (NATURAL range <>) of STD_ULOGIC;


    subtype UNSIGNED is (resolved) UNRESOLVED_UNSIGNED;

这是 unresolved_unsigned 的子类型,提供元素解析函数名称.解析函数在标准中有解释:

which is a subtype of unresolved_unsigned providing an element resolution function name. Resolution functions are explained in the standard:

4.6 解析功能

解析函数是定义如何将给定信号的多个源的值解析为该信号的单个值的函数.解析函数与需要解析的信号相关联,方法是在信号声明或信号子类型的声明中包含解析函数的名称.具有关联解析函数的信号称为解析信号(见 6.4.2.3).

A resolution function is a function that defines how the values of multiple sources of a given signal are to be resolved into a single value for that signal. Resolution functions are associated with signals that require resolution by including the name of the resolution function in the declaration of the signal or in the declaration of the subtype of the signal. A signal with an associated resolution function is called a resolved signal (see 6.4.2.3).

并且子类型声明语法可能需要找到解析函数:

and the subtype declaration syntax can require a resolution function be found:

6.3 子类型声明

子类型声明::=
    子类型标识符是 subtype_indication ;

subtype_declaration ::=
    subtype identifier is subtype_indication ;

subtype_indication ::=
   [resolution_indication] type_mark [constraint]

subtype_indication ::=
    [ resolution_indication ] type_mark [ constraint ]

分辨率指示::=
   resolution_function_name |( element_resolution )

resolution_indication ::=
    resolution_function_name | ( element_resolution )

element_resolution ::= array_element_resolution |记录分辨率

element_resolution ::= array_element_resolution | record_resolution

在 std_logic_1164 包声明中可以找到已解析的函数(在上面相同的 zip 文件中,作为标准的一部分提供).

and function resolved is found in the the std_logic_1164 package declaration (in the same above zip file, provided as part of the standard).

分辨率是模拟的问题,请参阅 14.7 模型的执行,特别是 14.7.3 信号值的传播及其将分辨率应用于信号的子条款.

Resolution is a matter for simulation, see 14.7 Execution of a model, particularly 14.7.3 Propagation of signal values and it's sub-clauses where resolution is applied to signals.

(关于这里你会明白为什么会有很多不完整的答案,这些答案不会排除未来的问题.在标准中找到答案需要主题理解,它的主要受众是工具实现者和高级用户,其中 VHDL 语法和语义定义简洁,允许将其用作正式符号.)

(And about here you see why there can be a lot of incomplete answers that don't preclude future questions. Finding answers in the standard requires subject matter understanding and it's primary audiences are tool implementors and advanced users where VHDL syntax and semantics are defined concisely allowing it's use as a formal notation.)

这篇关于运算符没有函数声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆