sebi707
sebi707

Reputation: 390

Weird signed comparison results

I encountered an unexpected comparison result when comparing a 2bit std_logic_vector with std_logic_signed package loaded to hex constants such as x"3". I was expecting the comparison to be true when both bits are set but it's always false. Probably because the std_logic_vector gets sign extended to 4bit for the comparison against the 4bit hex constant. What's really weird though, is that the comparison works as expected when using the constant 3, but only when using a std_logic_vector, not when using a signed type. See sample code below. All asserts fail except the first one. Why does this assert succeed? Also when not loading the std_logic_signed package the vec0 = x"3" comparison still fails. Only when loading std_logic_unsigned makes this comparison succeed.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

entity tb is
end entity;

architecture bhv of tb is
    signal vec0 : std_logic_vector(1 downto 0) := (others => '1');
    signal vec1 : signed(1 downto 0)           := (others => '1');
begin
    process
    begin
        assert vec0 = 3     report "Test 1";
        assert vec0 = x"3"  report "Test 2";
        assert vec1 = 3     report "Test 3";
        assert vec1 = x"3"  report "Test 4";
        wait;
    end process;
end architecture;

Upvotes: 2

Views: 971

Answers (1)

Tricky
Tricky

Reputation: 4516

When compares are done using signed/unsigned, both operands are expanded to the length of the longest operand and then compared.

So, for the x"3" case, you have a 4 bit number "0011" = +3

vec0 and vec1 = "11" = -1. Because they are SLV treated as a signed, or an actual signed, they are sign extended to "1111". Hence "1111" is not equal to "0011".

When comparing signed/slv to integer, the integer is converted to a vector the length of the other operand. In both cases, literal 3 cannot be converted to a 2 bit signed (as the range is -2 to +1)

For std_logic_signed (a non-standard VHDL package) the 3 is converted to "11" by the nature of how the function works. Hence you get a match (incorrectly)

Numeric_std has a check function where integers outside of the range of the signed (or unsigned) operand automatically return false.

numeric_std IS a VHDL standard.

Moral - dont bother using std_logic_signed.

Upvotes: 1

Related Questions