OpenCores
URL https://opencores.org/ocsvn/xmatchpro/xmatchpro/trunk

Subversion Repositories xmatchpro

[/] [xmatchpro/] [trunk/] [xmw4-comdec/] [xmatch_sim7/] [lib/] [lpm/] [220model.vhd] - Rev 9

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------
--   This VHDL file was developed by Altera Corporation.  It may be
-- freely copied and/or distributed at no cost.  Any persons using this
-- file for any purpose do so at their own risk, and are responsible for
-- the results of such use.  Altera Corporation does not guarantee that
-- this file is complete, correct, or fit for any particular purpose.
-- NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.  This notice must
-- accompany any copy of this file.
--
--------------------------------------------------------------------------
-- LPM Synthesizable Models (Support string type generic)
-- These models are based on LPM version 220 (EIA-IS103 October 1998).
-------------------------------------------------------------------------
-- Version Quartus v1.1 (lpm 220)      Date 02/26/02
--
-- 02/26/02: FIX spr 98850, lpm_counter 32 bit problem.
-- 02/01/01: Fix SPR79628 and 80251; integer overfow in Leapfrog and 
--           Speedwave for lpm_fifo_dc.
-- 01/23/01: Adding use_eab=on support for lpm_ram_io, lpm_ram_dp and
--           lpm_ram_dq.
-- 01/22/01: Fix SPR76524. Fix LPM_CLSHIFT implementation of arith
--           shift right underflow to match megafunction impl.
--------------------------------------------------------------------------
-- Version Quartus v1.0 (lpm 220)      Date 12/8/00
--
-- 12/8/00: Fix lpm_fifo_dc compilation problem for VSS.
--------------------------------------------------------------------------
-- Version 2.2 (lpm 220)      Date 12/05/00
--
-- 1. Fixed LPM_COUNTER code to remove requirement to use '-explicit'
--    option in modelsim.
-- 2. Fixed LPM_ROM, LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO hex reading to
--    support width>32bits.
--------------------------------------------------------------------------
-- Version 2.1 (lpm 220)      Date 09/21/00
--
-- 1. Fixed LPM_SHIFTREG to perform left shift or right shift according
--    to LPM_DIRECTION value.
-- 2. Changed Q port of LPM_SHIFTREG to be initialized with 0's.
-- 3. Added validity check for LPM_DIRECTION value of LPM_SHIFTREG.
-- 4. Changed SHIFTOUT port of LPM_SHIFTREG to output LSB of Q when
--    LPM_DIRECTION is "RIGHT".
-- 5. Fixed LPM_CLSHIFT to correctly sign extend output.
-- 6. Corrected OVERFLOW and UNDERFLOW ports of LPM_CLSHIFT.
-- 7. Added parameter value validity check.
-- 8. Changed all positive or integer type parameters to natural type.
-- 9. Changed LPM_ROM to check for null init file name.
--10. Changed the behaviour of LPM_FIFO_DC to match that of Quartus.
--11. Changed Data port of LPM_LATCH to be initialized with 0's.
--12. Fixed LPM_CLSHIFT and LPM_MULT array sizes mismatch error.
--13. Fixed LPM_FF initial state of output.
--14. Added LPM_REMAINDERPOSITIVE parameter to LPM_DIVIDE.  This is a
--    non-LPM 220 standard parameter.  It defaults to TRUE for LPM 220
--    behaviour.
--15. Changed default value of CIN port of LPM_ADD_SUB when subtract.
--16. Changed output pipelines of LPM_ADD_SUB to be initialized with 0's.
--17. Corrected the interpretation of CIN port of LPM_COUNTER.
--18. Fixed COUT port of LPM_COUNTER to go high when count is all 1's.
--19. Changed Q port of LPM_ROM to be initialized with 0's.
--------------------------------------------------------------------------
-- Version 2.0 (lpm 220)      Date 01/11/00
--
-- 1. Fixed LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO and LPM_ROM to correctly
--    read in values from LPM_FILE (*.hex) when the DATA width is greater
--    than 16 bits.
-- 2. Explicit sign conversions are added to standard logic vector
--    comparisons in LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO, LPM_ROM, and
--    LPM_COMPARE.
-- 3. LPM_FIFO_DC is rewritten to have correct outputs.
-- 4. LPM_FIFO outputs zeros when nothing has been read from it, and
--    outputs LPM_NUMWORDS mod exp(2, LPM_WIDTHU) when it is full.
-- 5. Fixed LPM_DIVIDE to divide correctly.
--------------------------------------------------------------------------
-- Version 1.9 (lpm 220)      Date 11/30/99
--
-- 1. Fixed UNUSED file not found problem and initialization problem
--    with LPM_RAM_DP, LPM_RAM_DQ, and LPM_RAM_IO.
-- 2. Fixed LPM_MULT when SUM port is not used.
-- 3. Fixed LPM_FIFO_DC to enable read when rdclock and wrclock rise
--    at the same time.
-- 4. Fixed LPM_COUNTER comparison problem when signed library is loaded
--    and counter is incrementing.
-- 5. Got rid of "Illegal Character" error message at time = 0 ns when
--    simulating LPM_COUNTER.
--------------------------------------------------------------------------
-- Version 1.8 (lpm 220)      Date 10/25/99
--
-- 1. Some LPM_PVALUE implementations were missing, and now implemented.
-- 2. Fixed LPM_COUNTER to count correctly without conversion overflow,
--    that is, when LPM_MODULUS = 2 ** LPM_WIDTH.
-- 3. Fixed LPM_RAM_DP sync process sensitivity list to detect wraddress
--    changes.
--------------------------------------------------------------------------
-- Version 1.7 (lpm 220)      Date 07/13/99
--
-- Changed LPM_RAM_IO so that it can be used to simulate both MP2 and
--   Quartus behaviour and LPM220-compliant behaviour.
--------------------------------------------------------------------------
-- Version 1.6 (lpm 220)      Date 06/15/99
--
-- 1. Fixed LPM_ADD_SUB sign extension problem and subtraction bug.
-- 2. Fixed LPM_COUNTER to use LPM_MODULUS value.
-- 3. Added CIN and COUT port, and discarded EQ port in LPM_COUNTER to
--    comply with the specfication.
-- 4. Included LPM_RAM_DP, LPM_RAM_DQ, LPM_RAM_IO, LPM_ROM, LPM_FIFO, and
--    LPM_FIFO_DC; they are all initialized to 0's.
--------------------------------------------------------------------------
-- Version 1.5 (lpm 220)      Date 05/10/99
--
-- Changed LPM_MODULUS from string type to integer.
--------------------------------------------------------------------------
-- Version 1.4 (lpm 220)      Date 02/05/99
-- 
-- 1. Added LPM_DIVIDE module.
-- 2. Added CLKEN port to LPM_MUX, LPM_DECODE, LPM_ADD_SUB, LPM_MULT
--    and LPM_COMPARE
-- 3. Replaced the constants holding string with the actual string.
--------------------------------------------------------------------------
-- Version 1.3                Date 07/30/96
--
-- Modification History
--
-- 1. Changed the DEFAULT value to "UNUSED" for LPM_SVALUE, LPM_AVALUE,
-- LPM_MODULUS, and LPM_NUMWORDS, LPM_HINT,LPM_STRENGTH, LPM_DIRECTION,
-- and LPM_PVALUE
--
-- 2. Added the two dimentional port components (AND, OR, XOR, and MUX).
--------------------------------------------------------------------------
-- Excluded Functions:
--
--   LPM_FSM and LPM_TTABLE
--
--------------------------------------------------------------------------
-- Assumptions:
--
-- 1. All ports and signal types are std_logic or std_logic_vector
--    from IEEE 1164 package.
-- 2. Synopsys std_logic_arith, std_logic_unsigned, and std_logic_signed
--    package are assumed to be accessible from IEEE library.
-- 3. lpm_component_package must be accessible from library work.
-- 4. The default value of LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, LPM_HINT,
--    LPM_NUMWORDS, LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE is
--    string "UNUSED".
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_CONSTANT is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_CVALUE : natural;
			 LPM_STRENGTH : string := "UNUSED";
			 LPM_TYPE : string := "LPM_CONSTANT";
			 LPM_HINT : string := "UNUSED");
	port (RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_CONSTANT;
 
architecture LPM_SYN of LPM_CONSTANT is
begin
 
	RESULT <= conv_std_logic_vector(LPM_CVALUE, LPM_WIDTH);
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_INV is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE : string := "LPM_INV";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_INV;
 
architecture LPM_SYN of LPM_INV is
begin
 
	RESULT <= not DATA;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_AND is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_SIZE : natural;    -- MUST be greater than 0
			 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 LPM_AND;
 
architecture LPM_SYN of LPM_AND is
 
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
 
begin
 
L1: for i in 0 to LPM_WIDTH-1 generate
		RESULT_INT(0,i) <= DATA(0,i);
L2:     for j in 0 to LPM_SIZE-2 generate
			RESULT_INT(j+1,i) <=  RESULT_INT(j,i) and DATA(j+1,i);
L3:         if j = LPM_SIZE-2 generate
				RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
			end generate L3;
		end generate L2;
	end generate L1;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_OR is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
             LPM_SIZE : natural;    -- MUST be greater than 0 
			 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 LPM_OR;
 
architecture LPM_SYN of LPM_OR is
 
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
 
begin
 
L1: for i in 0 to LPM_WIDTH-1 generate
		RESULT_INT(0,i) <= DATA(0,i);
L2:     for j in 0 to LPM_SIZE-2 generate
			RESULT_INT(j+1,i) <=  RESULT_INT(j,i) or DATA(j+1,i);
L3:         if j = LPM_SIZE-2 generate
				RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
			end generate L3;
		end generate L2;
	end generate L1;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_XOR is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
             LPM_SIZE : natural;    -- MUST be greater than 0 
			 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 LPM_XOR;
 
architecture LPM_SYN of LPM_XOR is
 
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
 
begin
 
L1: for i in 0 to LPM_WIDTH-1 generate
		RESULT_INT(0,i) <= DATA(0,i);
L2:     for j in 0 to LPM_SIZE-2 generate
			RESULT_INT(j+1,i) <=  RESULT_INT(j,i) xor DATA(j+1,i);
L3:         if j = LPM_SIZE-2 generate
				RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
			end generate L3;
		end generate L2;
	end generate L1;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_BUSTRI is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE : string := "LPM_BUSTRI";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ENABLEDT : in std_logic := '0';
		  ENABLETR : in std_logic := '0';
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  TRIDATA : inout std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_BUSTRI;
 
architecture LPM_SYN of LPM_BUSTRI is
begin
 
	process(DATA, TRIDATA, ENABLETR, ENABLEDT)
	begin
		if ENABLEDT = '0' and ENABLETR = '1' then
			RESULT <= TRIDATA;
			TRIDATA <= (OTHERS => 'Z');
		elsif ENABLEDT = '1' and ENABLETR = '0' then
			RESULT <= (OTHERS => 'Z');
			TRIDATA <= DATA;
		elsif ENABLEDT = '1' and ENABLETR = '1' then
			RESULT <= DATA;
			TRIDATA <= DATA;
		else
			RESULT <= (OTHERS => 'Z');
			TRIDATA <= (OTHERS => 'Z');
		end if;
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_MUX is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
             LPM_SIZE : natural;    -- MUST be greater than 0 
             LPM_WIDTHS : natural;    -- MUST be greater than 0 
             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 LPM_MUX;
 
architecture LPM_SYN of LPM_MUX is
 
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH-1 downto 0);
 
begin
 
	process (ACLR, CLOCK, SEL, DATA)
	variable resulttmp : t_resulttmp;
	variable ISEL : integer;
	begin
		if LPM_PIPELINE >= 0 then
			ISEL := conv_integer(SEL);
 
			for i in 0 to LPM_WIDTH-1 loop
				resulttmp(LPM_PIPELINE)(i) := DATA(ISEL,i);
			end loop;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					for i in 0 to LPM_PIPELINE loop
						resulttmp(i) := (OTHERS => '0');
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1'  then
					resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
				end if;
			end if;
 
			RESULT <= resulttmp(0);
		end if;
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
 
entity LPM_DECODE is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_DECODES : natural;    -- MUST be greater than 0
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE : string := "LPM_DECODE";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  ACLR : in std_logic := '0';
		  ENABLE : in std_logic := '1';
		  EQ : out std_logic_vector(LPM_DECODES-1 downto 0));
end LPM_DECODE;
 
architecture LPM_SYN of LPM_DECODE is
 
type t_eqtmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_DECODES-1 downto 0);
 
begin
 
	process(ACLR, CLOCK, DATA, ENABLE)
	variable eqtmp : t_eqtmp;
	begin
 
		if LPM_PIPELINE >= 0 then
			for i in 0 to LPM_DECODES-1 loop
				if conv_integer(DATA) = i then
					if ENABLE = '1' then
						eqtmp(LPM_PIPELINE)(i) := '1';
					else
						eqtmp(LPM_PIPELINE)(i) := '0';
					end if;
				else
					eqtmp(LPM_PIPELINE)(i) := '0';
				end if;
			end loop;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					for i in 0 to LPM_PIPELINE loop
						eqtmp(i) := (OTHERS => '0');
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
					eqtmp(0 to LPM_PIPELINE - 1) := eqtmp(1 to LPM_PIPELINE);
				end if;
			end if;
		end if;
 
		EQ <= eqtmp(0);
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_CLSHIFT is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHDIST : natural;    -- MUST be greater than 0
			 LPM_SHIFTTYPE : string := "LOGICAL";
			 LPM_TYPE : string := "LPM_CLSHIFT";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0); 
		  DISTANCE : in STD_LOGIC_VECTOR(LPM_WIDTHDIST-1 downto 0); 
		  DIRECTION : in STD_LOGIC := '0';
		  RESULT : out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0);
		  UNDERFLOW : out STD_LOGIC;
		  OVERFLOW : out STD_LOGIC);
end LPM_CLSHIFT;
 
architecture LPM_SYN of LPM_CLSHIFT is
 
signal IRESULT : std_logic_vector(LPM_WIDTH-1 downto 0);
 
