to_unsigned 做什么?

Sas*_*vic 2 unsigned type-conversion vhdl twos-complement signed-integer

有人可以解释一下 VHDL 的to_unsigned是如何工作的或者确认我的理解是正确的吗?例如:

C(30 DOWNTO 0) <= std_logic_vector (to_unsigned(-30, 31))
Run Code Online (Sandbox Code Playgroud)

这是我的理解:

  • -30 是有符号值,以位表示为 1111111111100010
  • 所有位都应反转并添加“1”以构建 C 的值
  • 0000000000011101+0000000000000001== 0000000000011111

小智 5

在 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.
Run Code Online (Sandbox Code Playgroud)

您不会找到带有声明为整数类型的参数或大小的声明函数 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;
Run Code Online (Sandbox Code Playgroud)

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));  
                                                        ^^^
Run Code Online (Sandbox Code Playgroud)

并且实际上告诉我们在源代码中哪里发现了错误。

可以肯定地说,您认为 to_unsigned 所做的事情并不是分析器认为它所做的事情。

VHDL 是一种强类型语言,您尝试提供一个值来放置该值超出IEEE 包 numeric_std 中声明的ARG函数中的参数范围TO_UNSIGNED

NATURAL 类型在包 standard 中声明,并通过推断声明库 std 使其可见;使用 std.standard.all;在上下文子句中。(参见 IEEE Std 1076-2008,13.2 设计库):

除上下文声明和包 STANDARD 之外的每个设计单元都假定包含以下隐式上下文项作为其上下文子句的一部分:

library STD, WORK; use STD.STANDARD.all;
Run Code Online (Sandbox Code Playgroud)

16.3 包装标准中的天然声明:

subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
Run Code Online (Sandbox Code Playgroud)

声明为 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 兼容工具保证给出相同的结果。