何时使用 VHDL 库 std_logic_unsigned 和 numeric_std?

When to use VHDL library std_logic_unsigned and numeric_std?

我在 ISE.I 中使用 VHDL-200X,总是使用像 std_logic_vectorstd_logicintegerbooleanreal 这样的数据类型.始终使用 std_logic_vector 转换为 integer 并反转。 队友让我用这三个部分 library IEEE.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

但是有人说不要使用IEEE.STD_LOGIC_UNSIGNED.ALL而不是IEEE.NUMERIC_STD.ALL。因为你在numeric_std中拥有你需要的一切,而STD_LOGIC_UNSIGNED不是标准库。 Here.

我很困惑,有人可以帮忙吗?

切勿使用 std_logic_arithstd_logic_**signed。当需要有符号或无符号值时,总是使用 numeric_std。以前的软件包声称是 IEEE,但实际上不是。它们是 Synopsys 或 Mentor Graphics 的供应商特定扩展。

两者都基于导入的包在 std_logic_vector 上定义了算术运算。这例如意味着您不能在同一架构中使用有符号和无符号值。

integer 秒内完成所有数学运算有一些缺点:

  • 没有未初始化的值
  • 没有'X'传播
  • 限于 32 位
    (如何写一个64位的计数器?)

我的纯粹主义者同意@Pabbles。 OTOH,我务实的一面不同意。我务实的一面获胜,因此,我推荐以下内容(直到支持 numeric_std_unsigned):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

对于 RTL 设计,我建议您对所有您认为是数学的运算使用有符号和无符号类型。这是我纯粹的一面。

在 RTL 中,我从不建议在 std_logic_vector 中进行数学运算,相反,std_logic_unsigned 只是一个安全网。考虑到所有关系运算符都是隐式定义的(=、/=、<、<=、>、>-)。在设计中,我们对值进行了很多比较:

if A = "00001" then 
. . . 
if B = X"1A" then 

如果 A 不是 5 位会怎样?如果 B 不是 8 位会怎样?如果使用隐式定义的比较,则为 FALSE。如果使用std_logic_unsigned中的比较,尺寸不同也没关系。如果您没有使用 std_logic_unsigned,您的测试台应该会发现这个问题。

因为“=”可以与 RTL 一起使用,如果有人在做地址解码器并写入:

Sel <= '1' when Addr > X"3FFF" else '0' ; 

如果 A 是 16 位,那么它应该可以运行。如果 A 不是 16 位怎么办?然后它进行词典编排(字典排序)比较。即:“100”>“01111”为真。

对于 std_logic_unsigned,这些将由无符号数学规则处理。在大多数情况下这是正确的。如果没有 std_logic_unsigned,这些将导致 FALSE。如果你没有使用 std_logic_unsigned 并且你对你的测试平台很小心,你应该找到这个。

我担心的是,如果您不使用 std_logic_unsigned,那么您模拟的电路可能与您综合的电路不同(因为综合工具往往会创建一个实现这与 std_logic_unsigned 一致)。如果您在模拟中错过了这一点,那么在评论中将很难找到。因此,我推荐 std_logic_unsigned 作为使用普通关系运算符时的安全网。

请注意,VHDL-2008 引入了包 numeric_std_unsigned,我计划在它适用于所有综合工具时切换到该包。

我非常严格的一面说我们应该通过创建额外的包来解决排序操作(<、<=、>、>=)的问题,这些包也会为 std_logic_vector 重载它们,因此,使用由于歧义,它们中的一部分会导致错误。请注意,我们不能以同样的方式保护“=”。

VHDL-2008 添加了匹配的关系操作“?=”、“?/=”、“?>”……当这些在您的综合工具中可用时,我建议切换到这些。匹配的相等运算符 (?=, ?/=) 要求操作数的长度相同 - 如果它们的长度不相等,则意味着编译错误。匹配的排序操作 (?>, ?>=, ?<, ?<=) 仅在 numeric_std 或 numeric_std_unsigned 等数学包中定义 - 因此,除非您使用一个合适的数学包。