Search code examples
vhdlfpga

Difference between unsigned and std_logic_vector


can anyone tell me about the difference between below written statement.

signal A: **unsigned**(3 downto 0);
signal B: **std_logic_vector**(3 downto 0);

Solution

  • Both std_logic_vector and unsigned are unconstrained arrays of std_logic. As is the signed type. std_logic_vector is declared in the std_logic_1164 package; unsigned and signed are declared in the package numeric_std. All three types are identical; the only difference is their names.

    So, what's the point of that? The point is well illustrated by an example:

    With

    variable U : unsigned(3 downto 0);
    variable S : signed(3 downto 0);
    variable I : integer;
    

    then

    U := "1111";
    I := to_integer(U);
    

    results in I being given the value 15, whereas

    S := "1111";
    I := to_integer(S);
    

    results in I being given the value -1. This is because the unsigned type is used to represent an unsigned number, which can only be positive. So, "1111" represents the number 15. A signed type, however, needs to be able to represent negative numbers, too, and with the signed type "1111" represents -1 (because the twos complement representation is used by this type).

    So, you can see that the same function - to_integer - returns two different results when called with "1111" - either 15 or -1 depending on whether the argument is of type unsigned or signed. So, you can see the point in having both types, even though the only difference between them is their name.

    Actually, there are two to_integer functions, not one. One takes an unsigned argument; the other (identically named to_integer) takes a signed argument. As you can see, they do behave differently. The compiler can decide which function needs to be called based on the type of the argument. This idea, where a compiler can choose between different (but identically-named functions) based on the type of the argument, is called overloading. It is common in software languages.

    So, what about std_logic_vector? Suppose you wrote:

    variable V : std_logic_vector(3 downto 0);
    variable I : integer;
    

    then

    V:= "1111";
    I := to_integer(V);
    

    what result would you expect from the to_integer function? 15 or -1? This dilemma is solved by the above code being illegal - it won't compile. It won't compile, because there is no version of the to_integer function defined for std_logic_vector - the to_integer function is not overloaded for the type std_logic_vector.

    So, if you only need to represent positive numbers, you're best off using the unsigned type; if you need to represent negative numbers you need to use the signed type. If you don't really care, because your pattern of bits is not a number or because your not doing any maths on it (you're merely transporting it from one place to another), then you're best off using std_logic_vector.

    https://www.edaplayground.com/x/2Qq4