begin
 
	process(DATA, DISTANCE, DIRECTION)
    variable tmpdata : std_logic_vector(LPM_WIDTH-1 downto 0);
    variable tmpdist : integer;
	begin
        if LPM_SHIFTTYPE = "ARITHMETIC" or LPM_SHIFTTYPE = "LOGICAL" then
            tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
            tmpdist := conv_integer(unsigned(DISTANCE));
            for i in LPM_WIDTH-1 downto 0 loop
                if DIRECTION = '0' then
                    if i >= tmpdist then
                        IRESULT(i) <= tmpdata(i-tmpdist);
                    else
                        IRESULT(i) <= '0';
                    end if;
                elsif DIRECTION = '1' then
                    if i+tmpdist < LPM_WIDTH then
                        IRESULT(i) <= tmpdata(i+tmpdist);
                    elsif LPM_SHIFTTYPE = "ARITHMETIC" then
                        IRESULT(i) <= DATA(LPM_WIDTH-1);
                    else
                        IRESULT(i) <= '0';
                    end if;
                end if;
            end loop;
		elsif LPM_SHIFTTYPE = "ROTATE" then
            tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
            tmpdist := conv_integer(unsigned(DISTANCE)) mod LPM_WIDTH;
            for i in LPM_WIDTH-1 downto 0 loop
                if DIRECTION = '0' then
                    if i >= tmpdist then
                        IRESULT(i) <= tmpdata(i-tmpdist);
                    else
                        IRESULT(i) <= tmpdata(i+LPM_WIDTH-tmpdist);
                    end if;
                elsif DIRECTION = '1' then
                    if i+tmpdist < LPM_WIDTH then
                        IRESULT(i) <= tmpdata(i+tmpdist);
                    else
                        IRESULT(i) <= tmpdata(i-LPM_WIDTH+tmpdist);
                    end if;
                end if;
            end loop;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_SHIFTTYPE property value for LPM_CLSHIFT!"
            SEVERITY ERROR;
		end if;
	end process;
 
    process(DATA, DISTANCE, DIRECTION, IRESULT)
    variable neg_one : signed(LPM_WIDTH-1 downto 0) := (OTHERS => '1');
    variable tmpdata : std_logic_vector(LPM_WIDTH-1 downto 0);
    variable tmpdist : integer;
    variable msb_cnt, lsb_cnt : integer := 0;
    variable sgn_bit : std_logic;
	begin
        tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
        tmpdist := conv_integer(DISTANCE);
 
        OVERFLOW <= '0';
        UNDERFLOW <= '0';
 
        if (tmpdist /= 0 and tmpdata /= 0) then
            if LPM_SHIFTTYPE = "ROTATE" then
                OVERFLOW <= 'U';
                UNDERFLOW <= 'U';
            else
                if (tmpdist < LPM_WIDTH) then
                    if LPM_SHIFTTYPE = "LOGICAL" then
                        msb_cnt := 0;
                        while (msb_cnt < LPM_WIDTH) and (tmpdata(LPM_WIDTH-msb_cnt-1) = '0') loop
                            msb_cnt := msb_cnt + 1;
                        end loop;
 
                        if ((tmpdist > msb_cnt) and (DIRECTION = '0')) then
                            OVERFLOW <= '1';
                        elsif ((tmpdist + msb_cnt >= LPM_WIDTH) and (DIRECTION = '1')) then
                            UNDERFLOW <= '1';
                        end if;
                    elsif LPM_SHIFTTYPE = "ARITHMETIC" then
                        sgn_bit := '0';
                        if (tmpdata(LPM_WIDTH-1) = '1') then
                            sgn_bit := '1';
                        end if;
 
                        msb_cnt := 0;
                        while (msb_cnt < LPM_WIDTH) and (tmpdata(LPM_WIDTH-msb_cnt-1) = sgn_bit) loop
                            msb_cnt := msb_cnt + 1;
                        end loop;
 
                        lsb_cnt := 0;
                        while (lsb_cnt < LPM_WIDTH) and (tmpdata(lsb_cnt) = '0') loop
                            lsb_cnt := lsb_cnt + 1;
                        end loop;
 
                        if (DIRECTION = '1') then         -- shift right
                            if (tmpdata(LPM_WIDTH-1) = '1') then  -- negative
                                --Use the following line if 1110 asr 1 yields NO underflow is desired.
                                --if (msb_cnt + tmpdist > LPM_WIDTH) or ((msb_cnt + tmpdist = LPM_WIDTH) and (tmpdist > lsb_cnt)) then
                                -- SPR76524 comments/replaces out the line below
                                -- if (msb_cnt + tmpdist > LPM_WIDTH) or ((msb_cnt + tmpdist = LPM_WIDTH) and (tmpdist >= lsb_cnt)) then
                                if (msb_cnt + tmpdist >= LPM_WIDTH) and (msb_cnt /= LPM_WIDTH) then
                                    UNDERFLOW <= '1';
                                end if;
                            else  -- non-neg
                                -- SPR76524 comments/replaces out the line below
                                -- if (msb_cnt + tmpdist >= LPM_WIDTH) then
                                if (msb_cnt + tmpdist >= LPM_WIDTH) and (msb_cnt /= LPM_WIDTH) then
                                    UNDERFLOW <= '1';
                                end if;
                            end if;
                        elsif (DIRECTION = '0') then      -- shift left
                            if (tmpdata(LPM_WIDTH-1) = '1') then -- negative
                                if ((signed(tmpdata) /= neg_one) and (tmpdist >= LPM_WIDTH)) or (tmpdist >= msb_cnt) then
                                    OVERFLOW <= '1';
                                end if;
                            else  -- non-neg
                                if ((tmpdata /= 0) and (tmpdist >= LPM_WIDTH-1)) or (tmpdist >= msb_cnt) then
                                    OVERFLOW <= '1';
                                end if;
                            end if;
                        end if;
                    end if;
                else
                    if DIRECTION = '0' then
                        OVERFLOW <= '1';
                    elsif DIRECTION = '1' then
                        UNDERFLOW <= '1';
                    end if;
                end if;  -- tmpdist < LPM_WIDTH
            end if;  -- LPM_SHIFTTYPE = "ROTATE"
        end if;  -- tmpdist /= 0 and tmpdata /= 0
	end process;
 
	RESULT <= IRESULT;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_ADD_SUB_SIGNED is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_DIRECTION : string := "UNUSED";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE : string := "LPM_ADD_SUB";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH downto 1);
		  DATAB : in std_logic_vector(LPM_WIDTH downto 1);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
          CIN : in std_logic := 'Z';
		  ADD_SUB : in std_logic := '1';
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  COUT : out std_logic;
		  OVERFLOW : out std_logic);
end LPM_ADD_SUB_SIGNED;
 
architecture LPM_SYN of LPM_ADD_SUB_SIGNED is
 
signal A, B : std_logic_vector(LPM_WIDTH downto 0);
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH downto 0);
 
begin
 
	A <= (DATAA(LPM_WIDTH) & DATAA);
	B <= (DATAB(LPM_WIDTH) & DATAB);
 
	process(ACLR, CLOCK, A, B, CIN, ADD_SUB)
    variable resulttmp : t_resulttmp := (OTHERS => (OTHERS => '0'));
    variable couttmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
    variable overflowtmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
    variable i_cin : std_logic;
	begin
		if LPM_PIPELINE >= 0 then
			if LPM_DIRECTION = "ADD" or
               (LPM_DIRECTION = "UNUSED" and ADD_SUB = '1') then
                if (CIN = 'Z') then
                    i_cin := '0';
                else
                    i_cin := CIN;
                end if;
 
                resulttmp(LPM_PIPELINE) := A + B + i_cin;
				couttmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH)
											xor DATAA(LPM_WIDTH)
											xor DATAB(LPM_WIDTH);
            elsif LPM_DIRECTION = "SUB" or
                  (LPM_DIRECTION = "UNUSED" and ADD_SUB = '0') then
                if (CIN = 'Z') then
                    i_cin := '1';
                else
                    i_cin := CIN;
                end if;
 
                resulttmp(LPM_PIPELINE) := A - B + i_cin - 1;
				couttmp(LPM_PIPELINE) := not resulttmp(LPM_PIPELINE)(LPM_WIDTH)
											xor DATAA(LPM_WIDTH)
											xor DATAB(LPM_WIDTH);
            elsif LPM_DIRECTION /= "UNUSED" then
                ASSERT FALSE
                REPORT "Illegal LPM_DIRECTION property value for LPM_ADD_SUB!"
                SEVERITY ERROR;
            end if;
 
			if (resulttmp(LPM_PIPELINE) > (2 ** (LPM_WIDTH-1)) -1) or
			   (resulttmp(LPM_PIPELINE) < -2 ** (LPM_WIDTH-1)) then
 
				overflowtmp(LPM_PIPELINE) := '1';
			else
				overflowtmp(LPM_PIPELINE) := '0';
			end if;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					overflowtmp := (OTHERS => '0');
					couttmp := (OTHERS => '0');
					for i in 0 to LPM_PIPELINE loop
						resulttmp(i) := (OTHERS => '0');
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
					overflowtmp(0 to LPM_PIPELINE - 1) := overflowtmp(1 to LPM_PIPELINE);
					couttmp(0 to LPM_PIPELINE - 1) := couttmp(1 to LPM_PIPELINE);
					resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
				end if;
			end if;
 
            COUT <= couttmp(0);
			OVERFLOW <= overflowtmp(0);
			RESULT <= resulttmp(0)(LPM_WIDTH-1 downto 0);
		end if;
	end process;
 
end LPM_SYN;
 
 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_ADD_SUB_UNSIGNED is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_DIRECTION : string := "UNUSED";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE : string := "LPM_ADD_SUB";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
          CIN : in std_logic := 'Z';
		  ADD_SUB : in std_logic := '1';
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  COUT : out std_logic;
		  OVERFLOW : out std_logic);
end LPM_ADD_SUB_UNSIGNED;
 
architecture LPM_SYN of LPM_ADD_SUB_UNSIGNED is
signal A, B : std_logic_vector(LPM_WIDTH downto 0);
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH downto 0);
 
begin
 
	A <= ('0' & DATAA);
	B <= ('0' & DATAB);
 
	process(ACLR, CLOCK, A, B, CIN, ADD_SUB)
    variable resulttmp : t_resulttmp := (OTHERS => (OTHERS => '0'));
    variable couttmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
    variable overflowtmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
    variable i_cin : std_logic;
	begin
 
		if LPM_PIPELINE >= 0 then
			if LPM_DIRECTION = "ADD" or
               (LPM_DIRECTION = "UNUSED" and ADD_SUB = '1') then
                if (CIN = 'Z') then
                    i_cin := '0';
                else
                    i_cin := CIN;
                end if;
 
                resulttmp(LPM_PIPELINE) := A + B + i_cin;
				couttmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH);
            elsif LPM_DIRECTION = "SUB" or
                  (LPM_DIRECTION = "UNUSED" and ADD_SUB = '0') then
                if (CIN = 'Z') then
                    i_cin := '1';
                else
                    i_cin := CIN;
                end if;
 
                resulttmp(LPM_PIPELINE) := A - B + i_cin - 1;
				couttmp(LPM_PIPELINE) := not resulttmp(LPM_PIPELINE)(LPM_WIDTH);
            elsif LPM_DIRECTION /= "UNUSED" then
                ASSERT FALSE
                REPORT "Illegal LPM_DIRECTION property value for LPM_ADD_SUB!"
                SEVERITY ERROR;
			end if;
 
			overflowtmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH);
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					overflowtmp := (OTHERS => '0');
					couttmp := (OTHERS => '0');
					for i in 0 to LPM_PIPELINE loop
						resulttmp(i) := (OTHERS => '0');
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
					overflowtmp(0 to LPM_PIPELINE - 1) := overflowtmp(1 to LPM_PIPELINE);
					couttmp(0 to LPM_PIPELINE - 1) := couttmp(1 to LPM_PIPELINE);
					resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
				end if;
			end if;
 
            COUT <= couttmp(0);
			OVERFLOW <= overflowtmp(0);
			RESULT <= resulttmp(0)(LPM_WIDTH-1 downto 0);
		end if;
	end process;
 
end LPM_SYN;
 
 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_ADD_SUB is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_DIRECTION : string := "UNUSED";
			 LPM_REPRESENTATION: string := "SIGNED";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE : string := "LPM_ADD_SUB";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
          CIN : in std_logic := 'Z';
		  ADD_SUB : in std_logic := '1';
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  COUT : out std_logic;
		  OVERFLOW : out std_logic);
end LPM_ADD_SUB;
 
architecture LPM_SYN of LPM_ADD_SUB is
 
	component LPM_ADD_SUB_SIGNED
            generic (LPM_WIDTH : natural;    -- MUST be greater than 0
					 LPM_DIRECTION : string := "UNUSED";
                     LPM_PIPELINE : natural := 0;
					 LPM_TYPE : string := "LPM_ADD_SUB";
					 LPM_HINT : string := "UNUSED");
			port (DATAA : in std_logic_vector(LPM_WIDTH downto 1);
				  DATAB : in std_logic_vector(LPM_WIDTH downto 1);
				  ACLR : in std_logic := '0';
				  CLOCK : in std_logic := '0';
				  CLKEN : in std_logic := '1';
                  CIN : in std_logic := 'Z';
				  ADD_SUB : in std_logic := '1';
				  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
				  COUT : out std_logic;
				  OVERFLOW : out std_logic);
	end component;
 
	component LPM_ADD_SUB_UNSIGNED
            generic (LPM_WIDTH : natural;    -- MUST be greater than 0
					 LPM_DIRECTION : string := "UNUSED";
                     LPM_PIPELINE : natural := 0;
					 LPM_TYPE : string := "LPM_ADD_SUB";
					 LPM_HINT : string := "UNUSED");
			port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
				  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
				  ACLR : in std_logic := '0';
				  CLOCK : in std_logic := '0';
				  CLKEN : in std_logic := '1';
                  CIN : in std_logic := 'Z';
				  ADD_SUB : in std_logic := '1';
				  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
				  COUT : out std_logic;
				  OVERFLOW : out std_logic);
	end component;
 
 
begin
 
L1: if LPM_REPRESENTATION = "UNSIGNED" generate
 
U:  LPM_ADD_SUB_UNSIGNED
	generic map (LPM_WIDTH => LPM_WIDTH, LPM_DIRECTION => LPM_DIRECTION,
				 LPM_PIPELINE => LPM_PIPELINE, LPM_TYPE => LPM_TYPE,
				 LPM_HINT => LPM_HINT)
	port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR, CLOCK => CLOCK,
			  CIN => CIN, ADD_SUB => ADD_SUB, RESULT => RESULT, COUT => COUT,
			  OVERFLOW => OVERFLOW, CLKEN => CLKEN);
	end generate;
 
L2: if LPM_REPRESENTATION = "SIGNED" generate
 
V:  LPM_ADD_SUB_SIGNED
	generic map (LPM_WIDTH => LPM_WIDTH, LPM_DIRECTION => LPM_DIRECTION,
				 LPM_PIPELINE => LPM_PIPELINE, LPM_TYPE => LPM_TYPE,
				 LPM_HINT => LPM_HINT)
	port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR, CLOCK => CLOCK,
			  CIN => CIN, ADD_SUB => ADD_SUB, RESULT => RESULT, COUT => COUT,
			  OVERFLOW => OVERFLOW, CLKEN => CLKEN);
	end generate;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_signed.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_COMPARE_SIGNED is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE: string := "LPM_COMPARE";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  AGB : out std_logic;
		  AGEB : out std_logic;
		  AEB : out std_logic;
		  ANEB : out std_logic;
		  ALB : out std_logic;
		  ALEB : out std_logic);
end LPM_COMPARE_SIGNED;
 
