krb686
krb686

Reputation: 1806

VHDL - Adding two 8-bit vectors into a 9-bit vector

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

Answers (4)

Martin Thompson
Martin Thompson

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

VAP
VAP

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

rick
rick

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

DonCookie
DonCookie

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

Related Questions