IMPLEMENTING ALU WITH OVERFLOW DETECTION ABILITY

C

chibiks

Hi all,

I am trying to implement a very simple 32-bit ALU capable of overflow
detection. Hence if the result of any computation (especially addition
and subtraction) results in a value > X'FFFFFFFF', then the system
should halt, freeze or a similar behaviour. Here is my code fragment
but it currently doesnt give expected behaviour - any suggestions
please?

LIBRARY IEEE;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
USE ieee.std_logic_arith.ALL;



-- The ALU unit

ENTITY ALU_32 IS
PORT (a,b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
opcode : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));

END ENTITY ALU_32;


ARCHITECTURE complex of ALU_32 is
signal undbit : bit;
signal overbit : bit;
BEGIN

-- Process is entered whenever the value of a, b or opcode changes
PROCESS(a,b,opcode)
VARIABLE alu_result : INTEGER; -- declares alu_result for result;
to be used within PROCESS only


BEGIN

CASE opcode is
--When addition
WHEN "001000" =>
alu_result:= CONV_INTEGER(a) + CONV_INTEGER(b); -- get the decimal
value of addition of a + b

--check for positive overflow
IF (alu_result > 31) THEN
overbit <= '1'; -- ALU does nothing
ELSE
overbit <= '0';
-- legal addition, it takes place
result <= CONV_STD_LOGIC_VECTOR(alu_result,32);
END IF;
-- check for negative overflow
IF (alu_result< -32) THEN
undbit <= '1'; -- ALU does nothing
ELSE
undbit <= '0';
-- legal negative addition, it takes place
result <= CONV_STD_LOGIC_VECTOR(alu_result,32);
END IF;
 
D

Dave Pollum

Hi all,

I am trying to implement a very simple 32-bit ALU capable of overflow
detection. Hence if the result of any computation (especially addition
and subtraction) results in a value > X'FFFFFFFF', then the system
should halt, freeze or a similar behaviour. Here is my code fragment
but it currently doesnt give expected behaviour - any suggestions
please?

LIBRARY IEEE;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
USE ieee.std_logic_arith.ALL;



-- The ALU unit

ENTITY ALU_32 IS
PORT (a,b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
opcode : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0));

END ENTITY ALU_32;


ARCHITECTURE complex of ALU_32 is
signal undbit : bit;
signal overbit : bit;
BEGIN

-- Process is entered whenever the value of a, b or opcode changes
PROCESS(a,b,opcode)
VARIABLE alu_result : INTEGER; -- declares alu_result for result;
to be used within PROCESS only


BEGIN

CASE opcode is
--When addition
WHEN "001000" =>
alu_result:= CONV_INTEGER(a) + CONV_INTEGER(b); -- get the decimal
value of addition of a + b

--check for positive overflow
IF (alu_result > 31) THEN
overbit <= '1'; -- ALU does nothing
ELSE
overbit <= '0';
-- legal addition, it takes place
result <= CONV_STD_LOGIC_VECTOR(alu_result,32);
END IF;
-- check for negative overflow
IF (alu_result< -32) THEN
undbit <= '1'; -- ALU does nothing
ELSE
undbit <= '0';
-- legal negative addition, it takes place
result <= CONV_STD_LOGIC_VECTOR(alu_result,32);
END IF;

I did a search within comp.lang.vhdl for "ALU" and "overflow". You may
find the following thread helpful:

http://groups.google.com/group/comp...nk=gst&q=ALU+overflow&rnum=7#8f64da52a605bcc1

Overflow and Carry flags are also discussed in "Max" Maxfield's book
"How Computers Do Math".
HTH
-Dave Pollum
 
W

Wolfgang Grafen

Hi,

please don't use the header capitalized as it means "shouting out loud"
which is generally considered as rude and annoying.

I see two potential problems with your code:
(1) integers are limited to the word length of your host processor. On a
32 bit machine you won't get results bigger or lower than 32 bits you
compare with. Even you are working at a 64 bit host it is better not
to use integers with more than 32 bit in your code (tests could be
performed at a lower specd machine).

I would use following template for declaring alu_result:

"""
LIBRARY ieee ;
USE ieee.std_logic_arith.all;


variable alu_result : signed(31 downto 0);
"""

(2) You check underflow and overflow against 31 but should be -(2**32) and
(2**32)-1

Regards

Wolfgang
 
W

Wolfgang Grafen

Typo, sorry
(2) You check underflow and overflow against 31 but should be -(2**32) and
(2**32)-1
2) You check underflow and overflow against 31 but should be -(2**31) and
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top