我纯粹的一面同意@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)中定义-因此,除非您使用适当的数学包,否则无法使用它们。
STD_LOGIC_ARITH
和STD_LOGIC_UNSIGNED
而不是numeric_std
。 - Staszek