In the following code, I am using numeric_std_unsigned. This defines "=" such that if S has a meta value, it will always fail the compare, regardless of what it is comparing to.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity lib_test is
end entity;
architecture sim of lib_test is
begin
process
variable s : std_logic_vector(7 downto 0);
begin
s := x"UU";
report "s=" & to_string(s);
if s = x"UU" then
report "S match";
else
report "S no match";
end if;
wait;
end process;
end architecture sim;
My Question is, other than manually adding all the functions I need from numeric_std_unsigned and leaving out the "=" function defined for arithmatic, or using explicit references to every function call (and not using numeric_std_unsigned.all at the top), is there a path I can explicitly use to get the "=" function implicitly defined for SLV?
Running your original test case with some white space modification:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity lib_test is
end entity;
architecture sim of lib_test is
begin
process
variable s: std_logic_vector(7 downto 0);
begin
s := x"UU";
report "s = " & to_string(s);
if s = x"UU" then
report "S match";
else
report "S no match";
end if;
wait;
end process;
end architecture sim;
yields a reproducible error:
ghdl -a --std=08 lib_test.vhdl
ghdl -e --std=08 lib_test sim
ghdl -r --std=08 lib_test sim
lib_test.vhdl:16:9:@0ms:(report note): s = UUUUUUUU
../../src/ieee2008/numeric_std-body.vhdl:1776:7:@0ms:(assertion warning): NUMERIC_STD."=": metavalue detected, returning FALSE
There are four ways to cure the issue in VHDL.
Using an alias in an inner declarative region to specify the correct "=" operator:
architecture sim_alias of lib_test is
begin
process -- <-- inner declarative region
variable s: std_logic_vector(7 downto 0);
alias "=" is ieee.std_logic_1164."="
[ieee.std_logic_1164.std_ulogic_vector,
ieee.std_logic_1164.std_ulogic_vector return
std.standard.BOOLEAN];
begin
s := x"UU";
report "s = " & to_string(s);
if s = x"UU" then
report "S match";
else
report "S no match";
end if;
wait;
end process;
end architecture sim_alias;
resulting in:
ghdl -e --std=08 lib_test sim_alias
ghdl -r --std=08 lib_test sim_alias
lib_test.vhdl:39:9:@0ms:(report note): s = UUUUUUUU
lib_test.vhdl:42:13:@0ms:(report note): S match
Testing the string value:
architecture sim_string of lib_test is
begin
process
variable s: std_logic_vector(7 downto 0);
begin
s := x"UU";
report "s = " & to_string(s);
if to_string(s) = x"UU" then
report "S match";
else
report "S no match";
end if;
wait;
end process;
end architecture sim_string;
also producing the correct result:
ghdl -e --std=08 lib_test sim_string
ghdl -r --std=08 lib_test sim_string
lib_test.vhdl:58:9:@0ms:(report note): s = UUUUUUUU
lib_test.vhdl:62:13:@0ms:(report note): S match
Calling the correct "=" function:
architecture sim_function_call of lib_test is
begin
process
variable s: std_logic_vector(7 downto 0);
begin
s := x"UU";
report "s = " & to_string(s);
if ieee.std_logic_1164."=" (s, x"UU") then
report "S match";
else
report "S no match";
end if;
wait;
end process;
end architecture sim_function_call;
also successful:
ghdl -e --std=08 lib_test sim_function_call
ghdl -r --std=08 lib_test sim_function_call
lib_test.vhdl:78:9:@0ms:(report note): s = UUUUUUUU
lib_test.vhdl:81:13:@0ms:(report note): S match
Use a case statement:
architecture sim_case of lib_test is
begin
process
variable s: std_logic_vector(7 downto 0);
begin
s := x"UU";
report "s = " & to_string(s);
case s is
when x"UU" =>
report "S match";
when others =>
report "S no match";
end case;
wait;
end process;
end architecture sim_case;
also producing the same result:
ghdl -e --std=08 lib_test sim_case
ghdl -r --std=08 lib_test sim_case
lib_test.vhdl:96:9:@0ms:(report note): s = UUUUUUUU
lib_test.vhdl:99:17:@0ms:(report note): S match
Also note that if you were assigning a signal or variable you could use a selected signal assignment or a selected variable assignment, both of which represent case statements which are guaranteed to use the predefined "=".
You could also author your own function providing an overload for "=" operator exhibiting the correct behavior. Like the use of an alias this would depend on the use of an inner declarative region (here the process statement) to prevent the predefined operator from being used in an arithmetic context where the operator in ieee.numeric_std_unsigned is intended.
Likewise you could author your own function for use in a function call, or with a little malice of forethought use
-- Id: M.5
function STD_MATCH (L, R : STD_ULOGIC_VECTOR) return BOOLEAN;
-- Result subtype: BOOLEAN
-- Result: terms compared per STD_LOGIC_1164 intent
From package numeric_std.
The issue comes about from mixing evaluation of a std_logic_vector value (base type std_ulogic_vector) both as metavalues and numeric values, which is likely driven by style issues when package numeric_std type unsigned could be used along with type conversions, noting the dearth of mapping between VHDL port types and interface types in multi-language supporting simulators (such as Modelsim).
The solution to abandon strong typing may not be the ideal solution. The proficiency required to patch up your VHDL source as a result is roughly equivalent to knowing when and where to perform type conversions. These are all 'gimmick' solutions.