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