architecture LPM_SYN of LPM_COMPARE_SIGNED is
begin
 
	process(ACLR, CLOCK, DATAA, DATAB)
	variable agbtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable agebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable aebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable anebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable albtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable alebtmp : std_logic_vector (0 to LPM_PIPELINE);
 
	begin
 
		if LPM_PIPELINE >= 0 then
			if signed(DATAA) > signed(DATAB) then
				agbtmp(LPM_PIPELINE) := '1';
				agebtmp(LPM_PIPELINE) := '1';
				anebtmp(LPM_PIPELINE) := '1';
				aebtmp(LPM_PIPELINE) := '0';
				albtmp(LPM_PIPELINE) := '0';
				alebtmp(LPM_PIPELINE) := '0';
			elsif signed(DATAA) = signed(DATAB) then
				agbtmp(LPM_PIPELINE) := '0';
				agebtmp(LPM_PIPELINE) := '1';
				anebtmp(LPM_PIPELINE) := '0';
				aebtmp(LPM_PIPELINE) := '1';
				albtmp(LPM_PIPELINE) := '0';
				alebtmp(LPM_PIPELINE) := '1';
			else
				agbtmp(LPM_PIPELINE) := '0';
				agebtmp(LPM_PIPELINE) := '0';
				anebtmp(LPM_PIPELINE) := '1';
				aebtmp(LPM_PIPELINE) := '0';
				albtmp(LPM_PIPELINE) := '1';
				alebtmp(LPM_PIPELINE) := '1';
			end if;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					for i in 0 to LPM_PIPELINE loop
						agbtmp(i) := '0';
						agebtmp(i) := '0';
						anebtmp(i) := '0';
						aebtmp(i) := '0';
						albtmp(i) := '0';
						alebtmp(i) := '0';
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
					agbtmp(0 to LPM_PIPELINE-1) :=  agbtmp(1 to LPM_PIPELINE);
					agebtmp(0 to LPM_PIPELINE-1) := agebtmp(1 to LPM_PIPELINE) ;
					anebtmp(0 to LPM_PIPELINE-1) := anebtmp(1 to LPM_PIPELINE);
					aebtmp(0 to LPM_PIPELINE-1) := aebtmp(1 to LPM_PIPELINE);
					albtmp(0 to LPM_PIPELINE-1) := albtmp(1 to LPM_PIPELINE);
					alebtmp(0 to LPM_PIPELINE-1) := alebtmp(1 to LPM_PIPELINE);
				end if;
			end if;
		end if;
 
		AGB <= agbtmp(0);
		AGEB <= agebtmp(0);
		ANEB <= anebtmp(0);
		AEB <= aebtmp(0);
		ALB <= albtmp(0);
		ALEB <= alebtmp(0);
	end process;
 
end LPM_SYN;
 
 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_COMPARE_UNSIGNED is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE: string := "LPM_COMPARE";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  AGB : out std_logic;
		  AGEB : out std_logic;
		  AEB : out std_logic;
		  ANEB : out std_logic;
		  ALB : out std_logic;
		  ALEB : out std_logic);
end LPM_COMPARE_UNSIGNED;
 
architecture LPM_SYN of LPM_COMPARE_UNSIGNED is
begin
 
	process(ACLR, CLOCK, DATAA, DATAB)
	variable agbtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable agebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable aebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable anebtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable albtmp : std_logic_vector (0 to LPM_PIPELINE);
	variable alebtmp : std_logic_vector (0 to LPM_PIPELINE);
 
	begin
		if LPM_PIPELINE >= 0 then
			if unsigned(DATAA) > unsigned(DATAB) then
				agbtmp(LPM_PIPELINE) := '1';
				agebtmp(LPM_PIPELINE) := '1';
				anebtmp(LPM_PIPELINE) := '1';
				aebtmp(LPM_PIPELINE) := '0';
				albtmp(LPM_PIPELINE) := '0';
				alebtmp(LPM_PIPELINE) := '0';
			elsif unsigned(DATAA) = unsigned(DATAB) then
				agbtmp(LPM_PIPELINE) := '0';
				agebtmp(LPM_PIPELINE) := '1';
				anebtmp(LPM_PIPELINE) := '0';
				aebtmp(LPM_PIPELINE) := '1';
				albtmp(LPM_PIPELINE) := '0';
				alebtmp(LPM_PIPELINE) := '1';
			else
				agbtmp(LPM_PIPELINE) := '0';
				agebtmp(LPM_PIPELINE) := '0';
				anebtmp(LPM_PIPELINE) := '1';
				aebtmp(LPM_PIPELINE) := '0';
				albtmp(LPM_PIPELINE) := '1';
				alebtmp(LPM_PIPELINE) := '1';
			end if;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					for i in 0 to LPM_PIPELINE loop
						agbtmp(i) := '0';
						agebtmp(i) := '0';
						anebtmp(i) := '0';
						aebtmp(i) := '0';
						albtmp(i) := '0';
						alebtmp(i) := '0';
					end loop;
				elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
					agbtmp(0 to LPM_PIPELINE-1) :=  agbtmp(1 to LPM_PIPELINE);
					agebtmp(0 to LPM_PIPELINE-1) := agebtmp(1 to LPM_PIPELINE) ;
					anebtmp(0 to LPM_PIPELINE-1) := anebtmp(1 to LPM_PIPELINE);
					aebtmp(0 to LPM_PIPELINE-1) := aebtmp(1 to LPM_PIPELINE);
					albtmp(0 to LPM_PIPELINE-1) := albtmp(1 to LPM_PIPELINE);
					alebtmp(0 to LPM_PIPELINE-1) := alebtmp(1 to LPM_PIPELINE);
				end if;
			end if;
		end if;
 
		AGB <= agbtmp(0);
		AGEB <= agebtmp(0);
		ANEB <= anebtmp(0);
		AEB <= aebtmp(0);
		ALB <= albtmp(0);
		ALEB <= alebtmp(0);
	end process;
 
end LPM_SYN;
 
 
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_COMPARE is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_REPRESENTATION : string := "UNSIGNED";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE: string := "LPM_COMPARE";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  AGB : out std_logic;
		  AGEB : out std_logic;
		  AEB : out std_logic;
		  ANEB : out std_logic;
		  ALB : out std_logic;
		  ALEB : out std_logic);
end LPM_COMPARE;
 
architecture LPM_SYN of LPM_COMPARE is
 
	component LPM_COMPARE_SIGNED
        generic (LPM_WIDTH : natural;    -- MUST be greater than 0
                 LPM_PIPELINE : natural := 0;
				 LPM_TYPE: string := "LPM_COMPARE";
				 LPM_HINT : string := "UNUSED");
		port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
			  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
			  ACLR : in std_logic := '0';
			  CLOCK : in std_logic := '0';
			  CLKEN : in std_logic := '1';
			  AGB : out std_logic;
			  AGEB : out std_logic;
			  AEB : out std_logic;
			  ANEB : out std_logic;
			  ALB : out std_logic;
			  ALEB : out std_logic);
	end component;
 
	component LPM_COMPARE_UNSIGNED
        generic (LPM_WIDTH : natural;    -- MUST be greater than 0
                 LPM_PIPELINE : natural := 0;
				 LPM_TYPE: string := "LPM_COMPARE";
				 LPM_HINT : string := "UNUSED");
		port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
			  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
			  ACLR : in std_logic := '0';
			  CLOCK : in std_logic := '0';
			  CLKEN : in std_logic := '1';
			  AGB : out std_logic;
			  AGEB : out std_logic;
			  AEB : out std_logic;
			  ANEB : out std_logic;
			  ALB : out std_logic;
			  ALEB : out std_logic);
	end component;
 
begin
 
L1: if LPM_REPRESENTATION = "UNSIGNED" generate
 
U1: LPM_COMPARE_UNSIGNED
	generic map (LPM_WIDTH => LPM_WIDTH, LPM_PIPELINE => LPM_PIPELINE,
				 LPM_TYPE => LPM_TYPE, LPM_HINT => LPM_HINT)
	port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR,
			  CLOCK => CLOCK, AGB => AGB, AGEB => AGEB, CLKEN => CLKEN,
			  AEB => AEB, ANEB => ANEB, ALB => ALB, ALEB => ALEB);
	end generate;
 
L2: if LPM_REPRESENTATION = "SIGNED" generate
 
U2: LPM_COMPARE_SIGNED
	generic map (LPM_WIDTH => LPM_WIDTH, LPM_PIPELINE => LPM_PIPELINE,
				 LPM_TYPE => LPM_TYPE, LPM_HINT => LPM_HINT)
	port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR,
			  CLOCK => CLOCK, AGB => AGB, AGEB => AGEB, CLKEN => CLKEN,
			  AEB => AEB, ANEB => ANEB, ALB => ALB, ALEB => ALEB);
	end generate;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_MULT is
    generic (LPM_WIDTHA : natural;    -- MUST be greater than 0
             LPM_WIDTHB : natural;    -- MUST be greater than 0
			 LPM_WIDTHS : natural := 0;
             LPM_WIDTHP : natural;    -- MUST be greater than 0
			 LPM_REPRESENTATION : string := "UNSIGNED";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE: string := "LPM_MULT";
			 LPM_HINT : string := "UNUSED");
	port (DATAA : in std_logic_vector(LPM_WIDTHA-1 downto 0);
		  DATAB : in std_logic_vector(LPM_WIDTHB-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  SUM : in std_logic_vector(LPM_WIDTHS-1 downto 0) := (OTHERS => '0');
		  RESULT : out std_logic_vector(LPM_WIDTHP-1 downto 0));
end LPM_MULT;
 
architecture LPM_SYN of LPM_MULT is
 
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHP-1 downto 0);
 
begin
 
	process (CLOCK, ACLR, DATAA, DATAB, SUM)
	variable resulttmp : t_resulttmp;
    variable tmp_prod_ab : std_logic_vector(LPM_WIDTHA+LPM_WIDTHB downto 0);
    variable tmp_prod_s : std_logic_vector(LPM_WIDTHS downto 0);
    variable tmp_prod_p : std_logic_vector(LPM_WIDTHP-1 downto 0);
    variable tmp_use : integer;
	begin
		if LPM_PIPELINE >= 0 then
 
            if LPM_REPRESENTATION = "SIGNED" then
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto 0) := signed(DATAA) * signed(DATAB);
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB) := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1);
            elsif LPM_REPRESENTATION = "UNSIGNED" then
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto 0) := unsigned(DATAA) * unsigned(DATAB);
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB) := '0';
            else
                ASSERT FALSE
                REPORT "Illegal LPM_REPRESENTATION property value for LPM_MULT!"
                SEVERITY ERROR;
            end if;
            tmp_use := 1; --AB
            if (LPM_WIDTHS > LPM_WIDTHA+LPM_WIDTHB) then
                if LPM_REPRESENTATION = "SIGNED" then
                    tmp_prod_s := (OTHERS => tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB));
                    tmp_prod_s(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab;
                    tmp_prod_s := signed(tmp_prod_s) + signed(SUM);
                    tmp_prod_p := (OTHERS => tmp_prod_s(LPM_WIDTHS));
                else
                    tmp_prod_s := (OTHERS => '0');
                    tmp_prod_s(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab;
                    tmp_prod_s := unsigned(tmp_prod_s) + unsigned(SUM);
                    tmp_prod_p := (OTHERS => '0');
                end if;
                tmp_use := 2; --S
            elsif (LPM_WIDTHS > 0) then
                if LPM_REPRESENTATION = "SIGNED" then
                    tmp_prod_ab := signed(tmp_prod_ab) + signed(SUM);
                    tmp_prod_p := (OTHERS => tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB));
                else
                    tmp_prod_ab := unsigned(tmp_prod_ab) + unsigned(SUM);
                    tmp_prod_p := (OTHERS => '0');
                end if;
            end if;
 
            if (tmp_use = 2) then --S
                if (LPM_WIDTHP > LPM_WIDTHS) then
                    tmp_prod_p(LPM_WIDTHS downto 0) := tmp_prod_s;
                elsif (LPM_WIDTHP = LPM_WIDTHS) then
                    tmp_prod_p := tmp_prod_s(LPM_WIDTHP-1 downto 0);
                else
                    tmp_prod_p := tmp_prod_s(LPM_WIDTHS-1 downto LPM_WIDTHS-LPM_WIDTHP);
                end if;
            else --AB
                if (LPM_WIDTHP > LPM_WIDTHA+LPM_WIDTHB) then
                    tmp_prod_p(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB downto 0);
                elsif (LPM_WIDTHP = LPM_WIDTHA+LPM_WIDTHB) then
                    tmp_prod_p := tmp_prod_ab(LPM_WIDTHP-1 downto 0);
                else
                    tmp_prod_p := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto LPM_WIDTHA+LPM_WIDTHB-LPM_WIDTHP);
                end if;
            end if;                
 
            resulttmp(LPM_PIPELINE) := tmp_prod_p;
 
			if LPM_PIPELINE > 0 then
				if ACLR = '1' then
					for i in 0 to LPM_PIPELINE loop
						resulttmp(i) := (OTHERS => '0');
					end loop;
                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' and now > 0 ns then
					resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
				end if;
			end if;
		end if;
 
		RESULT <= resulttmp(0);
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_DIVIDE is
    generic (LPM_WIDTHN : natural;    -- MUST be greater than 0
             LPM_WIDTHD : natural;    -- MUST be greater than 0
			 LPM_NREPRESENTATION : string := "UNSIGNED";
			 LPM_DREPRESENTATION : string := "UNSIGNED";
			 LPM_REMAINDERPOSITIVE : string := "TRUE";
             LPM_PIPELINE : natural := 0;
			 LPM_TYPE : string := "LPM_DIVIDE";
			 LPM_HINT : string := "UNUSED");
	port (NUMER : in std_logic_vector(LPM_WIDTHN-1 downto 0);
		  DENOM : in std_logic_vector(LPM_WIDTHD-1 downto 0);
		  ACLR : in std_logic := '0';
		  CLOCK : in std_logic := '0';
		  CLKEN : in std_logic := '1';
		  QUOTIENT : out std_logic_vector(LPM_WIDTHN-1 downto 0);
		  REMAIN : out std_logic_vector(LPM_WIDTHD-1 downto 0));
end LPM_DIVIDE;
 
architecture behave of lpm_divide is
 
type qpipeline is array (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHN-1 downto 0);
type rpipeline is array (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHD-1 downto 0);
 
begin
 
	process (aclr, clock, numer, denom)
	variable tmp_quotient : qpipeline;
	variable tmp_remain : rpipeline;
    variable int_numer, int_denom, int_quotient, int_remain : integer := 0;
	variable signed_quotient : signed(LPM_WIDTHN-1 downto 0);
	variable unsigned_quotient : unsigned(LPM_WIDTHN-1 downto 0);
	begin
        if (LPM_NREPRESENTATION = "UNSIGNED") then
			int_numer := conv_integer(unsigned(numer));
        elsif (LPM_NREPRESENTATION = "SIGNED") then
			int_numer := conv_integer(signed(numer));
        else
            ASSERT FALSE
            REPORT "Illegal LPM_NREPRESENTATION property value for LPM_DIVIDE!"
            SEVERITY ERROR;
		end if;
        if (LPM_DREPRESENTATION = "UNSIGNED" ) then
			int_denom := conv_integer(unsigned(denom));
        elsif (LPM_DREPRESENTATION = "SIGNED") then
			int_denom := conv_integer(signed(denom));
        else
            ASSERT FALSE
            REPORT "Illegal LPM_DREPRESENTATION property value for LPM_DIVIDE!"
            SEVERITY ERROR;
		end if;
		if int_denom = 0 then
			int_quotient := 0;
			int_remain := 0;
		else
            int_quotient := int_numer / int_denom;
            int_remain := int_numer rem int_denom;
 
            -- LPM 220 standard
            if ((LPM_REMAINDERPOSITIVE = "TRUE") and (int_remain < 0)) then
                if int_denom < 0 then
                    int_quotient := int_quotient + 1;
                else
                    int_quotient := int_quotient - 1;
                end if;
                int_remain := int_numer - int_quotient*int_denom;
            end if;
		end if;
		signed_quotient := conv_signed(int_quotient, LPM_WIDTHN);
		unsigned_quotient := conv_unsigned(int_quotient, LPM_WIDTHN);
 
        tmp_remain(LPM_PIPELINE) := conv_std_logic_vector(int_Remain, LPM_WIDTHD);
        if ((LPM_NREPRESENTATION = "UNSIGNED") and (LPM_DREPRESENTATION = "UNSIGNED")) then
            tmp_quotient(LPM_PIPELINE) := conv_std_logic_vector(unsigned_quotient, LPM_WIDTHN);
		else
            tmp_quotient(LPM_PIPELINE) := conv_std_logic_vector(signed_quotient, LPM_WIDTHN);
		end if;
 
        if LPM_PIPELINE > 0 then
			if aclr = '1' then
                for i in 0 to LPM_PIPELINE loop
					tmp_quotient(i) := (OTHERS => '0');
					tmp_remain(i) := (OTHERS => '0');
				end loop;
			elsif clock'event and clock = '1' then
				if clken = '1' then
                    tmp_quotient(0 to LPM_PIPELINE-1) := tmp_quotient(1 to LPM_PIPELINE);
                    tmp_remain(0 to LPM_PIPELINE-1) := tmp_remain(1 to LPM_PIPELINE);
				end if;
			end if;
		end if;
 
		quotient <= tmp_quotient(0);
		remain <= tmp_remain(0);
	end process;
 
end behave;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_ABS is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE: string := "LPM_ABS";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  OVERFLOW : out std_logic);
end LPM_ABS;
 
architecture LPM_SYN of LPM_ABS is
begin
 
	process(DATA)
	begin
		if (DATA = -2 ** (LPM_WIDTH-1)) then
			OVERFLOW <= '1';
			RESULT <= (OTHERS => 'X');
		elsif DATA < 0 then
			RESULT <= 0 - DATA;
			OVERFLOW <= '0';
		else
			RESULT <= DATA;
			OVERFLOW <= '0';
		end if;
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_COUNTER is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_MODULUS: natural := 0;
			 LPM_DIRECTION : string := "UNUSED";
			 LPM_AVALUE : string := "UNUSED";
			 LPM_SVALUE : string := "UNUSED";
			 LPM_PVALUE : string := "UNUSED";
			 LPM_TYPE: string := "LPM_COUNTER";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0):= (OTHERS => '0');
		  CLOCK : in std_logic;
		  CLK_EN : in std_logic := '1';
		  CNT_EN : in std_logic := '1';
		  UPDOWN : in std_logic := '1';
		  SLOAD : in std_logic := '0';
		  SSET : in std_logic := '0';
		  SCLR : in std_logic := '0';
		  ALOAD : in std_logic := '0';
		  ASET : in std_logic := '0';
		  ACLR : in std_logic := '0';
          CIN : in std_logic := '1';
          COUT : out std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
 
end LPM_COUNTER;
 
architecture LPM_SYN of LPM_COUNTER is
 
signal COUNT : std_logic_vector(LPM_WIDTH downto 0);
signal INIT : std_logic := '0';
signal DIR : std_logic_vector(1 downto 0);
 
begin
 
    Direction: process (UPDOWN)
    begin
        if LPM_DIRECTION = "UP" then
            DIR <= "01";    -- increment
        elsif LPM_DIRECTION = "DOWN" then
            DIR <= "00";    -- decrement
        else
            DIR(0) <= UPDOWN;
            if UPDOWN = '0' or UPDOWN = '1' then
                DIR(1) <= '0';  -- increment or decrement
            else
                DIR(1) <= '1';  -- unknown
            end if;
        end if;
    end process Direction;
 
    Counter: process (CLOCK, ACLR, ASET, ALOAD, DATA, INIT)
	variable IAVALUE, ISVALUE : integer;
	variable IMODULUS : integer;
	begin
		if INIT = '0' then
 
            -- INITIALIZE TO PVALUE & SETUP VARIABLES --
			if LPM_PVALUE /= "UNUSED" then
				COUNT <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH+1);
			else
				COUNT <= (OTHERS => '0');
			end if;
 
			if LPM_MODULUS = 0 then
			    if LPM_WIDTH >= 32 then -- 32 bit integer limit
				IMODULUS := 0;
 			    else 
				IMODULUS := 2 ** LPM_WIDTH ;
			    end if;
			else
				IMODULUS := LPM_MODULUS;
			end if;
 
            -- CHECK PARAMETERS VALIDITY --
            if (LPM_DIRECTION /= "UNUSED" and LPM_DIRECTION /= "UP" and LPM_DIRECTION /= "DOWN") then
                ASSERT FALSE
                REPORT "Illegal LPM_DIRECTION property value for LPM_COUNTER!"
                SEVERITY ERROR;
            end if;
 
			INIT <= '1';
		else
			if ACLR =  '1' then
				COUNT <= (OTHERS => '0');
			elsif ASET = '1' then
				if LPM_AVALUE = "UNUSED" then
					COUNT <= (OTHERS => '1');
				else
					IAVALUE := str_to_int(LPM_AVALUE);
					COUNT <= conv_std_logic_vector(IAVALUE, LPM_WIDTH+1);
				end if;
			elsif ALOAD = '1' then
				COUNT(LPM_WIDTH-1 downto 0) <= DATA;
			elsif CLOCK'event and CLOCK = '1' then
				if CLK_EN = '1' then
					if SCLR = '1' then
						COUNT <= (OTHERS => '0');
					elsif SSET = '1' then
						if LPM_SVALUE = "UNUSED" then
							COUNT <= (OTHERS => '1');
						else
							ISVALUE := str_to_int(LPM_SVALUE);
							COUNT <= conv_std_logic_vector(ISVALUE, LPM_WIDTH+1);
						end if;
					elsif SLOAD = '1' then
						COUNT(LPM_WIDTH-1 downto 0) <= DATA;
					elsif CNT_EN = '1' then
						if IMODULUS = 1 then
							COUNT <= (OTHERS => '0');
                        elsif CIN = '1' then
                            if DIR(0) = '1' and DIR(1) = '0' then
                                -- INCREMENT --
                                if COUNT + 1 = IMODULUS then
                                    COUNT <= conv_std_logic_vector(0, LPM_WIDTH+1);
                                else
                                    COUNT <= COUNT + 1;
                                end if;
                            elsif DIR(0) = '0' and DIR(1) = '0' then
                                -- DECREMENT --
                                if COUNT = 0 then
                                    COUNT <= conv_std_logic_vector(IMODULUS-1, LPM_WIDTH+1);
                                else
                                    COUNT <= COUNT - 1;
                                end if;
                            end if;
						end if;
					end if;
				end if;
			end if;
		end if;
 
		COUNT(LPM_WIDTH) <= '0';
	end process Counter;
 
    CarryOut: process (COUNT, CIN, INIT, DIR)
	variable IMODULUS : integer;
	begin
		if INIT = '1' then
			if LPM_MODULUS = 0 then
				IMODULUS := 2 ** LPM_WIDTH;
			else
				IMODULUS := LPM_MODULUS;
			end if;
 
            if (DIR(1) = '0') then
                COUT <= '0';
                if IMODULUS = 1 then
                    COUT <= '1';
                elsif CIN = '1' then
                    if ((DIR(0) = '0' and COUNT = 0) or
                        (DIR(0) = '1' and (COUNT = IMODULUS - 1 or
                                           COUNT = 2**LPM_WIDTH-1) )) then
                        COUT <= '1';
                    end if;
                end if;
            end if;
		end if;
	end process CarryOut;
 
	Q <= COUNT(LPM_WIDTH-1 downto 0);
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_LATCH is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_AVALUE : string := "UNUSED";
			 LPM_PVALUE : string := "UNUSED";
			 LPM_TYPE: string := "LPM_LATCH";
			 LPM_HINT : string := "UNUSED");
    port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
		  GATE : in std_logic;
		  ASET : in std_logic := '0';
		  ACLR : in std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_LATCH;
 
architecture LPM_SYN of LPM_LATCH is
 
signal INIT : std_logic := '0';
 
begin
 
	process (DATA, GATE, ACLR, ASET, INIT)
	variable IAVALUE : integer;
	begin
 
		-- INITIALIZE TO PVALUE --
		if INIT = '0' then
			if LPM_PVALUE /= "UNUSED" then
				Q <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
			end if;
			INIT <= '1';
		else
			if ACLR =  '1' then
				Q <= (OTHERS => '0');
			elsif ASET = '1' then
				if LPM_AVALUE = "UNUSED" then
					Q <= (OTHERS => '1');
				else
					IAVALUE := str_to_int(LPM_AVALUE);
					Q <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
				end if;
			elsif GATE = '1' then
				Q <= DATA;
			end if;
		end if;
	end process;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_FF is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_AVALUE : string := "UNUSED";
			 LPM_SVALUE : string := "UNUSED";
			 LPM_PVALUE : string := "UNUSED";
			 LPM_FFTYPE: string := "DFF";
			 LPM_TYPE: string := "LPM_FF";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  CLOCK : in std_logic;
		  ENABLE : in std_logic := '1';
		  SLOAD : in std_logic := '0';
		  SCLR : in std_logic := '0';
		  SSET : in std_logic := '0';
		  ALOAD : in std_logic := '0';
		  ACLR : in std_logic := '0';
		  ASET : in std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_FF;
 
architecture LPM_SYN of LPM_FF is
 
signal IQ : std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
signal INIT : std_logic := '0';
 
begin
 
	process (DATA, CLOCK, ACLR, ASET, ALOAD, INIT)
	variable IAVALUE, ISVALUE : integer;
	begin
		-- INITIALIZE TO PVALUE --
		if INIT = '0' then
			if LPM_PVALUE /= "UNUSED" then
				IQ <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
			end if;
            if LPM_FFTYPE /= "DFF" and LPM_FFTYPE /= "TFF" then
                ASSERT FALSE
                REPORT "Illegal LPM_FFTYPE property value for LPM_FF!"
                SEVERITY ERROR;
            end if;
			INIT <= '1';
		elsif ACLR =  '1' then
			IQ <= (OTHERS => '0');
		elsif ASET = '1' then
			if LPM_AVALUE = "UNUSED" then
				IQ <= (OTHERS => '1');
			else
				IAVALUE := str_to_int(LPM_AVALUE);
				IQ <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
			end if;
		elsif ALOAD = '1' then
			if LPM_FFTYPE = "TFF" then
				IQ <= DATA;
			end if;
        elsif CLOCK'event and CLOCK = '1' and NOW > 0 ns then
			if ENABLE = '1' then
				if SCLR = '1' then
					IQ <= (OTHERS => '0');
				elsif SSET = '1' then
					if LPM_SVALUE = "UNUSED" then
						IQ <= (OTHERS => '1');
					else
						ISVALUE := str_to_int(LPM_SVALUE);
						IQ <= conv_std_logic_vector(ISVALUE, LPM_WIDTH);
					end if;
				elsif  SLOAD = '1' then
					if LPM_FFTYPE = "TFF" then
						IQ <= DATA;
					end if;
				else
					if LPM_FFTYPE = "TFF" then
						for i in 0 to LPM_WIDTH-1 loop
							if DATA(i) = '1' then
								IQ(i) <= not IQ(i);
							end if;
						end loop;
					else
						IQ <= DATA;
					end if;
				end if;
			end if;
		end if;
	end process;
 
	Q <= IQ;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_SHIFTREG is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_AVALUE : string := "UNUSED";
			 LPM_SVALUE : string := "UNUSED";
			 LPM_PVALUE : string := "UNUSED";
             LPM_DIRECTION: string := "UNUSED";
			 LPM_TYPE: string := "L_SHIFTREG";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
		  CLOCK : in std_logic;
		  ENABLE : in std_logic := '1';
		  SHIFTIN : in std_logic := '1';
		  LOAD : in std_logic := '0';
		  SCLR : in std_logic := '0';
		  SSET : in std_logic := '0';
		  ACLR : in std_logic := '0';
		  ASET : in std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  SHIFTOUT : out std_logic);
end LPM_SHIFTREG;
 
architecture LPM_SYN of LPM_SHIFTREG is
 
signal i_q : std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
signal INIT : std_logic := '0';
signal i_shiftout_pos : integer := LPM_WIDTH-1;
 
begin
 
    process (CLOCK, ACLR, ASET, INIT)
	variable IAVALUE, ISVALUE : integer;
	begin
		-- INITIALIZE TO PVALUE --
		if INIT = '0' then
			if LPM_PVALUE /= "UNUSED" then
                i_q <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
			end if;
            if LPM_DIRECTION = "LEFT" or LPM_DIRECTION = "UNUSED" then
                i_shiftout_pos <= LPM_WIDTH-1;
            elsif LPM_DIRECTION = "RIGHT" then
                i_shiftout_pos <= 0;
            else
                ASSERT FALSE
                REPORT "Illegal LPM_DIRECTION property value for LPM_SHIFTREG!"
                SEVERITY ERROR;
            end if;
			INIT <= '1';
		elsif ACLR =  '1' then
            i_q <= (OTHERS => '0');
		elsif ASET = '1' then
			if LPM_AVALUE = "UNUSED" then
                i_q <= (OTHERS => '1');
			else
				IAVALUE := str_to_int(LPM_AVALUE);
                i_q <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
			end if;
		elsif CLOCK'event and CLOCK = '1' then
			if ENABLE = '1' then
				if SCLR = '1' then
                    i_q <= (OTHERS => '0');
				elsif SSET = '1' then
					if LPM_SVALUE = "UNUSED" then
                        i_q <= (OTHERS => '1');
					else
						ISVALUE := str_to_int(LPM_SVALUE);
                        i_q <= conv_std_logic_vector(ISVALUE, LPM_WIDTH);
					end if;
                elsif LOAD = '1' then
                    i_q <= DATA;
                else
                    if LPM_WIDTH < 2 then
                        i_q(0) <= SHIFTIN;
                    elsif LPM_DIRECTION = "LEFT" then
                        i_q <= (i_q(LPM_WIDTH-2 downto 0) & SHIFTIN);
                    else
                        i_q <= (SHIFTIN & i_q(LPM_WIDTH-1 downto 1));
                    end if;
				end if;
			end if;
		end if;
	end process;
 
    Q <= i_q;
    SHIFTOUT <= i_q(i_shiftout_pos);
 
