IMPLEMENTING ALU WITH OVERFLOW DETECTION ABILITY

  • Thread starter chibiks@googlemail.com
  • Start date
C

chibiks@googlemail.com

Guest
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;
 
chibiks@googlemail.com wrote:
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.lang.vhdl/browse_frm/thread/daf6e5740cb09ee9/8f64da52a605bcc1?lnk=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
 
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


chibiks@googlemail.com wrote:
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;
 
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
(2**31)-1
 

Welcome to EDABoard.com

Sponsor

Back
Top