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.

Full adder with 3 input signals (vectors)

Status
Not open for further replies.

Rorsh14

Newbie level 4
Joined
Aug 25, 2016
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
79
Hello, I'm learning VHDL and currently trying to implement full adder that has three inputs (a, b, c), and carry_in as is required for this type of adder.

My idea was to implement regular full adder>
Code:
entity full_adder is
    Port ( a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           c_in : in  STD_LOGIC;
           sum : out  STD_LOGIC;
           c_out : out  STD_LOGIC);
end full_adder;

architecture Behavioral of full_adder is
begin
	sum <= a xor b xor c_in;
	c_out <= (a and b) or (c_in and a) or (c_in and b);
end Behavioral;


--create a temporary signal of 12 bits in length, and store sum of a and b in there, then, add this signal and c and that would be the output
Code:
entity full_adder_3bit_12bit is
    Port ( a : in  STD_LOGIC_VECTOR (11 downto 0);
           b : in  STD_LOGIC_VECTOR (11 downto 0);
           c : in  STD_LOGIC_VECTOR (11 downto 0);
           c_in : in  STD_LOGIC;
           sum : out  STD_LOGIC_VECTOR (11 downto 0);
           c_out : out  STD_LOGIC);
end full_adder_3bit_12bit;

architecture Behavioral of full_adder_3bit_12bit is
	component full_adder
		port
		(
			a, b, c_in: in std_logic;
			sum, c_out: out std_logic
		);
	end component;
	
	signal carry1 : std_logic_vector(11 downto 0);
	signal carry2 : std_logic_vector(11 downto 0);
	signal sum_temp: std_logic_vector(11 downto 0);
begin

	FA1: full_adder port map(a(0), b(0), c_in, sum_temp(0), carry1(0));
	FA2: full_adder port map(a(1), b(1), carry1(0), sum_temp(1), carry1(1));
	FA3: full_adder port map(a(2), b(2), carry1(1), sum_temp(2), carry1(2));
	FA4: full_adder port map(a(3), b(3), carry1(2), sum_temp(3), carry1(3));
	FA5: full_adder port map(a(4), b(4), carry1(3), sum_temp(4), carry1(4));
	FA6: full_adder port map(a(5), b(5), carry1(4), sum_temp(5), carry1(5));
	FA7: full_adder port map(a(6), b(6), carry1(5), sum_temp(6), carry1(6));
	FA8: full_adder port map(a(7), b(7), carry1(6), sum_temp(7), carry1(7));
	FA9: full_adder port map(a(8), b(8), carry1(7), sum_temp(8), carry1(8));
	FA10: full_adder port map(a(9), b(9), carry1(8), sum_temp(9), carry1(9));
	FA11: full_adder port map(a(10), b(10), carry1(9), sum_temp(10), carry1(10));
	FA12: full_adder port map(a(11), b(11), carry1(10), sum_temp(11), carry1(11));
	
	FA13: full_adder port map(sum_temp(0), c(0), '0', sum(0), carry2(0));
	FA14: full_adder port map(sum_temp(1), c(1), carry2(0), sum(1), carry2(1));
	FA15: full_adder port map(sum_temp(2), c(2), carry2(1), sum(2), carry2(2));
	FA16: full_adder port map(sum_temp(3), c(3), carry2(2), sum(3), carry2(3));
	FA17: full_adder port map(sum_temp(4), c(4), carry2(3), sum(4), carry2(4));
	FA18: full_adder port map(sum_temp(5), c(5), carry2(4), sum(5), carry2(5));
	FA19: full_adder port map(sum_temp(6), c(6), carry2(5), sum(6), carry2(6));
	FA20: full_adder port map(sum_temp(7), c(7), carry2(6), sum(7), carry2(7));
	FA21: full_adder port map(sum_temp(8), c(8), carry2(7), sum(8), carry2(8));
	FA22: full_adder port map(sum_temp(9), c(9), carry2(8), sum(9), carry2(9));
	FA23: full_adder port map(sum_temp(10), c(10), carry2(9), sum(10), carry2(10));
	FA24: full_adder port map(sum_temp(11), c(11), carry2(10), sum(11), carry2(11));
	
	c_out <= (a(11) and b(11)) xor (a(11) and c(11)) xor (b(11) and c(11));

end Behavioral;

However, I realised that when all 4 inputs are '1', there is no place for output, because in this case output would be 3 bits long (100b = 4dec).

My ultimate goal is to create an adder that can add up three 12-bit vectors, so total of 13 bit output would be possible (12 bit vector + carry_out). So, I tried this: create a temporary signal of 12bits in length, and store sum of a and b in there, then, add this signal and c and that would be the output. As you can see. However, I noticed that if this temporary signal had carry bit set, overflow could happen again
1111 = 15
1000 = 8
1010 = 10

