VHDL-LS / rust_hdl

Other
332 stars 65 forks source link

[Bug] Warning reported regarding relational operators #305

Closed nselvara closed 4 months ago

nselvara commented 4 months ago

Hi guys, I get this warning when I try to use relational operators: Found no match for operator "?/="vhdl ls(unresolved) I also checked the VHDL-2008 LRM and the relational operators are mentioned as feature:

Relational operators include tests for equality, inequality, and ordering of operands. The operands of each relational operator shall be of the same type. The result type of each ordinary relational operator (=, /=, <, <=, >, and >=) is the predefined type BOOLEAN. The result type of each matching relational operator (?=, ?/=, ?<, ?<=, ?>, and ?>=) is the same as the type of the operands (for scalar operands) or the the element type of the operands (for array operands).

Here's an MRE:

package pkg_test is
    function to_std_ulogic(value: integer) return std_ulogic;
end package;

package body pkg_test is
    function to_std_ulogic(value: integer) return std_ulogic is begin
        return value ?/= 0;
    end function;
end package body;
Schottkyc137 commented 4 months ago

I believe that this is not a problem of VHDL_LS. The LRM says the following (quote taken from you):

The result type of each matching relational operator [...] is the same as the type of the operands (for scalar operands) or the the element type of the operands (for array operands).

In your case, you are comparing an integer to an integer (resp. universal integer). The result can therefore only be an integer.

nselvara commented 4 months ago

Ahh, sad life 😢, I should have read the entire paragraph. However, I checked again, the relational operator can only be used for scalar and array types. So for integers, sadly it doesn't work.

-- These should work:
function rel_op_test return std_ulogic is
    constant BLUE: std_ulogic_vector(7 downto 0) := x"00_00_FF";
    constant GREEN: std_ulogic_vector(7 downto 0) := x"00_FF_00";    
begin
    return BLUE ?/= GREEN;
end function;

function test_rel_op(value: std_ulogic) return std_ulogic is begin
    return value ?/= '0';
end function;

-- These not:
function to_std_ulogic(value: integer) return integer is begin
    return value ?/= 0;
end function;

function test_rel_op return natural is
    type test_array_t is array(0 to 1) of natural;
    constant test_array_1: test_array_t := (0, 1);
    constant test_array_2: test_array_t := (2, 3);
begin
    return test_array_1 ?/= test_array_2;
end function;

Sorry for trouble and thanks for clarifying. I close it for now.

Schottkyc137 commented 4 months ago

Integers are scalar values; you can use the relational operators on integers. You just have to make sure to compare them to signed or unsigned values to get a std_logic value.

nselvara commented 4 months ago

I see, that's a great trick. Thank you very much 🙏!

With this, it doesn't complain:

function test_rel_op(value: unsigned) return std_ulogic is begin
    return value ?/= 1;
end function;