为什么 `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;