--------------------------------------------------------------------------------
-- Company: MICROSEMI
--
-- File: Extended_adder_3_input.vhd
--
-- File history:
--      v1.0: APR 14-06-13: 
--
-- Description		: Implementation of 3-input extended addition
--
-- Targeted device	: Family	:: SmartFusion2  
-- 					  Die		:: M2S050T
--					  Package	:: 896 FBGA	
--			Author	: PHANIKIRAN T
--------------------------------------------------------------------------------


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

entity Extended_adder_3_input is
port(	clk			: in std_logic;
		reset_n		: in std_logic; 
		INPUTA		: in std_logic_vector(17 downto 0);
		INPUTB		: in std_logic_vector(17 downto 0);
		INPUTC		: in std_logic_vector(51 downto 0);
		INPUTD		: in std_logic_vector(51 downto 0);
		
		AddOutput	: out std_logic_vector(51 downto 0)
		
         );
end Extended_adder_3_input;


architecture Extended_adder_3_input_arch of Extended_adder_3_input is


component dotp_multadd is
    -- Port list
    port(
        -- Inputs
        A0        : in  std_logic_vector(17 downto 0);
        A0_ACLR_N : in  std_logic;
        A0_EN     : in  std_logic;
        A0_SCLR_N : in  std_logic;
        B0        : in  std_logic_vector(17 downto 0);
        B0_ACLR_N : in  std_logic;
        B0_EN     : in  std_logic;
        B0_SCLR_N : in  std_logic;
        C         : in  std_logic_vector(43 downto 0);
		CDIN      : in  std_logic_vector(43 downto 0);
        CLK       : in  std_logic;
        C_ACLR_N  : in  std_logic;
        C_EN      : in  std_logic;
        C_SCLR_N  : in  std_logic;
        P_ACLR_N  : in  std_logic;
        P_EN      : in  std_logic;
        P_SCLR_N  : in  std_logic;
        -- Outputs
        CARRYOUT  : out std_logic;
        CDOUT     : out std_logic_vector(43 downto 0);
        P         : out std_logic_vector(43 downto 0)
        );
end component dotp_multadd;

component dotp_multadd1 is
    -- Port list
    port(
        -- Inputs
        B0       : in  std_logic_vector(17 downto 0);
        C        : in  std_logic_vector(43 downto 0);
        CLK      : in  std_logic;
        P_ACLR_N : in  std_logic;
        P_EN     : in  std_logic;
        P_SCLR_N : in  std_logic;
        -- Outputs
        CDOUT    : out std_logic_vector(43 downto 0);
        P        : out std_logic_vector(43 downto 0)
        );
end component dotp_multadd1;

  
signal S			: std_logic; 
signal X			: std_logic; 
signal Z			: std_logic_vector(43 downto 0);

signal C0			: std_logic_vector(43 downto 0); 
signal CDOUT		: std_logic_vector(43 downto 0);

signal INPUTD_Sig	: std_logic_vector(43 downto 0);

signal INPUTC_reg0	: std_logic_vector(8 downto 0); 
signal INPUTC_reg1	: std_logic_vector(8 downto 0); 
signal INPUTD_reg0	: std_logic_vector(8 downto 0); 
signal INPUTD_reg1	: std_logic_vector(8 downto 0); 

signal Adderop_reg	: std_logic_vector(8 downto 0); 
signal Adderop_reg1	: std_logic_vector(8 downto 0); 

signal Res_Upper	: std_logic_vector(8 downto 0); 
signal Res_Upper_reg: std_logic_vector(8 downto 0);

begin



C0 			<= ('0'& INPUTC(42 downto 0));
INPUTD_Sig 	<= ('0'& INPUTD(42 downto 0));	

U0:dotp_multadd1 

    port map(
  
        -- Inputs
        B0       => (OTHERS => '0'),
        C        => INPUTD_Sig,
        CLK      => clk,
        P_ACLR_N => '1',
        P_EN     => '1',
        P_SCLR_N => '1',
        -- Outputs
        CDOUT    => CDOUT,
        P        => OPEN
        );





U1:dotp_multadd 

    port map(
        -- Inputs
        A0        => INPUTA,
        A0_ACLR_N => '1',
        A0_EN     => '1',
        A0_SCLR_N => '1',
        B0        => INPUTB,
        B0_ACLR_N => '1',
        B0_EN     => '1',
        B0_SCLR_N => '1',
        C         =>  C0,
		CDIN 	  =>  CDOUT,	
        CLK       =>  clk,
        C_ACLR_N  => '1',
        C_EN      => '1',
        C_SCLR_N  => '1',
        P_ACLR_N  => '1',
        P_EN      => '1',
        P_SCLR_N  => '1',

        -- Outputs 
		CARRYOUT  => X,
		CDOUT     => OPEN,
        P         => Z 
        );
 			


	process(clk, reset_n)
	begin
		if (reset_n = '0') then
			INPUTC_reg0 <= (others => '0');  
			INPUTC_reg1 <= (others => '0');  
			INPUTD_reg0 <= (others => '0');  
			INPUTD_reg1 <= (others => '0');  
		else
			if(rising_edge(clk))then
					INPUTC_reg0 <=  INPUTC(51 downto 43);
					INPUTC_reg1 <=  INPUTC_reg0;
					INPUTD_reg1 <=  INPUTD(51 downto 43);
--					INPUTD_reg1 <=  INPUTD_reg0;
			 end if;	
		end if;
	end process;


	process(clk, reset_n)
	begin
		if (reset_n = '0') then
			Adderop_reg	 <= (others => '0');    
		else
			if(rising_edge(clk))then
					Adderop_reg	  <= INPUTC_reg1+ INPUTD_reg1;
					
			 end if;	
		end if;
	end process;	

	S <= Z(43) AND X;
	Res_Upper(8 downto 2)  <= (OTHERS => S);
	Res_Upper(1)  <= X;
	Res_Upper(0)  <= Z(43);


	process(clk, reset_n)
	begin
		if (reset_n = '0') then
			Res_Upper_reg	 <= (others => '0');    
		else
			if(rising_edge(clk))then
				Res_Upper_reg	  <= Res_Upper;
			end if;	
		end if;
	end process;

	process(clk, reset_n)
	begin
		if (reset_n = '0') then
			Adderop_reg1	<= (others => '0');  
		else
			if(rising_edge(clk))then
				Adderop_reg1	<= Adderop_reg + Res_Upper_reg;
			 end if;	
		end if;
	end process;	

	

AddOutput <= Adderop_reg1 & Z(42 downto 0);

end Extended_adder_3_input_arch;