Sum = 33 = 100001 - 6 bits, when I hoped for only 5.

I found that I could use multiple carry bits, but can someone tell me how to do it? And how to "prioritize" those carry bits compared to each other?

How could I solve this?
 
Last edited by a moderator:

I'm sorry but I don't see an option of edition first post, so I had to do a double post.

I have a new idea, can you please tell me if this makes sense and would it work?
So, there are 12 bit vectors, to classic addition (like presented above on first 11 bits (10 downto 0)), and then, we have 4 one bit numbers->a(12), b(12), c(12), carry from addition...
My idea is to convert all these numbers to integers (so 1 or 0) and add them, then, convert that number to 3bit vector(max value could be 4 = 100b), and merge this small vector to what was calculated earlier

output <= add_on & addition
add_on (3 bits in length)

I do realise that my output would be 15 bits, but I could handle that.
addition (11 bits in length)
 

hi Rorsh14,
why are you go for complicated thing, no need to write unnecessary components.
check top level modified program

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
entity full_adder_3bit_12bit is
    Port ( a : in  STD_LOGIC_VECTOR (11 downto 0);
           b : in  STD_LOGIC_VECTOR (11 downto 0);
           c : in  STD_LOGIC_VECTOR (11 downto 0);
           c_in : in  STD_LOGIC;
           sum : out  STD_LOGIC_VECTOR (11 downto 0);
           c_out : out  STD_LOGIC);
end full_adder_3bit_12bit;
 
architecture Behavioral of full_adder_3bit_12bit is
    component full_adder
        port
        (
            a, b, c_in: in std_logic;
            sum, c_out: out std_logic
        );
    end component;
    
    signal carry1 : std_logic_vector(10 downto 0);
    
begin
 
    FA1: full_adder port map(a(0), b(0), c_in, sum(0), carry1(0));
    FA2: full_adder port map(a(1), b(1), carry1(0), sum(1), carry1(1));
    FA3: full_adder port map(a(2), b(2), carry1(1), sum(2), carry1(2));
    FA4: full_adder port map(a(3), b(3), carry1(2), sum(3), carry1(3));
    FA5: full_adder port map(a(4), b(4), carry1(3), sum(4), carry1(4));
    FA6: full_adder port map(a(5), b(5), carry1(4), sum(5), carry1(5));
    FA7: full_adder port map(a(6), b(6), carry1(5), sum(6), carry1(6));
    FA8: full_adder port map(a(7), b(7), carry1(6), sum(7), carry1(7));
    FA9: full_adder port map(a(8), b(8), carry1(7), sum(8), carry1(8));
    FA10: full_adder port map(a(9), b(9), carry1(8), sum(9), carry1(9));
    FA11: full_adder port map(a(10), b(10), carry1(9), sum(10), carry1(10));
    FA12: full_adder port map(a(11), b(11), carry1(10), sum(11), c_out);
 
 
end behavioral;

 

Hello and thank you for your fast reply. However, this doesn't solve my problem. You still have only one carry bit available, which is not enough. Not to mention you never use "c" vector.

EDIT: I believe I have found a solution.. Can anyone experienced and well versed please review and tell me if I'm mistaken somewhere?

entity full_adder_12bit is
Port ( a : in STD_LOGIC_VECTOR (11 downto 0);
b : in STD_LOGIC_VECTOR (11 downto 0);
c_in : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR (11 downto 0);
c_out : out STD_LOGIC);
end full_adder_12bit;

architecture Behavioral of full_adder_12bit is
component full_adder
port
(
a, b, c_in: in std_logic;
sum, c_out: out std_logic
);
end component;

signal carry: std_logic_vector(10 downto 0);
begin
FA1: full_adder port map(a(0), b(0), c_in, sum(0), carry(0));
FA2: full_adder port map(a(1), b(1), carry(0), sum(1), carry(1));
FA3: full_adder port map(a(2), b(2), carry(1), sum(2), carry(2));
FA4: full_adder port map(a(3), b(3), carry(2), sum(3), carry(3));
FA5: full_adder port map(a(4), b(4), carry(3), sum(4), carry(4));
FA6: full_adder port map(a(5), b(5), carry(4), sum(5), carry(5));
FA7: full_adder port map(a(6), b(6), carry(5), sum(6), carry(6));
FA8: full_adder port map(a(7), b(7), carry(6), sum(7), carry(7));
FA9: full_adder port map(a(8), b(8), carry(7), sum(8), carry(8));
FA10: full_adder port map(a(9), b(9), carry(8), sum(9), carry(9));
FA11: full_adder port map(a(10), b(10), carry(9), sum(10), carry(10));
FA12: full_adder port map(a(11), b(11), carry(10), sum(11), c_out);

