为什么 `to_unsigned(0, 4) >= -1` 在运行时计算为 `FALSE`?
Why does `to_unsigned(0, 4) >= -1` evaluate to `FALSE` at runtime?
使用下面的测试代码:
library ieee;
use ieee.numeric_std.all;
architecture sim of tb is
begin
process is
begin
for c in -1 to 1 loop
assert to_unsigned(0, 4) >= c report "Fails: 0 >= " & integer'image(c) severity NOTE;
end loop;
wait;
end process;
end architecture;
使用 ModelSim 10.5a 显示此输出:
Loading work.tb(sim)
** Note: Fails: 0 >= -1
Time: 0 ns Iteration: 0 Instance: /tb
** Note: Fails: 0 >= 1
Time: 0 ns Iteration: 0 Instance: /tb
如此有效 to_unsigned(0, 4) >= -1
评估为 FALSE
,并且在我使用 for
循环时 运行 时没有报告。这是为什么?
请注意,如果我在 运行 时不使用 for
循环获取 -1
值而编写 to_unsigned(0, 4) >= -1
,则 ModelSim 编译器将报告 "Value -1 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.".
TL/DR:请在任何获得 Modelsim 技术支持的地方询问这个问题,并根据他们的回答更新问题。
快速重写和 cross-check 使用(通常非常严格和准确的)ghdl 模拟器:
library ieee;
use ieee.numeric_std.all;
entity tb is
end tb;
architecture sim of tb is
begin
process is
begin
for c in -1 to 1 loop
assert to_unsigned(0, 4)
>=
c
report "Fails: 0 >= " & integer'image(c) severity NOTE;
end loop;
wait;
end process;
end architecture;
ghdl -r tb
./tb:error: bound check failure at tb.vhd:14
./tb:error: simulation failed
恰好在计算 c
时显示边界检查错误,这不在 Unsigned 或 Natural 的合法范围内。
所以问题是,ghdl 或 Modelsim 是否选择了不合适的 >=
运算符?
numeric_std 的源代码仅显示了两个 >=
运算符定义,其中第一个参数是 unsigned
。 (此文件是 "copyright 2008",因此适用于 VHDL-2008 标准。)
-- Id: C.19
function ">=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN;
-- Result subtype: BOOLEAN
-- Result: Computes "L >= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly
-- of different lengths.
-- Id: C.23
function ">=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN;
-- Result subtype: BOOLEAN
-- Result: Computes "L >= R" where L is an UNRESOLVED_UNSIGNED vector and
-- R is a nonnegative INTEGER.
它们都不允许将带符号的数量(带符号或整数)作为第二个参数。
因此,您可能需要查看安装中 numeric_std
的源代码,看看它是否是不同的修订版本,其中 >=
运算符允许混合无符号和整数数据类型。我怀疑它是否存在:它很容易产生这种误解。
如果没有这样的算子,这里Modelsim是宽容的;是否有编译选项来启用更严格的合规性?
如果您认为这是不必要的迂腐,请考虑一下:
c := -1;
if to_unsigned(0, 4) >= c then
emergency_stop;
end if;
使用下面的测试代码:
library ieee;
use ieee.numeric_std.all;
architecture sim of tb is
begin
process is
begin
for c in -1 to 1 loop
assert to_unsigned(0, 4) >= c report "Fails: 0 >= " & integer'image(c) severity NOTE;
end loop;
wait;
end process;
end architecture;
使用 ModelSim 10.5a 显示此输出:
Loading work.tb(sim)
** Note: Fails: 0 >= -1
Time: 0 ns Iteration: 0 Instance: /tb
** Note: Fails: 0 >= 1
Time: 0 ns Iteration: 0 Instance: /tb
如此有效 to_unsigned(0, 4) >= -1
评估为 FALSE
,并且在我使用 for
循环时 运行 时没有报告。这是为什么?
请注意,如果我在 运行 时不使用 for
循环获取 -1
值而编写 to_unsigned(0, 4) >= -1
,则 ModelSim 编译器将报告 "Value -1 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.".
TL/DR:请在任何获得 Modelsim 技术支持的地方询问这个问题,并根据他们的回答更新问题。
快速重写和 cross-check 使用(通常非常严格和准确的)ghdl 模拟器:
library ieee;
use ieee.numeric_std.all;
entity tb is
end tb;
architecture sim of tb is
begin
process is
begin
for c in -1 to 1 loop
assert to_unsigned(0, 4)
>=
c
report "Fails: 0 >= " & integer'image(c) severity NOTE;
end loop;
wait;
end process;
end architecture;
ghdl -r tb
./tb:error: bound check failure at tb.vhd:14
./tb:error: simulation failed
恰好在计算 c
时显示边界检查错误,这不在 Unsigned 或 Natural 的合法范围内。
所以问题是,ghdl 或 Modelsim 是否选择了不合适的 >=
运算符?
numeric_std 的源代码仅显示了两个 >=
运算符定义,其中第一个参数是 unsigned
。 (此文件是 "copyright 2008",因此适用于 VHDL-2008 标准。)
-- Id: C.19
function ">=" (L, R : UNRESOLVED_UNSIGNED) return BOOLEAN;
-- Result subtype: BOOLEAN
-- Result: Computes "L >= R" where L and R are UNRESOLVED_UNSIGNED vectors possibly
-- of different lengths.
-- Id: C.23
function ">=" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return BOOLEAN;
-- Result subtype: BOOLEAN
-- Result: Computes "L >= R" where L is an UNRESOLVED_UNSIGNED vector and
-- R is a nonnegative INTEGER.
它们都不允许将带符号的数量(带符号或整数)作为第二个参数。
因此,您可能需要查看安装中 numeric_std
的源代码,看看它是否是不同的修订版本,其中 >=
运算符允许混合无符号和整数数据类型。我怀疑它是否存在:它很容易产生这种误解。
如果没有这样的算子,这里Modelsim是宽容的;是否有编译选项来启用更严格的合规性?
如果您认为这是不必要的迂腐,请考虑一下:
c := -1;
if to_unsigned(0, 4) >= c then
emergency_stop;
end if;