Reputation: 1806
This is a pretty simple question, but I haven't been able to make this work yet, nor has any searching on google or here turned up anything really useful.
All I'm trying to do is add two 8-bit vectors and store the result in a 9-bit vector.
signal operand1, operand2 : STD_LOGIC_VECTOR(7 downto 0);
signal sum : STD_LOGIC_VECTOR(8 downto 0);
sum <= operand1 + operand2;
However I get the warning:
Width mismatch. <sum> has a width of 9 bits but assigned expression is 8-bit wide.
Shouldn't VHDL have some sort of built in routine to know that an extra bit is necessary for addition overflow?
I have these packages included:
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Perhaps STD_LOGIC_VECTOR is always signed? If so, then I need to define them explicity as unsigned?
Upvotes: 8
Views: 35077
Reputation: 16832
Use the standard ieee.numeric_std
library.
Then make your numbers either of unsigned
or signed
type, and make use of the handy resize function:
answer <= resize(operand1, answer'length) + resize(operand2, answer'length);
And bear in mind that many times it's much easier to just use integers, no conversions required, and arithmetic doesn't require you to jump through any resizing hoops!
Upvotes: 4
Reputation: 551
The suggestion above is correct: use the unsigned or signed type when implementing arithmetic circuits (remember to include the numeric_std package in your code).
Since in your case sum has an extra bit (compared to the largest of the operands), the following can be done:
1) If the system is unsigned:
sum <= ('0' & operand1) + ('0' & operand2);
2) If the system is signed (requires sign extension):
sum <= (operand1(N-1) & operand1) + (operand2(N-1) & operand2);
Upvotes: 2
Reputation: 1646
If your goal is to do arithmetic on your signals, get into the habit of declaring them with better-suited types for the job: unsigned
or integer
are good choices in your case.
Note that to prevent overflow you must concatenate a leading '0' to each operand, instead of doing it to the result:
sum <= ('0' & operand1) + ('0' & operand2);
Upvotes: 15
Reputation: 63
Try this: Combine your result with a '0'-vector logically before writing it into the longer vector. For me it worked.
sum <= '0' & (operand1 + operand2);
Hope that helps :)
Upvotes: -6