mathtypesvhdlunsignedieee

Need clarification on VHDL expressions involving std_logic_vector, unsigned and literals, unsure about compiler interpretation


I do not understand how the following operations 2s – 1 and 1 - 2s are performed in the following expressions:


R <= (s & '0') - 1;

L <= 1-(s & '0');

Considering the fact that R and L are of type signed(1 downto 0) and s of type std_logic. I have extracted them from a vhdl code snippet in my professor's notes.

What I understand (or at least consider to understand – premises of my reasoning)

  1. The concatenation with the 0 literal achieves the product by 2 (That is what shifting to the left does).
  2. The concatenation also achieves a std_logic_vector of 2 bits (not so sure about that, I inferred this from a comment in the following StackOverflow question
  3. "std_logic_vector is great for implementing data buses, it’s useless for performing arithmetic operations" - source: vhdlwhiz.

What baffles me:

  1. What type does the compiler interpret the 1 literal is?
    • An integer? If so, can an integer be used without casting in an arithmetic expression with a std_logic_vector? This option doesn't seem very plausible to me...
    • Assuming the fact that the (s & '0') is indeed interpreted as a std_logic_vector (second premise) it also comes to my mind the possibility that the compiler, based on the type of the other operand in the expression (i.e., (s & '0')), inferred 1 to be of type std_logic_vector as well. However, even though both (s & '0') and 1 were interpreted as std_logic_vector they should not be behaving correctly according to my third premise.
      • A thought that comes to my mind in order tu justify the possibility of both operands being of type std_logic_vector is that both (s & '0') and 1 are implicitly casted to signed by the compiler because it acknowledges the fact the signal in which the result is stored is of type signed. This, doesn't seem to make sense to me (suppose s is equal to 1): R <= (s & '0') - 1;

        Both operands are converted to std_logic_vectors(1 downto 0) R <= "10" - "01"

        Now, if the contents of the std_logic_vectors were interpreted as signed the result of the subtraction would be R <= (-2) - (1) = -3

As you can tell I am really confused. I believe we've only scratched the surface when it comes to discussing data types in class and I am encountering a lot of problems when solving problems because choosing the wrong data types.

I apologize for any lack of clarity in my questions; they reflect my current understanding of the subject. Thank you for your patience.


Solution

  • In this instance in the conext provided, (s & '0') does not create a std_logic_vector, it creates a signed. VHDL is a context driven language. Because no arithmatic is available on std_logic_vector, and the types of L and R are signed, the arithemtic must be of the signature (from ieee.numeric_std):

    function "-" (L: NATURAL; R: SIGNED) return SIGNED;
    function "-" (L: SIGNED;  R: NATURAL) return SIGNED;
    

    The numeric_std package provides the arithmetic functions above between signed and integer types, hence the 1 value is converted inside the "-" function to be the same as the other operand, in this case, a signed of 2 bits.