end LPM_SYN;
 
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all; 
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
use std.textio.all;
 
entity LPM_RAM_DQ is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
			 LPM_NUMWORDS : natural := 0;
			 LPM_INDATA : string := "REGISTERED";
			 LPM_ADDRESS_CONTROL: string := "REGISTERED";
			 LPM_OUTDATA : string := "REGISTERED";
			 LPM_FILE : string := "UNUSED";
			 LPM_TYPE : string := L_RAM_DQ;
			 USE_EAB  : string := "OFF";
			 INTENDED_DEVICE_FAMILY  : string := "UNUSED";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
		  INCLOCK : in std_logic := '0';
		  OUTCLOCK : in std_logic := '0';
		  WE : in std_logic;
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
 
	function int_to_str( value : integer ) return string is
	variable ivalue,index : integer;
	variable digit : integer;
	variable line_no: string(8 downto 1) := "        ";  
	begin
		ivalue := value;
		index := 1;
		while (ivalue > 0) loop
			digit := ivalue MOD 10;
			ivalue := ivalue/10;
			case digit is
				when 0 =>
					line_no(index) := '0';
				when 1 =>
					line_no(index) := '1';
				when 2 =>
					line_no(index) := '2';
				when 3 =>
					line_no(index) := '3';
				when 4 =>
					line_no(index) := '4';
				when 5 =>
					line_no(index) := '5';
				when 6 =>
					line_no(index) := '6';
				when 7 =>
					line_no(index) := '7';
				when 8 =>
					line_no(index) := '8';
				when 9 =>
					line_no(index) := '9';
				when others =>
					ASSERT FALSE
					REPORT "Illegal number!"
					SEVERITY ERROR;
			end case;
			index := index + 1;
		end loop;
		return line_no;
	end;
 
	function hex_str_to_int( str : string ) return integer is
	variable len : integer := str'length;
	variable ivalue : integer := 0;
	variable digit : integer;
	begin
		for i in len downto 1 loop
			case str(i) is
				when '0' =>
					digit := 0;
				when '1' =>
					digit := 1;
				when '2' =>
					digit := 2;
				when '3' =>
					digit := 3;
				when '4' =>
					digit := 4;
				when '5' =>
					digit := 5;
				when '6' =>
					digit := 6;
				when '7' =>
					digit := 7;
				when '8' =>
					digit := 8;
				when '9' =>
					digit := 9;
				when 'A' =>
					digit := 10;
				when 'a' =>
					digit := 10;
				when 'B' =>
					digit := 11;
				when 'b' =>
					digit := 11;
				when 'C' =>
					digit := 12;
				when 'c' =>
					digit := 12;
				when 'D' =>
					digit := 13;
				when 'd' =>
					digit := 13;
				when 'E' =>
					digit := 14;
				when 'e' =>
					digit := 14;
				when 'F' =>
					digit := 15;
				when 'f' =>
					digit := 15;
				when others =>
					ASSERT FALSE
					REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
					SEVERITY ERROR;
			end case;
			ivalue := ivalue * 16 + digit;
		end loop;
		return ivalue;
	end;
 
	procedure Shrink_line(L : inout LINE; pos : in integer) is
	subtype nstring is string(1 to pos);
	variable stmp : nstring;
	begin
		if pos >= 1 then
			read(l, stmp);
		end if;
	end;
 
end LPM_RAM_DQ;
 
architecture LPM_SYN of lpm_ram_dq is
 
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal data_tmp : std_logic_vector(lpm_width-1 downto 0);
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_tmp : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal address_tmp : std_logic_vector(lpm_widthad-1 downto 0);
signal address_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
signal we_tmp : std_logic;
signal we_reg : std_logic := '0';
 
