Carry save adder is very useful when you have to add more than two numbers at a time. Normally if you have three numbers, the method would be to add the first two numbers together and then add the result to the third one. This causes so much delay.
In this post I have implemented a 4 bit carry save adder which adds three numbers at a time. You might want to see page 1 and 2 of this paper to get a better understanding of how this exactly works.
fulladder.vhd
I have used the same full adder code in this post.
CSA.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity CSA is
Port ( x : in unsigned (3 downto 0);
y : in unsigned (3 downto 0);
z : in unsigned (3 downto 0);
cout : out std_logic;
s : out unsigned (4 downto 0)
);
end CSA;
architecture Behavioral of CSA is
component fulladder is
port (a : in std_logic;
b : in std_logic;
cin : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end component;
signal c1,s1,c2 : unsigned (3 downto 0) := (others => '0');
begin
fa_inst10 : fulladder port map(x(0),y(0),z(0),s1(0),c1(0));
fa_inst11 : fulladder port map(x(1),y(1),z(1),s1(1),c1(1));
fa_inst12 : fulladder port map(x(2),y(2),z(2),s1(2),c1(2));
fa_inst13 : fulladder port map(x(3),y(3),z(3),s1(3),c1(3));
fa_inst20 : fulladder port map(s1(1),c1(0),c2(0),s(1),c2(1));
fa_inst21 : fulladder port map(s1(2),c1(1),c2(1),s(2),c2(2));
fa_inst22 : fulladder port map(s1(3),c1(2),c2(2),s(3),c2(3));
fa_inst23 : fulladder port map('0',c1(3),c2(3),s(4),cout);
s(0) <= s1(0);
end Behavioral;
tb_adder.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY tb_adder IS
END tb_adder;
ARCHITECTURE behavior OF tb_adder IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT CSA is
Port ( x : in unsigned (3 downto 0);
y : in unsigned (3 downto 0);
z : in unsigned (3 downto 0);
cout : out std_logic;
s : out unsigned (4 downto 0)
);
end COMPONENT;
signal x,y,z : unsigned(3 downto 0) := (others => '0');
signal s : unsigned(4 downto 0) := (others => '0');
signal cout : std_logic := '0';
signal error : integer := 0;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: CSA PORT MAP (x,y,z,cout,s);
-- Stimulus process - all the input combinations are tested here.
--the number of errors are recorded in the signal named "error".
stim_proc: process
begin
for i in 0 to 15 loop
for j in 0 to 15 loop
for k in 0 to 15 loop
x <= to_unsigned(i,4);
y <= to_unsigned(j,4);
z <= to_unsigned(k,4);
wait for 10 ns;
if(to_integer(cout & S) /= (i+j+k)) then
error <= error + 1;
end if;
end loop;
end loop;
end loop;
wait;
end process;
END;
Simulation waveform:
The simulated waveform in Xilinx ISIM would look like this:
In this post I have implemented a 4 bit carry save adder which adds three numbers at a time. You might want to see page 1 and 2 of this paper to get a better understanding of how this exactly works.
fulladder.vhd
I have used the same full adder code in this post.
CSA.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity CSA is
Port ( x : in unsigned (3 downto 0);
y : in unsigned (3 downto 0);
z : in unsigned (3 downto 0);
cout : out std_logic;
s : out unsigned (4 downto 0)
);
end CSA;
architecture Behavioral of CSA is
component fulladder is
port (a : in std_logic;
b : in std_logic;
cin : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end component;
signal c1,s1,c2 : unsigned (3 downto 0) := (others => '0');
begin
fa_inst10 : fulladder port map(x(0),y(0),z(0),s1(0),c1(0));
fa_inst11 : fulladder port map(x(1),y(1),z(1),s1(1),c1(1));
fa_inst12 : fulladder port map(x(2),y(2),z(2),s1(2),c1(2));
fa_inst13 : fulladder port map(x(3),y(3),z(3),s1(3),c1(3));
fa_inst20 : fulladder port map(s1(1),c1(0),c2(0),s(1),c2(1));
fa_inst21 : fulladder port map(s1(2),c1(1),c2(1),s(2),c2(2));
fa_inst22 : fulladder port map(s1(3),c1(2),c2(2),s(3),c2(3));
fa_inst23 : fulladder port map('0',c1(3),c2(3),s(4),cout);
s(0) <= s1(0);
end Behavioral;
tb_adder.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY tb_adder IS
END tb_adder;
ARCHITECTURE behavior OF tb_adder IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT CSA is
Port ( x : in unsigned (3 downto 0);
y : in unsigned (3 downto 0);
z : in unsigned (3 downto 0);
cout : out std_logic;
s : out unsigned (4 downto 0)
);
end COMPONENT;
signal x,y,z : unsigned(3 downto 0) := (others => '0');
signal s : unsigned(4 downto 0) := (others => '0');
signal cout : std_logic := '0';
signal error : integer := 0;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: CSA PORT MAP (x,y,z,cout,s);
-- Stimulus process - all the input combinations are tested here.
--the number of errors are recorded in the signal named "error".
stim_proc: process
begin
for i in 0 to 15 loop
for j in 0 to 15 loop
for k in 0 to 15 loop
x <= to_unsigned(i,4);
y <= to_unsigned(j,4);
z <= to_unsigned(k,4);
wait for 10 ns;
if(to_integer(cout & S) /= (i+j+k)) then
error <= error + 1;
end if;
end loop;
end loop;
end loop;
wait;
end process;
END;
Simulation waveform:
The simulated waveform in Xilinx ISIM would look like this: