OpenCores
URL https://opencores.org/ocsvn/xmatchpro/xmatchpro/trunk
-------------------------------------------------------------------------- -- 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;

Subversion Repositories xmatchpro

[/] [xmatchpro/] [trunk/] [xmw4-comdec/] [xmatch_sim7/] [lib/] [lpm/] [220model.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line

powered by: WebSVN 2.1.0

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