# signed vs unsigned in VHDL, what is the difference?

Status
Not open for further replies.

#### matrixofdynamism

An 8 bit signed number would represent values from -128 to 127 while a signed number using those same bits in binary that is, represents numbers from 0 to 255. It is possible to add and subtract signed as well as unsigned numbers in VHDL where the signed and unsigned types are basically vector of binary values. However, this is not possible with std_logic_vector.

I am wondering, what difference is make whether we implement operands as signed or unsigned in an ALU that shall carry out add, subtract, multiply, divide, and, or, xor, nor, not operations? Of course the ports of the ALU shall be std_logic_vector and an internally generated signal shall convert that value to signed or unsigned so arithmatic operations may be carried out on them.

#### shaiko

I am wondering, what difference is make whether we implement operands as signed or unsigned in an ALU that shall carry out add, subtract, multiply, divide, and, or, xor, nor, not operations?

This probably depends on the architecture the IDE vendor decides to implement.
I might be wrong - but my guess is that '+' in Vivado probably won't infer the same logic as it would Quartus.

#### matrixofdynamism

The reason for this confusion is that as far as + and - operators are concerned, we can use them on both the types. I mean since - exists for the unsigned type also why do we need signed?

#### K-J

The reason for this confusion is that as far as + and - operators are concerned, we can use them on both the types. I mean since - exists for the unsigned type also why do we need signed?

The short answer is that you typically need to do more things than just the operators that you have listed. Some examples:

Code:
signal X:  unsigned(7 downto 0);
signal Y:  signed(7 downto 0);

signal X1:  unsigned(15 downto 0);
signal Y1:  signed(15 downto 0);

...
if X < 0 then
-- This branch will never be taken and should get optimized away during synthesis
end if;

if Y < 0 then
-- This branch will be taken if bit 7 is 1
end if;

X1 <= resize(X, X1'length); -- The upper bits will be zero filled
Y1 <= resize(Y, Y1'length);  -- The MSB will get replicated to pad out the upper bits

Kevin Jennings

Points: 2

### matrixofdynamism

Points: 2

#### matrixofdynamism

Yes Kevin, I did realize that when we have to resize an operand, it matters whether it is signed or not. As far as "upsizing" lets say from 16 to 32 bits is concerned, for logic operations we merely put zeros into the upper bits 16 bits. However, if we are resizing for arithmatic operations than we need to know if the string of 16 bits represents signed or unsigned numbers. For signed numbers, all the upper bits are filled with the the MSB of the actual data i.e 16th bit. This is for purpose of "sign preservation" but for unsigned numbers, we just fill in zeros in the upper 16 bits as done for the logic operation operands.

Your point with the < operator is spot on. Now I understand that is does matter quite seriously.

- - - Updated - - -

In the ALU to generate the "zero" signal I have written this code, note that result_i is unsigned and stores the intermediate result during the calculation. Also, ALUControl signal tells the ALU which arithmatic/logic operation to perform:

if (to_integer(result_i) = 0) and (ALUControl = alu_sub) then
zero_i <= '1';
else
zero_i <= '0';
end if;

The problem is that the above method is generating warning. It says 'Warning: (vsim-151) NUMERIC_STD.TO_INTEGER: Value -2 is not in bounds of NATURAL.'. Well result_i cannot be -2 since it was declared as unsigned but that is what the error message says. I am not sure why this message is generated. First I had written if (result_i = (others=>'0')) but it seems that the (others=>'0') does not work in conditional statements so that also did not work.