--------------------------------------------------------------------------------
-- Company: MICROSEMI
--
-- File: Mult32x32_SingleMACC.vhd
--
-- File history:
--      v1.0: 14-06-13: 
--
-- Description		: Implementation of Mult32x32 with Single Mathblock
--
-- 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 Mult32x32_SingleMACC is
	port(
			clk	: in  std_logic;
		reset_n	: in  std_logic;
		mul_en	: in  std_logic;	
			A	: in  std_logic_vector(31 downto 0);
			B	: in  std_logic_vector(31 downto 0); 
		Result	: out std_logic_vector(63 downto 0);	 	   	   	             	     	     	     	            
		mul_result_valid	: out  std_logic	
         );
end Mult32x32_SingleMACC;

architecture Mult32x32_SF2_ARCH of Mult32x32_SingleMACC is

 component acc_0 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;
        ARSHFT17        : in  std_logic;
        ARSHFT17_ACLR_N : in  std_logic;
        ARSHFT17_EN     : in  std_logic;
        ARSHFT17_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;

        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 acc_0;
 

TYPE  State IS (  IDLE,
					S0,
					S1,
					S2,
					S3,
					S4,
					S5,
					S6,
	                S7
					);

SIGNAL   Curr_State	: State;

	--//*****  SIGNAL DECLARATIONS  *****//

--SIGNAL   C				: STD_LOGIC_VECTOR(43 DOWNTO 0);
SIGNAL   CDIN 			: STD_LOGIC_VECTOR(43 DOWNTO 0);
SIGNAL   P	 			: STD_LOGIC_VECTOR(43 DOWNTO 0);
--SIGNAL   CO	 			: STD_LOGIC;
SIGNAL	 A0				: std_logic_vector(17 downto 0);
SIGNAL	 B0				: std_logic_vector(17 downto 0); 
SIGNAL  P_SCLR_N		: STD_LOGIC;
SIGNAL  ARSHFT17		: STD_LOGIC;
SIGNAL  ARSHFT17_SCLR_N	: STD_LOGIC;

BEGIN


--//***** MAIN FSM FOR 3X32 MULTIPLIER *****//
 PROCESS(clk,reset_n)
   BEGIN
       IF (reset_n = '0') THEN
			Curr_State	<= IDLE;  
       ELSE
			IF(rising_edge(clk)) THEN
				CASE Curr_State IS
					WHEN IDLE	=>  IF(mul_en = '1')THEN
										Curr_State	<= S0;
									END IF;
					WHEN S0		=>  Curr_State	<= S1;	
					WHEN S1   	=>	Curr_State	<= S2;													
					WHEN S2   	=>	Curr_State	<= S3;
					WHEN S3   	=>	Curr_State	<= S4;
					WHEN S4    	=>	Curr_State	<= S5;
					WHEN S5    	=>	Curr_State	<= S6;
					WHEN S6    	=>	Curr_State	<= S7;
					WHEN S7    	=>	Curr_State	<= IDLE;
					WHEN OTHERS => NULL;
				END CASE;	
			END IF ;
		END IF ;
   END PROCESS;



   PROCESS(clk,reset_n)
   BEGIN
       IF (reset_n = '0') THEN
			A0 	 <= (OTHERS => '0');
			B0 	 <= (OTHERS => '0');								
			ARSHFT17 <= '0'; 
       ELSE
			IF(rising_edge(clk)) THEN
				CASE Curr_State IS
					
					WHEN S0		=> 	A0 	 <= '0'& A(16 DOWNTO 0);	
									B0 	 <= '0'& B(16 DOWNTO 0);
									ARSHFT17 <= '0';

					WHEN S1		=> 	A0 	 <= A(31) & A(31) & A(31)& A(31 DOWNTO 17);
									B0 	 <= '0'& B(16 DOWNTO 0);																
									ARSHFT17 <= '1';

					WHEN S2   	=>	A0	 <= '0'& A(16 DOWNTO 0);	
									B0 	 <= B(31) & B(31) & B(31)& B(31 DOWNTO 17);												
									ARSHFT17 <= '0';

					WHEN S3   	=>	A0 	 <= A(31) & A(31) & A(31)& A(31 DOWNTO 17);	
									B0 	 <= B(31) & B(31) & B(31)& B(31 DOWNTO 17);												
									ARSHFT17 <= '1';

                    WHEN OTHERS =>	A0 	 <= (OTHERS => '0');
									B0 	 <= (OTHERS => '0');																
									ARSHFT17 <= '0';
				END CASE;	
			END IF ;
		END IF ;
   END PROCESS;

		

	P_SCLR_N 		<= '0' WHEN(Curr_State = IDLE)ELSE '1';
	ARSHFT17_SCLR_N <= '0' WHEN(Curr_State = IDLE)ELSE '1';
	--C 	 <=  (OTHERS => '0');	

	PROCESS(clk,reset_n)
	BEGIN
    	IF(reset_n = '0') THEN
			Result(63 DOWNTO 0) <=(OTHERS => '0');
  		ELSE
			IF(rising_edge(clk)) THEN
				CASE Curr_State IS
					WHEN S3   	=>	Result(16 DOWNTO 0)  <= P(16 DOWNTO 0);
					WHEN S5   	=>	Result(33 DOWNTO 17) <= P(16 DOWNTO 0);
					WHEN S6   	=>	Result(63 DOWNTO 34) <= P(29 DOWNTO 0);
        	   		WHEN OTHERS =>	NULL;
				END CASE;	
			END IF;
		END IF;
	END PROCESS;


	PROCESS(clk,reset_n)
	BEGIN
    	IF(reset_n = '0') THEN
			mul_result_valid <= '0';
       ELSE
			IF(rising_edge(clk)) THEN
				IF(Curr_State = S6)THEN
					mul_result_valid <= '1';
				ELSE
					mul_result_valid <= '0';	
				END IF;
			END IF;
	   END IF;	
   	END PROCESS;


--//*****MACC INSTANTIATION
 
U1: acc_0
    -- Port list
    port map(
        -- Inputs
       	A0        => A0,
        A0_ACLR_N => reset_n,
        A0_EN     		=> '1',
        A0_SCLR_N 		=> '1',
        ARSHFT17      	=> ARSHFT17,
        ARSHFT17_ACLR_N => reset_n,
        ARSHFT17_EN     => '1',
        ARSHFT17_SCLR_N => ARSHFT17_SCLR_N,
        B0       		=> B0,
        B0_ACLR_N		=> reset_n,
        B0_EN    		=> '1',
        B0_SCLR_N 		=> '1',
        CLK       		=> clk,
        P_ACLR_N  		=> reset_n,
        P_EN      		=> '1',
        P_SCLR_N  		=> P_SCLR_N,
        -- Outputs

        CDOUT    		=> OPEN,
        P        		=> P
        );
          
                          		                        			    		    
end Mult32x32_SF2_arch; 

