Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Unsigned and Signed Addition and subtraction VHDL

Status
Not open for further replies.

raguna

Junior Member level 3
Joined
Apr 23, 2010
Messages
30
Helped
4
Reputation
8
Reaction score
4
Trophy points
1,288
Location
Earth
Activity points
1,540
Hi all!
I am trying to design an ALU which does signed addition & subtraction and unsigned addition & subtraction. I have following code written, but does not work.

For unsigned : I used simple R<= A+B and R<= A-B; for addition and subtraction
For Signed: I tried to change the type of A,B to Signed and perform addition. And I am not sure how to check for overflow/underflow. Can someone please help me in this?

Code:
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all;

 
entity lab5 is 
 port(CLK: in std_logic; 
 A,B : in std_logic_vector(15 downto 0); 
 R : out std_logic_vector(15 downto 0); 
 Overflow : out std_logic);
end lab5; 
 
architecture archi of lab5 is 

 signal  tmp : std_logic_vector( 16 downto 0);
 variable sgnA, sgnB : SIGNED (16 downto 0);
 variable sgnout : SIGNED (16 downto 0);
 variable usgnA, usgnB: UNSIGNED (16 downto 0);
 variable usgnout : UNSIGNED (16 downto 0);
 begin 
 
 process (CLK) 
 begin 
	sgnA := signed(A'high+1 downto 0);
	sgnB := signed(B'high+1 downto 0);
	usgnA := unsigned(A);
	usgnB := unsigned(B);
	if (CLK'event and CLK='1') then 
		
		if(AluOp = "00000") then
		{R <= A + B; --Unsigned addition
		 Overflow <= A(15) and B(15);}

		elsif(AluOp = "00001") then
			{R <= A-B; --treating A & B as unsigned integers 
			 Overflow <= (A<B)?1:0; -- For underflow case 	}
		elsif(AluOp = "00010") then	
			{sgnout=sgnA-sgnB;--treating A & B as unsigned integers 
				R <= std_logic_vector(sgnout);	--Not sure how to do overflow in signed}
		elsif(AluOp = "00011") then	
			{sgnout=sgnA-sgnB;--treating A & B as unsigned integers 
				R <= std_logic_vector(sgnout);	}
 
Last edited:

Quick hints:

Use syntax tags for your code:

Define "but does not work" , we do not read minds.

Include your testbench that you didn't write, and screenshot of running the testbench that you didn't write.
 

easiest way to check for over/underflow - add an extra bit to the input operands, and then check the overflow bit in the result:

unsigned:

op <= ('0' &a) + ('0' & b);
overflow = op(MSB);

similarly for signed, extend the sign bit (use the resize function), check the new MSB, and then check the MSB of the two inputs to check for over/underflow.

op <= resize(a, op'length) - resize(b, op'length);
 

Hi TrickyDicky!
Thanks for your reply. I am having a syntax problem saying,"Can't determine the definition of operator "+""

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL; 
--use IEEE.STD_LOGIC_SIGNED.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 entity ALU16 is port
 ( A: in std_logic_vector (15 downto 0);
 B: in std_logic_vector (15 downto 0);
 AluOp: in std_logic_vector (4 downto 0);
 shamt: in std_logic_vector (2 downto 0);
 Zero: out std_logic;
 Overflow: out std_logic;
 R: out std_logic_vector (15 downto 0)
 );
 end ALU16;
 
 
 architecture RTL of ALU16 is
 signal  temp : std_logic_vector( 16 downto 0);
 signal usgnA, usgnB, Reg1 : unsigned(15 downto 0);
 signal sgnA, sgnB, Reg2 : signed(15 downto 0);
 
 begin
 
 process(AluOp)
 variable p : integer range 0 to 15;
 begin
 
--usgnA <= unsigned(A);
--usgnB <= unsigned(B);

sgnA <= signed(A);
sgnB <= signed(B);

	
 case AluOp is

	when "00000" =>
		--Reg1 <= usgnA + usgnB; 
		temp <= ('0' & A) + ('0' & B);
		Overflow <= temp(16);
		--temp <= A + B;
		R<=temp(15 downto 0);
		--Overflow <= A(15) and B(15);
			
--	when "00001" =>
--		--Reg1 <= usgnA - usgnB;
--		R<=A-B;
--		if (A < B) then Overflow<= '1';
--		else Overflow<= '0';
--		end if;
--		
--	when "00010" =>
--		Reg2 <= sgnA + sgnB;
--		R<=std_logic(Reg2);
--		Overflow <= A(14) and B(14);
--		
--	when "00011" =>
--		R <= sgnA - sgnB;
--		R<=std_logic(Reg2);
--		if (sgnA < sgnB) then Overflow<= '1';
--		else Overflow<= '0';
--		end if;
--	
--	when "00100" =>
--		if(A < B) then
--		R <= "1111111111111111";
--		else
--		R<= "0000000000000000";
--		end if;

--		when "00101" =>
--			 for i in 0 to 15 loop
--				R(i)<= A(i) and B(i);
--				end loop;
--			
--		when "00110" =>
--			 for i in 0 to 15 loop
--				R(i)<= A(i) or B(i);
--				end loop;
--			
--			
--		when "00111" =>
--			 for i in 0 to 15 loop
--				R(i)<= not (A(i) or B(i));
--				end loop;
--				
--			
--		when "01000" =>
--			for i in 0 to 15 loop
--				R(i)<= (A(i) xor B(i));
--				end loop;
--			
--		when "01001" =>
--			 for i in 0 to 15 loop
--				R(i)<= not A(i);
--				end loop;
--			
--		when "01010" =>
--			 	temp <= A;
--				temp <= shift_left(A,to_integer(shamt));
--				p :=to_integer(shamt);
--				for i in 1 to 3 loop
--				temp(i-1) <= '0';
--				end loop; 
--				R<= temp;
--			
--		
--		when "01011" =>
--			 	temp <= A;
--				temp <= shift_right(A,to_integer(shamt));
--				p :=to_integer(shamt);
--				for i in 1 to 3 loop
--				temp(i-1) <= '0';
--				end loop; 
--				R<= temp;
--			
--		when "01100" =>
--			 	temp <= A;
--				temp <= shift_right(A,to_integer(shamt));
--				p :=to_integer(shamt);
--				for i in 1 to 3 loop
--				temp(i-1) <= A(15);
--				end loop; 
--				R<= temp;
		
	when others =>
		NULL;
 
--	if( R = "0000000000000000" ) then
--			Zero <= '1';
--		else Zero <='0';
--		end if;
		
		
 end case;
 end process;
end RTL;
 

there is no definition of + or - for std_logic_Vector cast it to unsigned as TrickyDicky said
 

hai, im newbie....any idea for this..?

ARCHITECTURE beza OF beza IS
BEGIN
PROCESS (clk)
variable d : integer := 2;
variable a : integer := 5;
variable b : integer := 7;
BEGIN
IF clk'EVENT AND clk='1'THEN
c<=(a-b) / d;

the output should be -1.. but i got 1.

and if i change variable a into 3 and variable b into 9 the output from simulation is 253.. it should be -3

may someone help me
 

the output should be -1.. but i got 1.

and if i change variable a into 3 and variable b into 9 the output from simulation is 253.. it should be -3

may someone help me
According to your second case the first case output should be 255 check once.Actually 253 (binary) is the 2's complement of 3 which is equal to -3.better change radix representation to signed in your simulation.
 

According to your second case the first case output should be 255 check once.Actually 253 (binary) is the 2's complement of 3 which is equal to -3.better change radix representation to signed in your simulation.

LIBRARY ieee;
USE ieee.All;

ENTITY beza IS
PORT (
clk : IN bit;
c : OUT integer RANGE -127 TO 127
);
END beza;
ARCHITECTURE beza OF beza IS
BEGIN
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk='1'THEN
variable d : integer := 2;
variable a : integer := 5;
variable b : integer := 7;
c<=(a-b) / d;

END IF;
END PROCESS;
END beza;

sory i dont get it..

here my full coding
 

I doubt this is your full code because it has many syntax errors.

Also - you have a testbench for this?
 

no.. because i run this code in quartus version 8.1

there is no error in the simulation

hmm


sory.. i send wrong code.. this is the actual one



sory.. this is the correct one...[/QUOTE]

LIBRARY ieee;
USE ieee.All;

ENTITY beza IS
PORT (
clk : IN bit;
c : OUT integer RANGE -127 TO 127
);
END beza;
ARCHITECTURE beza OF beza IS
BEGIN
PROCESS (clk)
variable d : integer := 2;
variable a : integer := 5;
variable b : integer := 7;
BEGIN
IF clk'EVENT AND clk='1'THEN
c<=(a-b) / d;

END IF;
END PROCESS;
END beza;
 

Please be clear.
Your origional post said you had problem in simulation. Now you say the simulation is fine - so what is not working?
 
i mean the simulation doesnt show any error.. but the output is not what i want..

for ie :

c<= (a-b)/d
the output should be -1 if
variable d : integer := 2;
variable a : integer := 5;
variable b : integer := 7;

but in simulation it shows 1. it should be -1

and if i change :
variable d : integer := 2;
variable a : integer := 3;
variable b : integer := 9;

it should be -3.. but simulation shows 253
 

Please post your waveform.

Btw, 253 is -3 in 2s compliment.
 

Screenshot (133).pngScreenshot (132).png

the first waveform is when the variable
d=2
a=5
b=8

and the second wavedorm is when the variable

d=2
a=3
b=9
 

As i said it is showing 255 in first case and 253 in second case.In order to convert them to required values -1 and -3 respectively.Right click on the output variable in the simulation waveform editor one pop up window appears choose radix to signed decimal and then re run simulations...
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top