何时使用 VHDL 库 std_logic_unsigned 和 numeric_std?
When to use VHDL library std_logic_unsigned and numeric_std?
我在 ISE.I 中使用 VHDL-200X,总是使用像 std_logic_vector
、std_logic
、integer
、boolean
和 real
这样的数据类型.始终使用 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_arith
或 std_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 等数学包中定义 - 因此,除非您使用一个合适的数学包。
我在 ISE.I 中使用 VHDL-200X,总是使用像 std_logic_vector
、std_logic
、integer
、boolean
和 real
这样的数据类型.始终使用 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_arith
或 std_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 等数学包中定义 - 因此,除非您使用一个合适的数学包。