VHDL coding tips and tricks: VHDL code for Carry select adder

Monday, April 27, 2015

VHDL code for Carry select adder

A carry select adder is a special way of implementing a binary adder. Its simple yet fast adder. The block diagram below shows how you can implement a carry select adder.

                                           
                                                     (image from here)

The '+' blocks are full adders and mux's used are 2:1 size.

The VHDL codes are given below:

Fulladder.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity fulladder is
    port (: in std_logic;
            b : in std_logic;
           cin : in std_logic;
           sum : out std_logic;
           carry : out std_logic
         );
end fulladder;

architecture behavior of fulladder is

begin

sum <= a xor b xor cin;
carry <= (and b) or (cin and (xor b));

end;


Multiplexer2.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity multiplexer2 is
port (
      i0 : in std_logic;
      i1 : in std_logic;
     sel : in std_logic;
     bitout : out std_logic
     );
end multiplexer2;

architecture Behavioral of multiplexer2 is
begin

process(i0,i1,sel)
begin
case sel is
  when '0=> bitout <= i0;
  when others => bitout <= i1; 
end case; 
end process;

end Behavioral;

carryselectadder.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity carry_select_adder is
port( A,B : in std_logic_vector(3 downto 0);
        cin : in std_logic;
        S : out std_logic_vector(3 downto 0);
        cout : out std_logic
        );
end carry_select_adder;

architecture Behavioral of carry_select_adder is

COMPONENT fulladder is
    port (: in std_logic;
            b : in std_logic;
           cin : in std_logic;
           sum : out std_logic;
           carry : out std_logic
         );
end COMPONENT;

component multiplexer2 is
port (
      i0 : in std_logic;
      i1 : in std_logic;
     sel : in std_logic;
     bitout : out std_logic
     );
end component;

signal temp0,temp1,carry0,carry1 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";

begin

--for carry 0
fa00 : fulladder port map(A(0),B(0),'0',temp0(0),carry0(0));
fa01 : fulladder port map(A(1),B(1),carry0(0),temp0(1),carry0(1));
fa02 : fulladder port map(A(2),B(2),carry0(1),temp0(2),carry0(2));
fa03 : fulladder port map(A(3),B(3),carry0(2),temp0(3),carry0(3));

--for carry 1
fa10 : fulladder port map(A(0),B(0),'1',temp1(0),carry1(0));
fa11 : fulladder port map(A(1),B(1),carry1(0),temp1(1),carry1(1));
fa12 : fulladder port map(A(2),B(2),carry1(1),temp1(2),carry1(2));
fa13 : fulladder port map(A(3),B(3),carry1(2),temp1(3),carry1(3));

--mux for carry
mux_carry : multiplexer2 port map(carry0(3),carry1(3),cin,cout);
--mux's for sum
mux_sum0 : multiplexer2 port map(temp0(0),temp1(0),cin,S(0));
mux_sum1 : multiplexer2 port map(temp0(1),temp1(1),cin,S(1));
mux_sum2 : multiplexer2 port map(temp0(2),temp1(2),cin,S(2));
mux_sum3 : multiplexer2 port map(temp0(3),temp1(3),cin,S(3));


end Behavioral;


tb_adder.vhd  (testbench code)

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
ENTITY tb_adder IS
END tb_adder;
 
ARCHITECTURE behavior OF tb_adder IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT carry_select_adder
    PORT(
         A : IN  std_logic_vector(3 downto 0);
         B : IN  std_logic_vector(3 downto 0);
         cin : IN  std_logic;
         S : OUT  std_logic_vector(3 downto 0);
         cout : OUT  std_logic
        );
    END COMPONENT;
    
   signal A,B,S : std_logic_vector(3 downto 0) := (others => '0');
   signal cin,cout : std_logic := '0';
    signal error : integer := 0;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: carry_select_adder PORT MAP (
          A => A,
          B => B,
          cin => cin,
          S => S,
          cout => cout
        );

-- Stimulus process - all the input combinations are tested here.
--the number of errors are recorded in the signal named "error".
   stim_proc: process
   begin    
        cin <= '0';
      for i in 0 to 15 loop
            for j in 0 to 15 loop
                A <= conv_std_logic_vector(i,4);
                B <= conv_std_logic_vector(j,4);
                wait for 10 ns;
                if(conv_integer(cout & S) /= (i+j)) then
                    error <= error + 1;
                end if; 
            end loop;   
        end loop;
            
        cin <= '1';
      for i in 0 to 15 loop
            for j in 0 to 15 loop
                A <= conv_std_logic_vector(i,4);
                B <= conv_std_logic_vector(j,4);
                wait for 10 ns;
                if(conv_integer(cout & S) /= (i+j+1)) then
                    error <= error + 1;
                end if;
            end loop;   
        end loop;   
      wait;
   end process;

END;


Waveform after functional simulation:

The code was simulated using Xilinx ISIM. Its also synthesisable.




No comments:

Post a Comment