views:

1295

answers:

2

Hi folks,

I'm currently writing a 32Bit ALU (Add/Sub) in VHDL. I've got a problem with the overflow bit. I can't see when to set the overflow depending on the operation (addition, subtraction) and the input values.

Can you help me ?

best regards, Andre

A: 

What does the spec say it should do?

Conventionally, the overflow bit is set when the output is too big for the storage. You could think of it as a 33rd bit in the answer of summing two 32 bit numbers. In signed arithmetic, this can happen if the magnitude of the result of the operation is too big, irrespective of sign. With 2-s complement arithmetic, you have to be a bit careful as the biggest -ve number is slightly more -ve than the biggest +ve number that you can represent in a given number of bits.

In terms of actually doing it, just create a bit vector 1 bit wider than the inputs, do

a<=b+c;

and let the synthesizer create the logic. Take the MSB of "a" and call it the overflow.

Martin Thompson
+1  A: 

Just to add a bit of extra information to Martin's answer, you need to be careful about detecting the overflow with 2's complement arithmetic.

For example, if you have 3-bit signed values represented in two's complement format and you want to detect an overflow, you need to sign extend into the extra bit and then look to see if the extra bit is different from the most significant wanted bit:

For example, if you want to calculate a = b + c:

--Declare the signals
signal overflow : std_logic;
signal a : signed(2 downto 0);
signal b : signed(2 downto 0);
signal c : signed(2 downto 0);

-- Declare some additional signals with one more MSB than the original signals
signal a_extended : std_logic(3 downto 0);
signal b_extended : std_logic(3 downto 0);
signal c_extended : std_logic(3 downto 0);

-- Sign extend the MSB
b_extended <= b(2) & b;
c_extended <= c(2) & c;

-- Perform the addition
a_extended <= b_extended + c_extended;

-- Detect the overflow case
overflow <= '1' when a_extended(3) /= a_extended(2) else '0';

-- Calculate the answer
-- Limit to 100 (-4) or 011 (+3) in the case of overflow
process(a_extended)
begin
   if a_extended(3) /= a_extended(2) then
      if a_extended(3) = '1' then
         a <= "100";
      else
         a <= "011";
      end if;
   else
      a <= a_extended(2 downto 0);
   end if;
end process;
Justin
You make an important point about twos-complement overflow...
Marty
To add to Justin's answer (which makes good points :) there's functions for resizing vectors in the ieee.numeric_std library. The addition could be written as `a<=resize(b,a'length)+resize(b,a'length)`.Also, limiting the answer is not usually what you want to do in the case of overflow - it costs extra logic. If the carry is used for multi-word additions, you *really* don't want saturating arithmetic.
Martin Thompson