end Behavioral;

entity full_adder_3bit_12bit is
Port ( a : in STD_LOGIC_VECTOR (11 downto 0);
b : in STD_LOGIC_VECTOR (11 downto 0);
c : in STD_LOGIC_VECTOR (11 downto 0);
c_in : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR (11 downto 0);
c_out : out STD_LOGIC_VECTOR (1 downto 0));
end full_adder_3bit_12bit;

architecture Behavioral of full_adder_3bit_12bit is
component full_adder_12bit
port
(
a, b: in std_logic_vector(11 downto 0);
c_in: in std_logic;
sum: out std_logic_vector(11 downto 0);
c_out: out std_logic
);
end component;

signal carry1v : std_logic_vector(1 downto 0);
signal carry2v : std_logic_vector(1 downto 0);
signal carry1un : unsigned(1 downto 0);
signal carry2un : unsigned(1 downto 0);
signal sum_carry : unsigned(1 downto 0);
signal carry1 : std_logic;
signal carry2 : std_logic;
signal sum_temp: std_logic_vector(11 downto 0);

begin
FA12_1: full_adder_12bit port map(a, b, c_in, sum_temp, carry1);
FA12_2: full_adder_12bit port map(sum_temp, c, '0', sum, carry2);

carry1v <= '0' & carry1;
carry2v <= '0' & carry2;

carry1un <= unsigned(carry1v);
carry2un <= unsigned(carry2v);

sum_carry <= carry1un + carry2un;

c_out <= std_logic_vector(sum_carry);

end Behavioral;
 
Last edited:

If you're going to use addition just for the carries, why not go the whole hog and just make your life easy and use + for the whole adder?


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity full_adder_12bit is
  port (
    a : in unsigned(11 downto 0);
    b : in unsigned(11 downto 0);
 
   c : out unsigned(12 downto 0);
  );
end entity full_adder_12bit;
 
architecture rtl of full_adder_12bit is
begin
  c <= ('0' & a) + ('0' & b);
end architecture rtl;



Thats what the libraries are there for.
 
Don't know really, I just thought maybe I would need it for something else, and I'm still learning, so I considered this project as an exercise. To be honest, I would never think of what you did here...

Thanks a lot for your comment, really helpful!
 

Don't know really, I just thought maybe I would need it for something else, and I'm still learning, so I considered this project as an exercise. To be honest, I would never think of what you did here...

Thanks a lot for your comment, really helpful!

look for some textbook on hardware design & synthesis. you were trying to do something that looks like structural instead of behavioural. there is no need for that, since the synthesis tool will not respect what you wrote anyway.
 

Using the code from post #3 you mentioned the problem with the 2-bits of carry produced when adding three 12-bit numbers, which wasn't accounted for in that code.

You needed an extra full adder instances...


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
FA1: full_adder port map(a(0), b(0), c_in, sum(0), carry(0));
    FA2: full_adder port map(a(1), b(1), carry(0), sum(1), carry(1));
    FA3: full_adder port map(a(2), b(2), carry(1), sum(2), carry(2));
    FA4: full_adder port map(a(3), b(3), carry(2), sum(3), carry(3));
    FA5: full_adder port map(a(4), b(4), carry(3), sum(4), carry(4));
    FA6: full_adder port map(a(5), b(5), carry(4), sum(5), carry(5));
    FA7: full_adder port map(a(6), b(6), carry(5), sum(6), carry(6));
    FA8: full_adder port map(a(7), b(7), carry(6), sum(7), carry(7));
    FA9: full_adder port map(a(8), b(8), carry(7), sum(8), carry(8));
    FA10: full_adder port map(a(9), b(9), carry(8), sum(9), carry(9));
    FA11: full_adder port map(a(10), b(10), carry(9), sum(10), carry(10));
    FA12: full_adder port map(a(11), b(11), carry(10), sum(11), carry(11));  -- this is the first carry bit
    FA13: full_adder port map('0', '0', carry(11), sum(12), c_out);  -- this is the second carry bit


This is similar to the code provided by Tricky with the unsigned extended '0's being added to the a and b inputs. Though for three 12-bit adds it should have been ("00" & a) + ("00" & b) to avoid any overflow.

The extra code you added in your original post to generate the carry was unnecessary as the carry is rippled through each FA until you get the final carry. You only need to sign extend (in this case 0 extend as you are interpreting the values as unsigned) the inputs to get the correct number of carry bits.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top