不能将实数和整数相乘 TL; DR 详细信息

问题描述

我在测试台中使用此代码,该代码可以按预期工作:

std_logic_vector(to_unsigned(integer(0.603205*(2**16)),16))

我想用同一文件中定义的功能替换它:

function convert_mult(mult : real) return std_logic_vector is
begin       
    
    return std_logic_vector(to_unsigned(integer(mult*(2**16)),16));
    
end function;

并这样称呼它:

convert_mult(0.603205)

函数使用“无法找到带有以[[REAL,UNIVERSAL_INTEGER]”签名表示的操作数的“ *”运算符”的编译失败。

我无法解决这个问题,我认为支持实数*整数吗?我应该使用其他类型吗?

解决方法

TL; DR

您可以像0.603205*(2**16)中那样混合实数和整数文字,但不能像mult*(2**16)中那样混合非文字实数和整数文字。正如Matthew所指出的,realinteger紧密相关的类型,因此转换很容易。使用:

return std_logic_vector(to_unsigned(integer(mult*real(2**16)),16));

而且,顺便说一句,您写了我认为支持实数*整数。好吧,你错了。不支持。您必须使用显式转换...除非使用文字。

详细信息

为什么它适用于文字而不适用于非文字?根据VHDL 2008语言参考手册( IEEE Std 1076-2008 ),universal_integeruniversal_real分别是整数和浮点文字的类型。

0.603205universal_real

2**16有点复杂,因为它是一个包含整数文字(universal_integer s)的表达式。 LRM的 9.3.6类型转换部分说明,universal_integer可以在上下文需要时自动转换为另一种整数类型。我不确切知道会进行什么自动转换,因为LRM很难做到这一点,但是我怀疑16是根据9.3.6节的规则自动转换为integer的,允许使用程序包universal_integer ** integer的{​​{1}}操作数返回一个STANDARD(请参阅 16.3 Package STANDARD 部分,其中所有这些运算符均以其函数形式定义)。

最后,第9.5节通用表达式明确指出universal_integer运算符是在*universal_integer * universal_real上定义的。两者都返回universal_real * universal_integer

注意:还有一个universal_real返回universal_real / universal_integer,但没有universal_real