Why ** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0?

Lasse Karagiannis picture Lasse Karagiannis · Feb 11, 2017 · Viewed 14.8k times · Source

Why does Modelsim complain about the component instantiation i1?

Time: 0 ps Iteration: 1 Instance: /vhdl2_uppgift_1_extra_vhd_tst/i1
** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0

LIBRARY ieee;                                               
USE ieee.std_logic_1164.all;  
use ieee.numeric_std.all;
LIBRARY work; 

--Add in do-file
--set StdArithNoWarnings 1
---run 0 ns;
---set StdArithNoWarnings 0
---run 20 ms;                             

ENTITY vhdl2_uppgift_1_extra_vhd_tst IS
END vhdl2_uppgift_1_extra_vhd_tst;
ARCHITECTURE vhdl2_uppgift_1_extra_arch OF vhdl2_uppgift_1_extra_vhd_tst IS
-- constants    
constant sys_clk_period: TIME:=20 ns;                                               
-- signals                                                   
SIGNAL CLOCK_50    : STD_LOGIC;
SIGNAL KEY         : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL reset_n     : STD_LOGIC;
SIGNAL VGA_B       : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL VGA_BLANK_N : STD_LOGIC;
SIGNAL VGA_CLK     : STD_LOGIC;
SIGNAL VGA_G       : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL VGA_HS      : STD_LOGIC;
SIGNAL VGA_R       : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL VGA_VS      : STD_LOGIC;
SIGNAL x           : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL y           : STD_LOGIC_VECTOR(9 DOWNTO 0);
COMPONENT vhdl2_uppgift_1_extra
PORT (
    CLOCK_50 : IN STD_LOGIC;
    KEY : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
    reset_n : IN STD_LOGIC;
    VGA_B : BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
    VGA_BLANK_N : BUFFER STD_LOGIC;
    VGA_CLK : BUFFER STD_LOGIC;
    VGA_G : BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
    VGA_HS : BUFFER STD_LOGIC;
    VGA_R : BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
    VGA_VS : BUFFER STD_LOGIC;
    x : BUFFER STD_LOGIC_VECTOR(9 DOWNTO 0);
    y : BUFFER STD_LOGIC_VECTOR(9 DOWNTO 0)
    );
END COMPONENT;
BEGIN

 i1 : vhdl2_uppgift_1_extra
 PORT MAP (
 -- list connections between master ports and signals
 CLOCK_50 => CLOCK_50,
 KEY => KEY,
 reset_n => reset_n,
 VGA_B => VGA_B,
 VGA_BLANK_N => VGA_BLANK_N,
 VGA_CLK => VGA_CLK,
 VGA_G => VGA_G,
 VGA_HS => VGA_HS,
 VGA_R => VGA_R,
 VGA_VS => VGA_VS,
 x => x,
 y => y
 );



clock : PROCESS                                               
-- variable declarations                                     
BEGIN                                                        
  CLOCK_50 <= '0';
    wait for sys_clk_period/2;
    CLOCK_50 <= '1';
    wait for sys_clk_period/2;
END PROCESS clock; 
 -----------------------

reset_n <= '0', '1' after 10*sys_clk_period;

-----------------------

always : PROCESS                                                                                  
BEGIN                                                        
  -- code executes for every event on sensitivity list  
  KEY <= "110";
  wait for 20 ms;
WAIT;                                                        
END PROCESS always; 

-----------------------

compare: PROCESS(x,y)
    VARIABLE VGA_HS_error               : BOOLEAN := FALSE;
    VARIABLE VGA_VS_error               : BOOLEAN := FALSE;
    VARIABLE VGA_BLANK_error            : BOOLEAN := FALSE;
    VARIABLE VGA_CLK_PHASE_error        : BOOLEAN := FALSE;
    VARIABLE VGA_CLK_COUNTER            : INTEGER :=0;
    VARIABLE CLOCK_50_COUNTER           : INTEGER :=0;
    VARIABLE VGA_CLK_FREQUENCY_ERROR : BOOLEAN := FALSE;