begin
 
	sync: process(data, data_reg, address, address_reg,
				  we, we_reg, q_tmp, q_reg)
	begin
		if (lpm_address_control = "REGISTERED") then
			address_tmp <= address_reg;
			we_tmp <= we_reg;
        elsif (lpm_address_control = "UNREGISTERED") then
			address_tmp <= address;
			we_tmp <= we;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_DQ!"
            SEVERITY ERROR;
		end if;
		if (lpm_indata = "REGISTERED") then
			data_tmp <= data_reg;
        elsif (lpm_indata = "UNREGISTERED") then
			data_tmp <= data;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_INDATA property value for LPM_RAM_DQ!"
            SEVERITY ERROR;
		end if;
		if (lpm_outdata = "REGISTERED") then
			q <= q_reg;
        elsif (lpm_outdata = "UNREGISTERED") then
			q <= q_tmp;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_DQ!"
            SEVERITY ERROR;
		end if;
	end process;
 
	input_reg: process (inclock)
	begin
		if inclock'event and inclock = '1' then
			data_reg <= data;
			address_reg <= address;
			we_reg <= we;
		end if;
	end process;
 
	output_reg: process (outclock)
	begin
		if outclock'event and outclock = '1' then
			q_reg <= q_tmp;
		end if;
	end process;
 
	memory: process(data_tmp, we_tmp, address_tmp, inclock)
	variable mem_data : lpm_memory;
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
	variable mem_init: boolean := false;
	variable i,j,k,n,m,lineno: integer := 0;
	variable buf: line ;
	variable booval: boolean ;
	FILE unused_file: TEXT IS OUT "UNUSED";
	FILE mem_data_file: TEXT IS IN LPM_FILE;
	variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
	variable startadd: string(4 downto 1);
	variable ibase: integer := 0;
	variable ibyte: integer := 0;
	variable istartadd: integer := 0;
	variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
	begin
		-- INITIALIZE --
		if NOT(mem_init) then
			-- INITIALIZE TO 0 --
			for i in mem_data'LOW to mem_data'HIGH loop
				mem_data(i) := (OTHERS => '0');
			end loop;
 
			if (LPM_FILE = "UNUSED") then
				ASSERT FALSE
				REPORT "Initialization file not found!"
				SEVERITY WARNING;
			else
				WHILE NOT ENDFILE(mem_data_file) loop
					booval := true;
					READLINE(mem_data_file, buf);
					lineno := lineno + 1;
					check_sum_vec := (OTHERS => '0');
					if (buf(buf'LOW) = ':') then
						i := 1;
						shrink_line(buf, i);
						READ(L=>buf, VALUE=>byte, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
							SEVERITY ERROR;
						end if;
						ibyte := hex_str_to_int(byte);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
						READ(L=>buf, VALUE=>startadd, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						istartadd := hex_str_to_int(startadd);
						addr(2) := startadd(4);
						addr(1) := startadd(3);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						addr(2) := startadd(2);
						addr(1) := startadd(1);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						READ(L=>buf, VALUE=>rec_type, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
					else
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
						SEVERITY ERROR;
					end if;
					case rec_type is
						when "00"=>     -- Data record
							i := 0;
							k := lpm_width / 8;
							if ((lpm_width MOD 8) /= 0) then
								k := k + 1; 
							end if;
							-- k = no. of bytes per CAM entry.
							while (i < ibyte) loop
                                                                mem_data_word := (others => '0');
                                                                n := (k - 1)*8;
                                                                m := lpm_width - 1;
								for j in 1 to k loop
									READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
									if not (booval) then
										ASSERT FALSE
										REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
										SEVERITY ERROR;
									end if;
									check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
                                                                        m := n - 1;
                                                                        n := n - 8;
								end loop;
								i := i + k;
								mem_data(ibase + istartadd) := mem_data_word;
								istartadd := istartadd + 1;
							end loop;
						when "01"=>
							exit;
						when "02"=>
							ibase := 0;
							if (ibyte /= 2) then
								ASSERT FALSE
								REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
								SEVERITY ERROR;
							end if;
							for i in 0 to (ibyte-1) loop
								READ(L=>buf, VALUE=>base,good=>booval);
								ibase := ibase * 256 + hex_str_to_int(base);
								if not (booval) then
									ASSERT FALSE
									REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
									SEVERITY ERROR;
								end if;
								check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
							end loop;
							ibase := ibase * 16;
						when OTHERS =>
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
							SEVERITY ERROR;
					end case;
					READ(L=>buf, VALUE=>checksum,good=>booval);
					if not (booval) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
						SEVERITY ERROR;
					end if;
 
					check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
					check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
 
					if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
						SEVERITY ERROR;
					end if;
				end loop;
			end if;
			mem_init := TRUE;
		end if;
 
		-- MEMORY FUNCTION --
		if we_tmp = '1' then
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_address_control = "REGISTERED")) then
			    if (inclock = '0') then
                                mem_data (conv_integer(address_tmp)) := data_tmp ;
                            end if;
                        else
			    mem_data (conv_integer(address_tmp)) := data_tmp;
                        end if;
		end if;
		q_tmp <= mem_data(conv_integer(address_tmp));
	end process;
 
end LPM_SYN;
 
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
use std.textio.all;
 
entity LPM_RAM_DP is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
			 LPM_NUMWORDS : natural := 0;
			 LPM_INDATA : string := "REGISTERED";
			 LPM_OUTDATA : string := "REGISTERED";
			 LPM_RDADDRESS_CONTROL : string := "REGISTERED";
			 LPM_WRADDRESS_CONTROL : string := "REGISTERED";
			 LPM_FILE : string := "UNUSED";
			 LPM_TYPE : string := "LPM_RAM_DP";
			 USE_EAB  : string := "OFF";
			 INTENDED_DEVICE_FAMILY  : string := "UNUSED";
			 RDEN_USED  : string := "TRUE";
			 LPM_HINT : string := "UNUSED");
	port (RDCLOCK : in std_logic := '0';
		  RDCLKEN : in std_logic := '1';
		  RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
		  RDEN : in std_logic := '1';
		  DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
		  WREN : in std_logic;
		  WRCLOCK : in std_logic := '0';
		  WRCLKEN : in std_logic := '1';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
 
	function int_to_str( value : integer ) return string is
	variable ivalue,index : integer;
	variable digit : integer;
	variable line_no: string(8 downto 1) := "        ";  
	begin
		ivalue := value;
		index := 1;
		while (ivalue > 0) loop
			digit := ivalue MOD 10;
			ivalue := ivalue/10;
			case digit is
				when 0 =>
					line_no(index) := '0';
				when 1 =>
					line_no(index) := '1';
				when 2 =>
					line_no(index) := '2';
				when 3 =>
					line_no(index) := '3';
				when 4 =>
					line_no(index) := '4';
				when 5 =>
					line_no(index) := '5';
				when 6 =>
					line_no(index) := '6';
				when 7 =>
					line_no(index) := '7';
				when 8 =>
					line_no(index) := '8';
				when 9 =>
					line_no(index) := '9';
				when others =>
					ASSERT FALSE
					REPORT "Illegal number!"
					SEVERITY ERROR;
			end case;
			index := index + 1;
		end loop;
		return line_no;
	end;
 
	function hex_str_to_int( str : string ) return integer is
	variable len : integer := str'length;
	variable ivalue : integer := 0;
	variable digit : integer;
	begin
		for i in len downto 1 loop
			case str(i) is
				when '0' =>
					digit := 0;
				when '1' =>
					digit := 1;
				when '2' =>
					digit := 2;
				when '3' =>
					digit := 3;
				when '4' =>
					digit := 4;
				when '5' =>
					digit := 5;
				when '6' =>
					digit := 6;
				when '7' =>
					digit := 7;
				when '8' =>
					digit := 8;
				when '9' =>
					digit := 9;
				when 'A' =>
					digit := 10;
				when 'a' =>
					digit := 10;
				when 'B' =>
					digit := 11;
				when 'b' =>
					digit := 11;
				when 'C' =>
					digit := 12;
				when 'c' =>
					digit := 12;
				when 'D' =>
					digit := 13;
				when 'd' =>
					digit := 13;
				when 'E' =>
					digit := 14;
				when 'e' =>
					digit := 14;
				when 'F' =>
					digit := 15;
				when 'f' =>
					digit := 15;
				when others =>
					ASSERT FALSE
					REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
					SEVERITY ERROR;
			end case;
			ivalue := ivalue * 16 + digit;
		end loop;
		return ivalue;
	end;
 
	procedure Shrink_line(L : inout LINE; pos : in integer) is
	subtype nstring is string(1 to pos);
	variable stmp : nstring;
	begin
		if pos >= 1 then
			read(l, stmp);
		end if;
	end;
 
end LPM_RAM_DP;
 
architecture LPM_SYN of lpm_ram_dp is
 
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal data_tmp : std_logic_vector(lpm_width-1 downto 0);
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_tmp : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal rdaddress_tmp : std_logic_vector(lpm_widthad-1 downto 0);
signal rdaddress_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
signal wraddress_tmp : std_logic_vector(lpm_widthad-1 downto 0);
signal wraddress_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
signal wren_tmp : std_logic;
signal wren_reg : std_logic := '0';
signal rden_tmp : std_logic;
signal rden_reg : std_logic := '0';
 
begin
        rden_tmp <= '1' when rden_used = "FALSE" else rden when lpm_rdaddress_control = "UNREGISTERED" else rden_reg;
        rdaddress_tmp <= rdaddress when lpm_rdaddress_control = "UNREGISTERED" else rdaddress_reg;
        wren_tmp <= wren when lpm_wraddress_control = "UNREGISTERED" else wren_reg;
        wraddress_tmp <= wraddress when lpm_wraddress_control = "UNREGISTERED" else wraddress_reg;
        data_tmp <= data when lpm_indata = "UNREGISTERED" else data_reg;
        q <= q_tmp when lpm_outdata = "UNREGISTERED" else q_reg;
 
	input_reg: process (wrclock)
	begin
		if wrclock'event and wrclock = '1' and wrclken = '1' then
			data_reg <= data;
			wraddress_reg <= wraddress;
                        wren_reg <= wren;
		end if;
	end process;
 
	output_reg: process (rdclock)
	begin
		if rdclock'event and rdclock = '1' and rdclken = '1' then
			rdaddress_reg <= rdaddress;
			rden_reg <= rden; 
			q_reg <= q_tmp;
		end if;
	end process;
 
	memory: process(data_tmp, wren_tmp, rdaddress_tmp, wraddress_tmp, rden_tmp, wrclock)
	variable mem_data : lpm_memory;
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
	variable mem_init: boolean := false;
	variable i,j,k,n,m,lineno: integer := 0;
	variable buf: line ;
	variable booval: boolean ;
	FILE unused_file: TEXT IS OUT "UNUSED";
	FILE mem_data_file: TEXT IS IN LPM_FILE;
	variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
	variable startadd: string(4 downto 1);
	variable ibase: integer := 0;
	variable ibyte: integer := 0;
	variable istartadd: integer := 0;
	variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
	begin
		-- INITIALIZE --
		if NOT(mem_init) then
			-- INITIALIZE TO 0 --
			for i in mem_data'LOW to mem_data'HIGH loop
				mem_data(i) := (OTHERS => '0');
			end loop;
 
                        if ((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) then
                            if intended_device_family = "APEX20K" then
                                q_tmp <= (others => '0');
                            else
                                q_tmp <= (others => '1');
                            end if;
                        end if;
 
			if (LPM_FILE = "UNUSED") then
				ASSERT FALSE
				REPORT "Initialization file not found!"
				SEVERITY WARNING;
			else
				WHILE NOT ENDFILE(mem_data_file) loop
					booval := true;
					READLINE(mem_data_file, buf);
					lineno := lineno + 1;
					check_sum_vec := (OTHERS => '0');
					if (buf(buf'LOW) = ':') then
						i := 1;
						shrink_line(buf, i);
						READ(L=>buf, VALUE=>byte, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
							SEVERITY ERROR;
						end if;
						ibyte := hex_str_to_int(byte);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
						READ(L=>buf, VALUE=>startadd, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						istartadd := hex_str_to_int(startadd);
						addr(2) := startadd(4);
						addr(1) := startadd(3);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						addr(2) := startadd(2);
						addr(1) := startadd(1);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						READ(L=>buf, VALUE=>rec_type, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
					else
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
						SEVERITY ERROR;
					end if;
					case rec_type is
						when "00"=>     -- Data record
							i := 0;
							k := lpm_width / 8;
							if ((lpm_width MOD 8) /= 0) then
								k := k + 1; 
							end if;
							-- k = no. of bytes per CAM entry.
							while (i < ibyte) loop
                                                                mem_data_word := (others => '0');
                                                                n := (k - 1)*8;
                                                                m := lpm_width - 1;
								for j in 1 to k loop
									READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
									if not (booval) then
										ASSERT FALSE
										REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
										SEVERITY ERROR;
									end if;
									check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
                                                                        m := n - 1;
                                                                        n := n - 8;
								end loop;
								i := i + k;
								mem_data(ibase + istartadd) := mem_data_word;
								istartadd := istartadd + 1;
							end loop;
						when "01"=>
							exit;
						when "02"=>
							ibase := 0;
							if (ibyte /= 2) then
								ASSERT FALSE
								REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
								SEVERITY ERROR;
							end if;
							for i in 0 to (ibyte-1) loop
								READ(L=>buf, VALUE=>base,good=>booval);
								ibase := ibase * 256 + hex_str_to_int(base);
								if not (booval) then
									ASSERT FALSE
									REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
									SEVERITY ERROR;
								end if;
								check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
							end loop;
							ibase := ibase * 16;
						when OTHERS =>
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
							SEVERITY ERROR;
					end case;
					READ(L=>buf, VALUE=>checksum,good=>booval);
					if not (booval) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
						SEVERITY ERROR;
					end if;
 
					check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
					check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
 
					if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
						SEVERITY ERROR;
					end if;
				end loop;
			end if;
			mem_init := TRUE;
		end if;
 
		-- MEMORY FUNCTION --
		if wren_tmp = '1' then
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_wraddress_control = "REGISTERED")) then
			    if (wrclock = '0') then
                                mem_data (conv_integer(wraddress_tmp)) := data_tmp ;
                            end if;
                        else
			    mem_data (conv_integer(wraddress_tmp)) := data_tmp ;
                        end if;
		end if;
		if (rden_tmp = '1') or (rden_used = "FALSE") then
			q_tmp <= mem_data(conv_integer(rdaddress_tmp));
		else if ((intended_device_family = "APEX20K") and (use_eab = "ON")) then
		        q_tmp <= (OTHERS => '0');
                     end if;
		end if;
	end process;
 
end LPM_SYN;
 
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
use std.textio.all;
 
entity LPM_RAM_IO is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
			 LPM_NUMWORDS : natural := 0;
			 LPM_INDATA : string := "REGISTERED";
			 LPM_ADDRESS_CONTROL : string := "REGISTERED";
			 LPM_OUTDATA : string := "REGISTERED";
			 LPM_FILE : string := "UNUSED";
			 LPM_TYPE : string := "LPM_RAM_IO";
			 USE_EAB  : string := "OFF";
			 INTENDED_DEVICE_FAMILY  : string := "UNUSED";
			 LPM_HINT : string := "UNUSED");
	port (ADDRESS : in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0);
		  INCLOCK : in STD_LOGIC := '0';
		  OUTCLOCK : in STD_LOGIC := '0';
		  MEMENAB : in STD_LOGIC := '1';
		  OUTENAB : in STD_LOGIC := 'Z';
		  WE : in STD_LOGIC := 'Z';
		  DIO : inout STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0));
 
	function int_to_str( value : integer ) return string is
	variable ivalue,index : integer;
	variable digit : integer;
	variable line_no: string(8 downto 1) := "        ";  
	begin
		ivalue := value;
		index := 1;
		while (ivalue > 0 ) loop
			digit := ivalue MOD 10;
			ivalue := ivalue/10;
			case digit is
				when 0 =>
					line_no(index) := '0';
				when 1 =>
					line_no(index) := '1';
				when 2 =>
					line_no(index) := '2';
				when 3 =>
					line_no(index) := '3';
				when 4 =>
					line_no(index) := '4';
				when 5 =>
					line_no(index) := '5';
				when 6 =>
					line_no(index) := '6';
				when 7 =>
					line_no(index) := '7';
				when 8 =>
					line_no(index) := '8';
				when 9 =>
					line_no(index) := '9';
				when others =>
					ASSERT FALSE
					REPORT "Illegal number!"
					SEVERITY ERROR;
			end case;
			index := index + 1;
		end loop;
		return line_no;
	end;
 
	function hex_str_to_int( str : string ) return integer is
	variable len : integer := str'length;
	variable ivalue : integer := 0;
	variable digit : integer;
	begin
		for i in len downto 1 loop
			case str(i) is
				when '0' =>
					digit := 0;
				when '1' =>
					digit := 1;
				when '2' =>
					digit := 2;
				when '3' =>
					digit := 3;
				when '4' =>
					digit := 4;
				when '5' =>
					digit := 5;
				when '6' =>
					digit := 6;
				when '7' =>
					digit := 7;
				when '8' =>
					digit := 8;
				when '9' =>
					digit := 9;
				when 'A' =>
					digit := 10;
				when 'a' =>
					digit := 10;
				when 'B' =>
					digit := 11;
				when 'b' =>
					digit := 11;
				when 'C' =>
					digit := 12;
				when 'c' =>
					digit := 12;
				when 'D' =>
					digit := 13;
				when 'd' =>
					digit := 13;
				when 'E' =>
					digit := 14;
				when 'e' =>
					digit := 14;
				when 'F' =>
					digit := 15;
				when 'f' =>
					digit := 15;
				when others =>
					ASSERT FALSE
					REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
					SEVERITY ERROR;
			end case;
			ivalue := ivalue * 16 + digit;
		end loop;
		return ivalue;
	end;
 
	procedure Shrink_line(L : inout LINE; pos : in integer) is
	subtype nstring is string(1 to pos);
	variable stmp : nstring;
	begin
		if pos >= 1 then
			read(l, stmp);
		end if;
	end;
 
end LPM_RAM_IO;
 
architecture LPM_SYN of lpm_ram_io is
 
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal data_tmp, di, do : std_logic_vector(lpm_width-1 downto 0);
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_tmp, q : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
signal address_tmp : std_logic_vector(lpm_widthad-1 downto 0);
signal address_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
signal we_tmp : std_logic;
signal we_reg : std_logic := '0';
signal memenab_tmp : std_logic;
signal memenab_reg : std_logic := '0';
 
signal outenab_used : std_logic;
 
-- provided for MP2 compliance
signal we_used : std_logic;
 
begin
	sync: process(di, data_reg, address, address_reg, memenab, memenab_reg, 
				  we,we_reg, q_tmp, q_reg)
	begin
		if (lpm_address_control = "REGISTERED") then
			address_tmp <= address_reg;
			we_tmp <= we_reg;
			memenab_tmp <= memenab_reg;
        elsif (lpm_address_control = "UNREGISTERED") then
			address_tmp <= address;
			we_tmp <= we;
			memenab_tmp <= memenab;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_IO!"
            SEVERITY ERROR;
		end if;
		if (lpm_indata = "REGISTERED") then
			data_tmp <= data_reg;
        elsif (lpm_indata = "UNREGISTERED") then
			data_tmp <= di;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_INDATA property value for LPM_RAM_IO!"
            SEVERITY ERROR;
		end if;
		if (lpm_outdata = "REGISTERED") then
			q <= q_reg;
        elsif (lpm_outdata = "UNREGISTERED") then
			q <= q_tmp;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_IO!"
            SEVERITY ERROR;
		end if;
	end process;
 
	input_reg: process (inclock)
	begin
		if inclock'event and inclock = '1' then
			data_reg <= di;
			address_reg <= address;
			we_reg <= we;
			memenab_reg <= memenab;
		end if;
	end process;
 
	output_reg: process (outclock)
	begin
		if outclock'event and outclock = '1' then
			q_reg <= q_tmp;
		end if;
	end process;
 
	memory: process(data_tmp, we_tmp, memenab_tmp, outenab, address_tmp, inclock)
	variable mem_data : lpm_memory;
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
	variable mem_init: boolean := false;
	variable i,j,k,n,m,lineno: integer := 0;
	variable buf: line ;
	variable booval: boolean ;
	FILE unused_file: TEXT IS OUT "UNUSED";
	FILE mem_data_file: TEXT IS IN LPM_FILE;
	variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
	variable startadd: string(4 downto 1);
	variable ibase: integer := 0;
	variable ibyte: integer := 0;
	variable istartadd: integer := 0;
	variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
	begin
		-- INITIALIZE --
		if NOT(mem_init) then
			-- INITIALIZE TO 0 --
			for i in mem_data'LOW to mem_data'HIGH loop
				mem_data(i) := (OTHERS => '0');
			end loop;
 
			if (outenab = 'Z' and we = 'Z') then
				ASSERT FALSE
				REPORT "One of OutEnab or WE must be used!"
				SEVERITY ERROR;
			end if;
 
			-- In reality, both are needed in current TDF implementation
			if (outenab /= 'Z' and we /= 'Z') then
				ASSERT FALSE
				REPORT "Only one of OutEnab or WE should be used!"
				-- Change severity to ERROR for full LPM 220 compliance
				SEVERITY WARNING;
			end if;
 
			-- Comment out the following 5 lines for full LPM 220 compliance
			if (we = 'Z') then
				ASSERT FALSE
				REPORT "WE is required!"
				SEVERITY WARNING;
			end if;
 
			if (outenab = 'Z') then
				outenab_used <= '0';
				we_used <= '1';
			else
				outenab_used <= '1';
				we_used <= '0';
			end if;
 
			-- Comment out the following 5 lines for full LPM 220 compliance
			if (we = 'Z') then
				we_used <= '0';
			else
				we_used <= '1';
			end if;
 
			if (LPM_FILE = "UNUSED") then
				ASSERT FALSE
				REPORT "Initialization file not found!"
				SEVERITY WARNING;
			else
				WHILE NOT ENDFILE(mem_data_file) loop
					booval := true;
					READLINE(mem_data_file, buf);
					lineno := lineno + 1;
					check_sum_vec := (OTHERS => '0');
					if (buf(buf'LOW) = ':') then
						i := 1;
						shrink_line(buf, i);
						READ(L=>buf, VALUE=>byte, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
							SEVERITY ERROR;
						end if;
						ibyte := hex_str_to_int(byte);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
						READ(L=>buf, VALUE=>startadd, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						istartadd := hex_str_to_int(startadd);
						addr(2) := startadd(4);
						addr(1) := startadd(3);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						addr(2) := startadd(2);
						addr(1) := startadd(1);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						READ(L=>buf, VALUE=>rec_type, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
					else
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
						SEVERITY ERROR;
					end if;
					case rec_type is
						when "00"=>     -- Data record
							i := 0;
							k := lpm_width / 8;
							if ((lpm_width MOD 8) /= 0) then
								k := k + 1; 
							end if;
							-- k = no. of bytes per CAM entry.
							while (i < ibyte) loop
                                                                mem_data_word := (others => '0');
                                                                n := (k - 1)*8;
                                                                m := lpm_width - 1;
								for j in 1 to k loop
									READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
									if not (booval) then
										ASSERT FALSE
										REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
										SEVERITY ERROR;
									end if;
									check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
                                                                        m := n - 1;
                                                                        n := n - 8;
								end loop;
								i := i + k;
                                                                mem_data(ibase + istartadd) := mem_data_word;
								istartadd := istartadd + 1;
							end loop;
						when "01"=>
							exit;
						when "02"=>
							ibase := 0;
							if (ibyte /= 2) then
								ASSERT FALSE
								REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
								SEVERITY ERROR;
							end if;
							for i in 0 to (ibyte-1) loop
								READ(L=>buf, VALUE=>base,good=>booval);
								ibase := ibase * 256 + hex_str_to_int(base);
								if not (booval) then
									ASSERT FALSE
									REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
									SEVERITY ERROR;
								end if;
								check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
							end loop;
							ibase := ibase * 16;
						when OTHERS =>
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
							SEVERITY ERROR;
					end case;
					READ(L=>buf, VALUE=>checksum,good=>booval);
					if not (booval) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
						SEVERITY ERROR;
					end if;
 
					check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
					check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
 
					if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
						SEVERITY ERROR;
					end if;
				end loop;
			end if;
			mem_init := TRUE;
		end if;
 
		-- MEMORY FUNCTION --
		if (((we_used = '1' and we_tmp = '1')
			 or (outenab_used = '1' and we_used = '0' and outenab = '0'))
			and memenab_tmp = '1') then
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_address_control = "REGISTERED")) then
			    if inclock = '0' then
                                mem_data (conv_integer(address_tmp)) := data_tmp ;
                            end if;
                        else
			    mem_data (conv_integer(address_tmp)) := data_tmp ;
                        end if;
			q_tmp <= data_tmp ;
		else
			q_tmp <= mem_data(conv_integer(address_tmp)) ; 
		end if;
	end process;
 
	di <= dio when ((outenab_used = '0' and we = '1')
					or (outenab_used = '1' and outenab = '0'))
			  else (OTHERS => 'Z');
	do <= q when memenab_tmp = '1' else (OTHERS => 'Z') ;
	dio <= do when ((outenab_used = '0' and we = '0')
					or (outenab_used = '1' and outenab = '1'))
			  else (OTHERS => 'Z');
 
end LPM_SYN;
 
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
use std.textio.all;
 
entity LPM_ROM is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
			 LPM_NUMWORDS : natural := 0;
			 LPM_ADDRESS_CONTROL : string := "REGISTERED";
			 LPM_OUTDATA : string := "REGISTERED";
			 LPM_FILE : string;
			 LPM_TYPE : string := "LPM_ROM";
			 INTENDED_DEVICE_FAMILY  : string := "UNUSED";
			 LPM_HINT : string := "UNUSED");
	port (ADDRESS : in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0);
		  INCLOCK : in STD_LOGIC := '0';
		  OUTCLOCK : in STD_LOGIC := '0';
		  MEMENAB : in STD_LOGIC := '1';
		  Q : out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0));
 
	function int_to_str( value : integer ) return string is
	variable ivalue,index : integer;
	variable digit : integer;
	variable line_no: string(8 downto 1) := "        ";  
	begin
		ivalue := value;
		index := 1;
		while (ivalue > 0 ) loop
			digit := ivalue MOD 10;
			ivalue := ivalue/10;
			case digit is
				when 0 =>
					line_no(index) := '0';
				when 1 =>
					line_no(index) := '1';
				when 2 =>
					line_no(index) := '2';
				when 3 =>
					line_no(index) := '3';
				when 4 =>
					line_no(index) := '4';
				when 5 =>
					line_no(index) := '5';
				when 6 =>
					line_no(index) := '6';
				when 7 =>
					line_no(index) := '7';
				when 8 =>
					line_no(index) := '8';
				when 9 =>
					line_no(index) := '9';
				when others =>
					ASSERT FALSE
					REPORT "Illegal number!"
					SEVERITY ERROR;
			end case;
			index := index + 1;
		end loop;
		return line_no;
	end;
 
	function hex_str_to_int( str : string ) return integer is
	variable len : integer := str'length;
	variable ivalue : integer := 0;
	variable digit : integer;
	begin
		for i in len downto 1 loop
			case str(i) is
				when '0' =>
					digit := 0;
				when '1' =>
					digit := 1;
				when '2' =>
					digit := 2;
				when '3' =>
					digit := 3;
				when '4' =>
					digit := 4;
				when '5' =>
					digit := 5;
				when '6' =>
					digit := 6;
				when '7' =>
					digit := 7;
				when '8' =>
					digit := 8;
				when '9' =>
					digit := 9;
				when 'A' =>
					digit := 10;
				when 'a' =>
					digit := 10;
				when 'B' =>
					digit := 11;
				when 'b' =>
					digit := 11;
				when 'C' =>
					digit := 12;
				when 'c' =>
					digit := 12;
				when 'D' =>
					digit := 13;
				when 'd' =>
					digit := 13;
				when 'E' =>
					digit := 14;
				when 'e' =>
					digit := 14;
				when 'F' =>
					digit := 15;
				when 'f' =>
					digit := 15;
				when others =>
					ASSERT FALSE
					REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
					SEVERITY ERROR;
			end case;
			ivalue := ivalue * 16 + digit;
		end loop;
		return ivalue;
	end;
 
	procedure Shrink_line(L : inout LINE; pos : in integer) is
	subtype nstring is string(1 to pos);
	variable stmp : nstring;
	begin
		if pos >= 1 then
			read(l, stmp);
		end if;
	end;
 
end LPM_ROM;
 
architecture LPM_SYN of lpm_rom is
 
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal q2, q_tmp, q_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
signal address_tmp, address_reg : std_logic_vector(lpm_widthad-1 downto 0);
 
begin
 
	enable_mem: process(memenab, q2)
	begin
		if (memenab = '1') then
			q <= q2;
		else
			q <= (OTHERS => 'Z');
		end if;
	end process;
 
	sync: process(address, address_reg, q_tmp, q_reg)
	begin
		if (lpm_address_control = "REGISTERED") then
			address_tmp <= address_reg;
        elsif (lpm_address_control = "UNREGISTERED") then
			address_tmp <= address;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_ROM!"
            SEVERITY ERROR;
		end if;
		if (lpm_outdata = "REGISTERED") then
			q2 <= q_reg;
        elsif (lpm_outdata = "UNREGISTERED") then
			q2 <= q_tmp;
        else
            ASSERT FALSE
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_ROM!"
            SEVERITY ERROR;
		end if;
	end process;
 
	input_reg: process (inclock)
	begin
		if inclock'event and inclock = '1' then
			address_reg <= address;
		end if;
	end process;
 
	output_reg: process (outclock)
	begin
		if outclock'event and outclock = '1' then
			q_reg <= q_tmp;
		end if;
	end process;
 
	memory: process(memenab, address_tmp)
	variable mem_data : lpm_memory;
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
	variable mem_init: boolean := false;
	variable i, j, k, n, m, lineno : integer := 0;
	variable buf: line ;
	variable booval: boolean ;
	FILE mem_data_file: TEXT IS IN LPM_FILE;
	variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
	variable startadd: string(4 downto 1);
	variable ibase: integer := 0;
	variable ibyte: integer := 0;
	variable istartadd: integer := 0;
	variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
	begin
		-- INITIALIZE --
		if NOT(mem_init) then
			-- INITIALIZE TO 0 --
			for i in mem_data'LOW to mem_data'HIGH loop
				mem_data(i) := (OTHERS => '0');
			end loop;
 
            if (LPM_FILE = "UNUSED" or LPM_FILE = "") then
                ASSERT FALSE
				REPORT "Initialization file not found!"
				SEVERITY ERROR;
			else
				WHILE NOT ENDFILE(mem_data_file) loop
					booval := true;
					READLINE(mem_data_file, buf);
					lineno := lineno + 1;
					check_sum_vec := (OTHERS => '0');
					if (buf(buf'LOW) = ':') then
						i := 1;
						shrink_line(buf, i);
						READ(L=>buf, VALUE=>byte, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
							SEVERITY ERROR;
						end if;
						ibyte := hex_str_to_int(byte);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
						READ(L=>buf, VALUE=>startadd, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						istartadd := hex_str_to_int(startadd);
						addr(2) := startadd(4);
						addr(1) := startadd(3);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						addr(2) := startadd(2);
						addr(1) := startadd(1);
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
						READ(L=>buf, VALUE=>rec_type, good=>booval);
						if not (booval) then
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
							SEVERITY ERROR;
						end if;
						check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
					else
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
						SEVERITY ERROR;
					end if;
					case rec_type is
						when "00"=>  -- Data record
							i := 0;
							k := lpm_width / 8;
							if ((lpm_width MOD 8) /= 0) then
								k := k + 1; 
							end if;
							-- k = no. of bytes per CAM entry.
							while (i < ibyte) loop
                                                                mem_data_word := (others => '0');
                                                                n := (k - 1)*8;
                                                                m := lpm_width - 1;
								for j in 1 to k loop
									READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
									if not (booval) then
										ASSERT FALSE
										REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
										SEVERITY ERROR;
									end if;
									check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
                                                                        m := n - 1;
                                                                        n := n - 8;
								end loop;
								i := i + k;
								mem_data(ibase + istartadd) := mem_data_word;
								istartadd := istartadd + 1;
							end loop;
						when "01"=>
							exit;
						when "02"=>
							ibase := 0;
							if (ibyte /= 2) then
								ASSERT FALSE
								REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
								SEVERITY ERROR;
							end if;
							for i in 0 to (ibyte-1) loop
								READ(L=>buf, VALUE=>base,good=>booval);
								ibase := ibase * 256 + hex_str_to_int(base);
								if not (booval) then
									ASSERT FALSE
									REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
									SEVERITY ERROR;
								end if;
								check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
							end loop;
							ibase := ibase * 16;
						when OTHERS =>
							ASSERT FALSE
							REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
							SEVERITY ERROR;
					end case;
					READ(L=>buf, VALUE=>checksum,good=>booval);
					if not (booval) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
						SEVERITY ERROR;
					end if;
 
					check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
					check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
 
					if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
						ASSERT FALSE
						REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
						SEVERITY ERROR;
					end if;
				end loop;
			end if;
			mem_init := TRUE;
		end if;
 
		-- MEMORY FUNCTION --
		--if memenab = '1' then
			q_tmp <= mem_data(conv_integer(address_tmp));
		--else
		--    q_tmp <= (OTHERS => 'Z');
		--end if;
	end process;
 
end LPM_SYN;
 
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_FIFO is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHU : natural := 1;    -- MUST be greater than 0
             LPM_NUMWORDS : natural;    -- MUST be greater than 0
			 LPM_SHOWAHEAD : string := "OFF";
			 LPM_TYPE : string := "LPM_FIFO";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  CLOCK : in std_logic;
		  WRREQ : in std_logic;
		  RDREQ : in std_logic;
		  ACLR : in std_logic := '0';
		  SCLR : in std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  USEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
		  FULL : out std_logic;
		  EMPTY : out std_logic);
end LPM_FIFO; 
 
architecture LPM_SYN of lpm_fifo is
 
type lpm_memory is array (lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal tmp_q : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
signal read_id, write_id, count_id : integer := 0;
signal empty_flag : std_logic := '1';
signal full_flag : std_logic := '0';
constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
 
begin
 
	process (clock, aclr)
	variable mem_data : lpm_memory := (OTHERS => ZEROS);
 
	begin
        if (LPM_SHOWAHEAD /= "ON" and LPM_SHOWAHEAD /= "OFF") then
            ASSERT FALSE
            REPORT "Illegal LPM_SHOWAHEAD property value for LPM_FIFO!"
            SEVERITY ERROR;
        end if;
 
		if (aclr = '1') then
			tmp_q <= ZEROS;
			full_flag <= '0';
			empty_flag <= '1';
			read_id <= 0;
			write_id <= 0;
			count_id <= 0;
			if (lpm_showahead = "ON") then
				tmp_q <= mem_data(0);
			end if;
		elsif (clock'event and clock = '1') then
			if (sclr = '1') then
				tmp_q <= mem_data(read_id);
				full_flag <= '0';
				empty_flag <= '1';
				read_id <= 0;
				write_id <= 0;
				count_id <= 0;
				if (lpm_showahead = "ON") then
					tmp_q <= mem_data(0);
				end if;
			else
				----- IF BOTH READ AND WRITE -----
				if (wrreq = '1' and full_flag = '0') and
					(rdreq = '1' and empty_flag = '0') then
 
					mem_data(write_id) := data;
					if (write_id >= lpm_numwords-1) then
						write_id <= 0;
					else
						write_id <= write_id + 1;
					end if;
 
					tmp_q <= mem_data(read_id);
					if (read_id >= lpm_numwords-1) then
						read_id <= 0;
						if (lpm_showahead = "ON") then
							tmp_q <= mem_data(0);
						end if;
					else
						read_id <= read_id + 1;
						if (lpm_showahead = "ON") then
							tmp_q <= mem_data(read_id+1);
						end if;
					end if;
 
				----- IF WRITE (ONLY) -----
				elsif (wrreq = '1' and full_flag = '0') then
 
					mem_data(write_id) := data;
					if (lpm_showahead = "ON") then
						tmp_q <= mem_data(read_id);
					end if;
					count_id <= count_id + 1;
					empty_flag <= '0';
					if (count_id >= lpm_numwords-1) then
						full_flag <= '1';
						count_id <= lpm_numwords;
					end if;
					if (write_id >= lpm_numwords-1) then
						write_id <= 0;
					else
						write_id <= write_id + 1;
					end if;
 
				----- IF READ (ONLY) -----
				elsif (rdreq = '1' and empty_flag = '0') then
 
					tmp_q <= mem_data(read_id);
					count_id <= count_id - 1;
					full_flag <= '0';
					if (count_id <= 1) then
						empty_flag <= '1';
						count_id <= 0;
					end if;
					if (read_id >= lpm_numwords-1) then
						read_id <= 0;
						if (lpm_showahead = "ON") then
							tmp_q <= mem_data(0);
						end if;
					else
						read_id <= read_id + 1;
						if (lpm_showahead = "ON") then
							tmp_q <= mem_data(read_id+1);
						end if;
					end if;
				end if;  -- if WRITE and/or READ
			end if;  -- if sclr = '1'
		end if;  -- if aclr = '1'
	end process;
 
	q <= tmp_q;
	full <= full_flag;
	empty <= empty_flag;
	usedw <= conv_std_logic_vector(count_id, lpm_widthu);
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_FIFO_DC_DFFPIPE is
    generic (LPM_DELAY : natural);
    port (D : in integer;
          Q : out integer := 0;
          CLOCK : in std_logic;
          ACLR : in std_logic := '0');
end LPM_FIFO_DC_DFFPIPE;
 
architecture LPM_SYN of LPM_FIFO_DC_DFFPIPE is
type delaypipe is array (LPM_DELAY downto 0) of integer;
 
begin
 
    process (clock, aclr, d)
    variable intpipe : delaypipe := (OTHERS => 0);
    variable delay : integer := LPM_DELAY-1;
    variable init : integer := 0;
    begin
        if (LPM_DELAY = 0) then
            if (aclr = '1' or init = 0) then
                q <= 0;
                init := 1;
            else
                q <= d;
            end if;
        else
            if (aclr = '1' or init = 0) then
                for i in LPM_DELAY downto 0 loop
                    intpipe(i) := 0;
                end loop;
                init := 1;
                q <= 0;
            end if;
            if (clock'event and clock = '1' and NOW > 0 ns) then
                if (delay > 0) then
                    for i in delay downto 1 loop
                        intpipe(i) := intpipe(i-1);
                    end loop;
                end if;
                intpipe(0) := d;
                q <= intpipe(delay);
            end if;
        end if;
    end process;
 
end LPM_SYN;
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_FIFO_DC_FEFIFO is
    generic (LPM_WIDTHAD : natural;
             LPM_NUMWORDS : natural;
	     UNDERFLOW_CHECKING : string := "ON"; 
             LPM_MODE : string );
    port (USEDW_IN : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
          WREQ : in std_logic := 'Z';
          RREQ : in std_logic := 'Z';
          EMPTY : out std_logic;
          FULL : out std_logic;
          CLOCK : in std_logic;
          ACLR : in std_logic := '0');
end LPM_FIFO_DC_FEFIFO;
 
architecture LPM_SYN of LPM_FIFO_DC_FEFIFO is
signal usedw : std_logic_vector(LPM_WIDTHAD-1 downto 0);
signal sm_empty : std_logic_vector(1 downto 0) := "00";
signal lrreq : std_logic := '0'; -- DFF;
signal init : natural := 0;
signal i_empty : std_logic := '1';
signal i_full : std_logic := '0';
signal valid_rreq : std_logic;
 
begin
 
    valid_rreq <= rreq when underflow_checking = "OFF" else
                  rreq and not i_empty;
 
    process (clock, aclr)
    begin
        if (aclr = '1') then
            lrreq <= '0';
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
            lrreq <= valid_rreq;
        end if;
    end process;
 
    process (clock, aclr)
    variable almost_full : integer := 0;
    begin
        if (aclr = '1') then
            i_full <= '0';
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
            if (lpm_numwords >= 3) then
                almost_full := lpm_numwords-3;
            end if;
            if (unsigned(usedw) >= almost_full) then
                i_full <= '1';
            else
                i_full <= '0';
            end if;
        end if;
    end process;
 
    process (clock, aclr)
    variable local_sm_empty : std_logic_vector(1 downto 0) := "00";
    variable usedw_is_1 : boolean;
    begin
        local_sm_empty := sm_empty;
        if (aclr = '1') then
            local_sm_empty := "00";
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
            if (lpm_mode = "READ") then
                case sm_empty is
                    when "00" =>                    -- state_empty
                        if (usedw /= 0) then
                            local_sm_empty := "01";
                        end if;
                    when "01" =>                    -- state_non_empty
                        usedw_is_1 := (usedw = 1 and lrreq = '0') or (usedw = 2 and lrreq = '1');
                        if (rreq = '1' and usedw_is_1) then
                            local_sm_empty := "10";
                        end if;
                    when "10" =>                    -- state_emptywait
                        if (usedw > 1) then
                            local_sm_empty := "01";
                        else
                            local_sm_empty := "00";
                        end if;
                    when others =>
                        -- INTERNAL ERROR
                end case;
            elsif (lpm_mode = "WRITE") then
                case sm_empty is
                    when "00" =>                    -- state_empty
                        if (wreq = '1') then
                            local_sm_empty := "01";
                        end if;
                    when "01" =>                    -- state_one
                        if (wreq = '0') then
                            local_sm_empty := "11";
                        end if;
                    when "11" =>                    -- state_non_empty
                        if (wreq = '1') then
                            local_sm_empty := "01";
                        elsif (usedw = 0) then
                            local_sm_empty := "00";
                        end if;
                    when others =>
                        -- INTERNAL ERROR
                end case;
            end if;
        end if;
        sm_empty <= local_sm_empty;
        i_empty <= not local_sm_empty(0);
    end process;
 
    usedw <= usedw_in;
    empty <= i_empty;
    full <= i_full;
 
end LPM_SYN;
 
---------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.LPM_COMPONENTS.all;
use std.textio.all;
 
entity LPM_FIFO_DC is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
             LPM_WIDTHU : natural := 1;    -- MUST be greater than 0
             LPM_NUMWORDS : natural;    -- MUST be greater than 0
	     LPM_SHOWAHEAD : string := "OFF";
	     LPM_TYPE : string := "LPM_FIFO_DC";
	     UNDERFLOW_CHECKING : string := "ON"; 
	     OVERFLOW_CHECKING : string := "ON"; 
	     LPM_HINT : string := "USE_EAB=ON");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  WRCLOCK : in std_logic;
		  RDCLOCK : in std_logic;
		  WRREQ : in std_logic;
		  RDREQ : in std_logic;
		  ACLR : in std_logic := '0';
		  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  WRUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
		  RDUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
		  WRFULL : out std_logic;
		  RDFULL : out std_logic;
		  WREMPTY : out std_logic;
		  RDEMPTY : out std_logic);
end LPM_FIFO_DC; 
 
architecture LPM_SYN of lpm_fifo_dc is
 
type lpm_memory is array (2**lpm_widthu-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
 
signal i_q : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
signal i_rdptr, i_wrptr, i_rdptrrg, i_wrdelaycycle : integer := 0;
signal i_ws_nbrp, i_rs_nbwp, i_ws_dbrp, i_rs_dbwp : integer := 0;
signal i_wr_udwn, i_rd_udwn, i_wr_dbuw, i_rd_dbuw : integer := 0;
signal i_rdempty, i_wrempty : std_logic := '1';
signal i_rdfull, i_wrfull : std_logic := '0';
signal i_rdusedw, i_wrusedw : integer := 0;
signal i_rden, i_wren, i_rdenclock : std_logic := '0';
signal slv_wr_dbuw, slv_rd_dbuw : std_logic_vector(lpm_widthu-1 downto 0);
 
signal i_data_tmp, i_data_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
signal i_q_tmp, i_q_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
signal i_rdptr_tmp, i_wrptr_tmp, i_wrptr_reg : integer := 0;
signal i_wren_tmp, i_wren_reg : std_logic := '0';
 
constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
constant WRSYNC_DELAYPIPE : integer := 3;   -- from the rdclk to the wrclk subsystem
constant RDSYNC_DELAYPIPE : integer := 3;   -- from the wrclk to the rdclk subsystem
constant GRAY_DELAYPIPE : integer := 1;
constant DELAY_WRUSEDW : integer := 1;      -- output delay to the wrusedw outputs
constant DELAY_RDUSEDW : integer := 1;      -- output delay to the rdusedw outputs
constant WRUSEDW_DELAYPIPE : integer := 1;  -- delayed usedw to compute empty/full
constant RDUSEDW_DELAYPIPE : integer := 1;  -- delayed usedw to compute empty/full
 
component LPM_FIFO_DC_FEFIFO
    generic (LPM_WIDTHAD : natural;
             LPM_NUMWORDS : natural;
  	     UNDERFLOW_CHECKING : STRING := "ON"; 
             LPM_MODE : string);
    port (USEDW_IN : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
          WREQ : in std_logic := 'Z';
          RREQ : in std_logic := 'Z';
          EMPTY : out std_logic;
          FULL : out std_logic;
          CLOCK : in std_logic;
          ACLR : in std_logic := '0');
end component;
 
component LPM_FIFO_DC_DFFPIPE
    generic (LPM_DELAY : natural);
    port (D : in integer;
          Q : out integer := 0;
          CLOCK : in std_logic;
          ACLR : in std_logic := '0');
end component;
 
begin
 
    ----------
    -- FIFOram
    ----------
 
    i_rden <= rdreq when underflow_checking = "OFF" else
              rdreq and not i_rdempty;
    i_wren <= wrreq when overflow_checking = "OFF" else
              wrreq and not i_wrfull;
 
    FIFOram_sync: process (i_data_reg, i_q_tmp, i_q_reg, aclr,
                           i_rdptr, i_wren_reg, i_wrptr_reg)
    begin
        if (aclr = '1') then
            i_wrptr_tmp <= 0;
            i_rdptr_tmp <= 0;
            i_wren_tmp <= '0';
            i_data_tmp <= (OTHERS => '0');
            if (LPM_SHOWAHEAD = "ON") then
                i_q <= i_q_tmp;
            else
                i_q <= (OTHERS => '0');
            end if;
        else
            i_wrptr_tmp <= i_wrptr_reg;
            i_rdptr_tmp <= i_rdptr;
            i_wren_tmp <= i_wren_reg;
            i_data_tmp <= i_data_reg;
            if (LPM_SHOWAHEAD = "ON") then
                i_q <= i_q_tmp;
            else
                i_q <= i_q_reg;
            end if;
        end if;
    end process;
 
    FIFOram_wrclock: process (wrclock, aclr)
    begin
        if (aclr = '1') then
            i_data_reg <= (OTHERS => '0');
            i_wrptr_reg <= 0;
            i_wren_reg <= '0';
        elsif (wrclock'event and wrclock = '1' and NOW > 0 ns) then
            i_data_reg <= data;
            i_wrptr_reg <= i_wrptr;
            i_wren_reg <= i_wren;
        end if;
    end process;
 
    FIFOram_rdclock: process (rdclock, aclr)
    begin
        if (aclr = '1') then
            i_q_reg <= (OTHERS => '0');
        elsif (rdclock'event and rdclock = '1' and i_rden = '1' and NOW > 0 ns) then
            i_q_reg <= i_q_tmp;
        end if;
    end process;
 
    FIFOram_memory: process (i_data_tmp, i_wren_tmp, i_wrptr_tmp, i_rdptr_tmp, wrclock)
    variable mem_data : lpm_memory := (OTHERS => ZEROS);
    variable init : integer := 0;
    begin
        if (init = 0) then
            for i in lpm_numwords-1 downto 0 loop
                mem_data(i) := ZEROS;
            end loop;
            init := 1;
        end if;
        if wrclock'event and i_wren_tmp = '1' and
            ((wrclock = '0' and lpm_hint = "USE_EAB=ON") or
             (wrclock = '1' and lpm_hint /= "USE_EAB=ON")) then
                mem_data(i_wrptr_tmp) := i_data_tmp;
        end if;
        i_q_tmp <= mem_data(i_rdptr_tmp);
    end process;
 
 
    -----------
    -- Counters
    -----------
 
    rdptr: process (rdclock, aclr)
    begin
        if (aclr = '1') then
            i_rdptr <= 0;
        elsif (rdclock'event and rdclock = '1' and i_rden = '1' and NOW > 0 ns) then
            if (i_rdptr < 2**lpm_widthu-1) then
                i_rdptr <= i_rdptr + 1;
            else
                i_rdptr <= 0;
            end if;
        end if;
    end process;
 
    wrptr: process (wrclock, aclr)
    begin
        if (aclr = '1') then
            i_wrptr <= 0;
        elsif (wrclock'event and wrclock = '1' and i_wren = '1' and NOW > 0 ns) then
            if (i_wrptr < 2**lpm_widthu-1) then
                i_wrptr <= i_wrptr + 1;
            else
                i_wrptr <= 0;
            end if;
        end if;
    end process;
 
 
    ---------------------
    -- Delays & DFF Pipes
    ---------------------
 
    process (rdclock)
    begin
        if (rdclock = '0') then
            i_rdenclock <= '0';
        elsif (rdclock = '1' and i_rden = '1') then
            i_rdenclock <= '1';
        end if;
    end process;
 
    RDPTR_D:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => 0)
                    port map (D => i_rdptr, Q => i_rdptrrg,
                              CLOCK => i_rdenclock, ACLR => aclr);
 
    WRPTR_D:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => 1)
                    port map (D => i_wrptr, Q => i_wrdelaycycle,
                              CLOCK => wrclock, ACLR => aclr);
 
    WS_NBRP:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => WRSYNC_DELAYPIPE)
                    port map (D => i_rdptrrg, Q => i_ws_nbrp,
                              CLOCK => wrclock, ACLR => aclr);
 
    RS_NBWP:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => RDSYNC_DELAYPIPE)
                    port map (D => i_wrdelaycycle, Q => i_rs_nbwp,
                              CLOCK => rdclock, ACLR => aclr);
 
    WS_DBRP:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => GRAY_DELAYPIPE)
                    port map (D => i_ws_nbrp, Q => i_ws_dbrp,
                              CLOCK => wrclock, ACLR => aclr);
 
    RS_DBWP:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => GRAY_DELAYPIPE)
                    port map (D => i_rs_nbwp, Q => i_rs_dbwp,
                              CLOCK => rdclock, ACLR => aclr);
 
    process (i_wrptr, i_ws_dbrp)
    begin
        i_wr_udwn <= i_wrptr - i_ws_dbrp;
    end process;
 
    process (i_rdptr, i_rs_dbwp)
    begin
        i_rd_udwn <= i_rs_dbwp - i_rdptr;
    end process;
 
    WR_USEDW:   LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => DELAY_WRUSEDW)
                    port map (D => i_wr_udwn, Q => i_wrusedw,
                              CLOCK => wrclock, ACLR => aclr);
 
    RD_USEDW:   LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => DELAY_RDUSEDW)
                    port map (D => i_rd_udwn, Q => i_rdusedw,
                              CLOCK => rdclock, ACLR => aclr);
 
    WR_DBUW:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => WRUSEDW_DELAYPIPE)
                    port map (D => i_wr_udwn, Q => i_wr_dbuw,
                              CLOCK => wrclock, ACLR => aclr);
 
    RD_DBUW:    LPM_FIFO_DC_DFFPIPE
                    generic map (LPM_DELAY => RDUSEDW_DELAYPIPE)
                    port map (D => i_rd_udwn, Q => i_rd_dbuw,
                              CLOCK => rdclock, ACLR => aclr);
 
 
    -------------
    -- Full/Empty
    -------------
 
    slv_wr_dbuw <= conv_std_logic_vector(i_wr_dbuw, LPM_WIDTHU);
    slv_rd_dbuw <= conv_std_logic_vector(i_rd_dbuw, LPM_WIDTHU);
 
    WR_FE:  LPM_FIFO_DC_FEFIFO
                generic map (LPM_WIDTHAD => LPM_WIDTHU,
                             LPM_NUMWORDS => LPM_NUMWORDS,
                             LPM_MODE => "WRITE",
                             UNDERFLOW_CHECKING => UNDERFLOW_CHECKING)
                port map (USEDW_IN => slv_wr_dbuw, WREQ => wrreq,
                          CLOCK => wrclock, ACLR => aclr,
                          EMPTY => i_wrempty, FULL => i_wrfull);
 
    RD_FE:  LPM_FIFO_DC_FEFIFO
                generic map (LPM_WIDTHAD => LPM_WIDTHU,
                             LPM_NUMWORDS => LPM_NUMWORDS,
                             LPM_MODE => "READ",
                             UNDERFLOW_CHECKING => UNDERFLOW_CHECKING)
                port map (USEDW_IN => slv_rd_dbuw, RREQ => rdreq,
                          CLOCK => rdclock, ACLR => aclr,
                          EMPTY => i_rdempty, FULL => i_rdfull);
 
    ----------
    -- Outputs
    ----------
 
    q <= i_q;
    wrfull <= i_wrfull;
    wrempty <= i_wrempty;
    rdfull <= i_rdfull;
    rdempty <= i_rdempty;
    wrusedw <= conv_std_logic_vector(i_wrusedw, LPM_WIDTHU);
    rdusedw <= conv_std_logic_vector(i_rdusedw, LPM_WIDTHU);
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_INPAD is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE : string := "LPM_INPAD";
			 LPM_HINT : string := "UNUSED");
	port (PAD : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_INPAD;
 
architecture LPM_SYN of LPM_INPAD is
begin
 
	RESULT <=  PAD;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_OUTPAD is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE : string := "L_OUTPAD";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  PAD : out std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_OUTPAD;
 
architecture LPM_SYN of LPM_OUTPAD is
begin
 
	PAD <= DATA;
 
end LPM_SYN;
 
 
--------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use work.LPM_COMPONENTS.all;
 
entity LPM_BIPAD is
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
			 LPM_TYPE : string := "LPM_BIPAD";
			 LPM_HINT : string := "UNUSED");
	port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
		  ENABLE : in std_logic;
		  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
		  PAD : inout std_logic_vector(LPM_WIDTH-1 downto 0));
end LPM_BIPAD;
 
architecture LPM_SYN of LPM_BIPAD is
begin
 
	process(DATA, PAD, ENABLE)
	begin
		if ENABLE = '1' then
			PAD <= DATA;
			RESULT <= (OTHERS => 'Z');
		else
			RESULT <= PAD;
			PAD <= (OTHERS => 'Z');
		end if;
	end process;
 
end LPM_SYN;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.