有人可以解释一下 VHDL 的to_unsigned是如何工作的或确认我的理解是正确的吗?例如:
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31))
以下是我的理解:
- -30 是有符号值,以位表示为 1111111111100010
- 所有位都应反转并添加“1”以构建 C 的值
- 0000000000011101+0000000000000001 == 0000000000011111
有人可以解释一下 VHDL 的to_unsigned是如何工作的或确认我的理解是正确的吗?例如:
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31))
以下是我的理解:
在 IEEE 包 numeric_std 中,声明TO_UNSIGNED
:
-- Id: D.3
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED(SIZE-1 downto 0)
-- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
-- the specified SIZE.
您不会找到带有声明为整数类型的参数或大小的声明函数 to_unsigned。后果是什么?
让我们把它放在一个最小、完整和可验证的例子中:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity what_to_unsigned is
end entity;
architecture does of what_to_unsigned is
signal C: std_logic_vector (31 downto 0);
begin
C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31));
end architecture;
VHDL 分析器会给我们一个错误:
ghdl -a what_to_unsigned.vhdl
what_to_unsigned.vhdl:12:53:静态常量违反界限
ghdl:编译错误
并告诉我们 -30(第 12 行:字符 53)违反了边界。在这种情况下,意味着转换为Universal_integer的数字文字不会转换为natural
函数中的类型to_unsigned
。
一个不同的工具可能会更形象地告诉我们:
nvc -a what_to_unsigned.vhdl ** Error: value -30 out of bounds 0 to 2147483647 for parameter ARG File what_to_unsigned.vhdl, Line 12 C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31)); ^^^
并且实际上告诉我们在源代码中的哪里发现了错误。
可以肯定地说,您认为 to_unsigned 所做的并不是分析器认为它所做的。
VHDL 是一种强类型语言,您尝试提供一个值来放置该值超出IEEE 包 numeric_std 中声明的ARG
函数中的参数范围的位置。TO_UNSIGNED
NATURAL 类型在包标准中声明,并通过推断的声明库 std 可见;使用 std.standard.all;在上下文条款中。(参见 IEEE Std 1076-2008, 13.2 设计库):
除了上下文声明和包 STANDARD 之外的每个设计单元都假定包含以下隐式上下文项作为其上下文子句的一部分:
library STD, WORK; use STD.STANDARD.all;
16.3 Package STANDARD 中的 natural 声明:
subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
声明为 NATURAL 的值是 INTEGER 的子类型,具有不包括负数的受限范围。
关于这里,您可以看到您可以通过访问符合 VHDL 标准的工具并参考 IEEE Std 1076-2008,IEEE 标准 VHDL 语言参考手册来回答这个问题。
TL:DR; 细节
你可以注意到 9.4 静态表达式,9.4.1 通用允许在分析期间评估本地静态表达式:
某些表达式被称为是静态的。类似地,某些离散范围被称为是静态的,某些子类型的类型标记被称为表示静态子类型。
静态表达式有两类。某些表达形式可以在分析它们出现的设计单元的过程中进行评估;这样的表达式被称为局部静态的。某些表达形式可以在它们出现的设计层次结构被详细阐述后立即进行评估;据说这样的表达式是全局静态的。
可能有一些符合标准的工具在分析期间不会评估本地静态表达式。“可以”是允许的而不是强制性的。上述代码示例中演示的两个 VHDL 工具利用了该权限。在这两个工具中,命令行参数 -a 告诉工具分析提供的文件,如果成功,则插入到当前工作库中(默认为 WORK,参见 13.5 分析顺序,13.2 设计库)。
在详细说明局部静态表达式时评估边界检查的工具通常是纯解释性的,甚至可以通过单独的分析过程来克服。
VHDL 语言可用于在附件 D 规定的范围内的形式证明中使用的设计模型的形式规范 潜在的不可移植构造和仅依赖于纯函数时(参见 4.子程序和包,4.1 常规)。
VHDL 兼容工具保证提供相同的结果,尽管没有对错误消息进行标准化,也没有对工具实施方法施加限制。
to_unsigned
用于在不同类型之间进行转换:
signal i : integer := 2;
signal u : unsigned(3 downto 0);
...
u <= i; -- Error, incompatible types
u <= to_unsigned(i, 4); -- OK, conversion function does the right thing
如果您尝试转换负整数,这是一个错误。
u <= to_unsigned(-2, 4); -- Error, does not work with negative numbers
如果您只是想反转一个整数,即 2 变为 -2,5 变为 -5,只需使用-
运算符:
u <= to_unsigned(-i, 4); -- OK as long as `i` was negative or zero
如果你想要绝对值,numeric_std
库提供了一个函数。
u <= to_unsigned(abs(i), 4);