Using the test code below:
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;
Shows this output using 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
So effectively to_unsigned(0, 4) >= -1
evaluated to FALSE
, and this is not reported at run-time when I used the for
loop. Why is this?
Note that if I write to_unsigned(0, 4) >= -1
without using the for
loop for getting the -1
value at runtime, then the ModelSim compiler will report that "Value -1 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.".
TL/DR : Please ask this wherever you get tech support for Modelsim, and update the question with their response.
A quick rewrite and a cross-check with the (generally pretty strict and accurate) ghdl simulator:
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
shows a bound check error precisely at the evaluation of c
which is not within the legal range for an Unsigned or Natural.
So the question is, did either ghdl or Modelsim pick an inappropriate >=
operator?
The source for numeric_std shows only two >=
operator definitions where the first argument is an unsigned
. (This file is "copyright 2008" so for the VHDL-2008 standard.)
-- 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.
Neither of which permits a signed quantity (Signed or Integer) as the second argument.
So, you might want to look at the source for numeric_std
in your installation to see if it's a different revision, with a >=
operator permitting mixed Unsigned and Integer datatypes. I doubt it exists : it would be dangerously prone to just this sort of misunderstanding.
If there is no such operator, Modelsim is being permissive here; are there compilation options to turn on stricter compliance?
And if you think this is unnecessarily pedantic, consider this:
c := -1;
if to_unsigned(0, 4) >= c then
emergency_stop;
end if;