BEGIN
--VGA_HS
if TO_INTEGER(unsigned(x)) >= 659 AND TO_INTEGER(unsigned(x)) < 756    then

            if VGA_HS /= '0' then
                VGA_HS_error:= true;
            end if;

            ASSERT VGA_HS = '0'
            REPORT "FAIL on VGA_HS"
            SEVERITY ERROR; --  eller stanna simulatorn: SEVERITY FAILURE;
            -- eller REPORT "FAIL on VGA_HS signal on horizontal position " & integer'image(x);
        end if;

--VGA_VS
      if TO_INTEGER(unsigned(y)) = 493 then

            if VGA_VS = '1' then
              VGA_VS_error:= true;
            end if;

            ASSERT VGA_VS = '0'
            REPORT "FAIL on VGA_VS"
            SEVERITY ERROR; --  eller stanna simulatorn: SEVERITY FAILURE;

        end if;

--VGA_BLANK_N
     if TO_INTEGER(unsigned(x)) < 640 and TO_INTEGER(unsigned(y)) < 480 then

            if VGA_BLANK_N /= '1' then
                VGA_BLANK_error:= true;
            end if;

            ASSERT VGA_BLANK_N = '1'
            REPORT "VGA_BLANK_N"
            SEVERITY ERROR; --  eller stanna simulatorn: SEVERITY FAILURE;

      end if;

--VGA_CLK
     if rising_edge(VGA_CLK)AND NOT rising_edge(CLOCK_50) then
            VGA_CLK_PHASE_error :=true;
            ASSERT rising_edge(CLOCK_50)
            REPORT "FAIL on VGA_CLK"
            SEVERITY ERROR; --  eller stanna simulatorn: SEVERITY FAILURE;

      end if;


END PROCESS compare;

vga_clk_test:process

    VARIABLE TIME_VGA_CLK_RISING        : TIME;
    VARIABLE TIME_VGA_CLK_FALLING   : TIME;
    VARIABLE TIME_DIFF                  : TIME;
    begin
        WAIT UNTIL rising_edge(VGA_CLK);
        TIME_VGA_CLK_RISING := now;

        WAIT UNTIL falling_edge(VGA_CLK);
        TIME_VGA_CLK_FALLING := now;

        TIME_DIFF := TIME_VGA_CLK_FALLING - TIME_VGA_CLK_RISING;

        REPORT "TEST 11: Half-periodtime  : " & time'image(TIME_DIFF);

        IF TIME_DIFF = 20000 ps THEN
            REPORT "TEST 11: OK VGA_CLK ";
        ELSE
            REPORT "TEST 11: ERROR VGA_CLK";

        END IF;

        wait;
   end process vga_clk_test;                                         
END vhdl2_uppgift_1_extra_arch;

Answer

JHBonarius picture JHBonarius · Feb 21, 2017

Warnings are not always a problem, for instance in this case. The code probably simulates and synthesizes and such.

In this case the warning is caused because numeric_std.to_integer() is getting a so-called metavalue, which means it is an input it cannot convert to an integer. For example 'X' or 'U'.

If you don't want the error messages you can do what user1155120 describes in the comments:

...in modelsim.ini uncomment or set NumericStdNoWarnings = 1

He also describes that is is allowed by IEEE1076 standard to modify the numeric_std package, as mentioned for instance in IEEE1076-2008:

16.8.5.2 Allowable modifications Vendors of tools conforming to this standard shall not modify the package declarations. [...] The package bodies for the NUMERIC_BIT and NUMERIC_STD packages declare a constant named NO_WARNING that has the value FALSE. A user may set NO_WARNING to TRUE and reanalyze the package body to suppress warning messages generated by calls to the functions in these packages.[...]

An alternative option is to use an intermediate variable for x and y and used the function Is_X() to detect and prevent a metavalue. However, I am not sure if it will synthesize properly. Example:

x_nometa <= (others=>'0') when Is_X(x) else x;

One other thing I noticed in you code, is that you uses BUFFER-type ports. You should preferable not use those. They are not supported properly by for instance FPGA vendors. E.g. Xilinx. There are ways around this: How to stop using "buffer" ports in VHDL