--////////////////////////////////////////////////////////////////////////////////////////
--////////////////////////////// LPM COMPONENT DECLNS for Verplex ////////////////////////
--////////////////////////////////////////////////////////////////////////////////////////


library IEEE;
use IEEE.std_logic_1164.all;

PACKAGE lpm_components IS

TYPE std_logic_2d IS ARRAY (NATURAL RANGE <>, NATURAL RANGE <>) of STD_LOGIC;

-- convert std_logic_vector to integer
function to_int (arg : in std_logic_vector) return integer ;

COMPONENT lpm_and
        generic (
		LPM_WIDTH : natural;  
                LPM_SIZE : natural; 
                LPM_TYPE : string := "LPM_AND";
                LPM_HINT : string := "UNUSED"
	);
        port (
		DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0); 
                RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0)
	); 
end COMPONENT; 
 
COMPONENT lpm_or 
        generic (
		LPM_WIDTH : natural;   
                LPM_SIZE : natural;    
                LPM_TYPE : string := "LPM_OR";
                LPM_HINT : string := "UNUSED"
	);
        port (
		DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0); 
                RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0)
	); 
end COMPONENT; 

COMPONENT lpm_xor
        generic (
		LPM_WIDTH : natural;    
                LPM_SIZE : natural;    
                LPM_TYPE : string := "LPM_XOR";
                LPM_HINT : string := "UNUSED"
	);
        port (
		DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0); 
                RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0)
	); 
end COMPONENT; 
COMPONENT lpm_mux
        generic (
		LPM_WIDTH : natural;    
                LPM_SIZE : natural;    
                LPM_WIDTHS : natural;    
                LPM_PIPELINE : natural := 0;
                LPM_TYPE : string := "LPM_MUX";
                LPM_HINT : string := "UNUSED"
	);
        port (
		DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0);
                ACLR : in std_logic := '0';
                CLOCK : in std_logic := '0';
                CLKEN : in std_logic := '1';
                SEL : in std_logic_vector(LPM_WIDTHS-1 downto 0); 
                RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0)
	);
end COMPONENT;

COMPONENT pipeline_internal_fv
	generic (
		DATA_WIDTH : natural := 1;
		LATENCY : natural := 2
	);
	port (
		CLK : in std_logic;
		ENA : in std_logic;
		CLR : in std_logic;
		D   : in  std_logic_vector(DATA_WIDTH-1 DOWNTO 0);
		PIPED : out std_logic_vector(DATA_WIDTH-1 DOWNTO 0)
	);
END COMPONENT;

end;

PACKAGE BODY lpm_components IS
function to_int (arg : in std_logic_vector) return integer is
variable result : integer := 0;
begin
    result := 0;
    for i in arg'range loop
        if arg(i) = '1' then
            result := result + 2**i;
        end if;
    end loop;
    return result;
end to_int;
end;

