何时使用VHDL库std_logic_unsigned和numeric_std?

8

我在ISE中使用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并不是标准库。在这里可以了解更多详情。
我对此感到困惑,请问有谁能帮助我吗?

请参见 https://electronics.stackexchange.com/questions/188622/vhdl-converting-types-and-integer-substraction/188677#188677。 - wjl
1
没有人知道你的队友,以及他们的意图。他们可能只是不知道这个问题。我会问他们为什么坚持使用STD_LOGIC_ARITHSTD_LOGIC_UNSIGNED而不是numeric_std - Staszek
他们说如果你不进行任何算术运算,你就不需要使用numeric_std。@Staszek - Liang He
几乎是相同的问题。谢谢。@wjl - Liang He
2个回答

24

永远不要使用std_logic_arithstd_logic_**signed。需要使用有符号或无符号值时,始终使用numeric_std。前者声称是IEEE标准,但实际上它们是Synopsys或Mentor Graphics的供应商特定扩展。

两个包都基于导入的包定义了对std_logic_vector执行的算术运算。这意味着您不能在同一个体系结构中使用有符号和无符号值。

integer中进行所有数学计算存在一些缺点:

  • 没有未初始化的值
  • 没有“X”传播
  • 仅限于32位
    (如何编写64位计数器?)

但是,当我编写控制函数模块时,几乎不需要使用“signed”或“unsigned”类型吗? - Liang He
未初始化值的含义是什么?没有“X”传播的含义是什么? - Liang He
如果您不需要有符号和无符号值,则除了std_logic_1164之外,不要使用任何其他包...没有必要将更多未使用的类型和运算符加载到当前范围中。 - Paebbels
对于 'U':在模拟中,您将能够看到没有默认值的寄存器、未驱动的信号,因为它们初始化为 'U',电路永远不会重置。对于 'X',即使仅查看顶层信号,您也有机会在顶层看到内部的 X 值,因为错误('X')正在通过您的设计并冒泡到顶部。这就是为什么我们使用 std_logic 而不是 bit 作为数据类型的原因。 - Paebbels
注意:关于编程语言,“Latter”指的是两者中的第二个,相反的则是“Former”,但在这种情况下,我会重复它们的名称。 - JHBonarius
显示剩余2条评论

7

我纯粹的一面同意@Pabbles的观点。然而,我的实用主义者不同意。我的实用主义者获胜,因此,我建议以下做法(直到支持numeric_std_unsigned):

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

对于RTL设计,我建议您将您认为是数学运算的所有操作都使用signed和unsigned类型。这是我的纯粹派面。

在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”为TRUE。
使用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)中定义-因此,除非您使用适当的数学包,否则无法使用它们。

谢谢。@Jim Lewis非常详细的答案。我需要一些时间来阅读它。 - Liang He

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接