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

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
1 9 eejlny
--------------------------------------------------------------------------
2
--   This VHDL file was developed by Altera Corporation.  It may be
3
-- freely copied and/or distributed at no cost.  Any persons using this
4
-- file for any purpose do so at their own risk, and are responsible for
5
-- the results of such use.  Altera Corporation does not guarantee that
6
-- this file is complete, correct, or fit for any particular purpose.
7
-- NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.  This notice must
8
-- accompany any copy of this file.
9
--
10
--------------------------------------------------------------------------
11
-- LPM Synthesizable Models (Support string type generic)
12
-- These models are based on LPM version 220 (EIA-IS103 October 1998).
13
-------------------------------------------------------------------------
14
-- Version Quartus v1.1 (lpm 220)      Date 02/26/02
15
--
16
-- 02/26/02: FIX spr 98850, lpm_counter 32 bit problem.
17
-- 02/01/01: Fix SPR79628 and 80251; integer overfow in Leapfrog and 
18
--           Speedwave for lpm_fifo_dc.
19
-- 01/23/01: Adding use_eab=on support for lpm_ram_io, lpm_ram_dp and
20
--           lpm_ram_dq.
21
-- 01/22/01: Fix SPR76524. Fix LPM_CLSHIFT implementation of arith
22
--           shift right underflow to match megafunction impl.
23
--------------------------------------------------------------------------
24
-- Version Quartus v1.0 (lpm 220)      Date 12/8/00
25
--
26
-- 12/8/00: Fix lpm_fifo_dc compilation problem for VSS.
27
--------------------------------------------------------------------------
28
-- Version 2.2 (lpm 220)      Date 12/05/00
29
--
30
-- 1. Fixed LPM_COUNTER code to remove requirement to use '-explicit'
31
--    option in modelsim.
32
-- 2. Fixed LPM_ROM, LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO hex reading to
33
--    support width>32bits.
34
--------------------------------------------------------------------------
35
-- Version 2.1 (lpm 220)      Date 09/21/00
36
--
37
-- 1. Fixed LPM_SHIFTREG to perform left shift or right shift according
38
--    to LPM_DIRECTION value.
39
-- 2. Changed Q port of LPM_SHIFTREG to be initialized with 0's.
40
-- 3. Added validity check for LPM_DIRECTION value of LPM_SHIFTREG.
41
-- 4. Changed SHIFTOUT port of LPM_SHIFTREG to output LSB of Q when
42
--    LPM_DIRECTION is "RIGHT".
43
-- 5. Fixed LPM_CLSHIFT to correctly sign extend output.
44
-- 6. Corrected OVERFLOW and UNDERFLOW ports of LPM_CLSHIFT.
45
-- 7. Added parameter value validity check.
46
-- 8. Changed all positive or integer type parameters to natural type.
47
-- 9. Changed LPM_ROM to check for null init file name.
48
--10. Changed the behaviour of LPM_FIFO_DC to match that of Quartus.
49
--11. Changed Data port of LPM_LATCH to be initialized with 0's.
50
--12. Fixed LPM_CLSHIFT and LPM_MULT array sizes mismatch error.
51
--13. Fixed LPM_FF initial state of output.
52
--14. Added LPM_REMAINDERPOSITIVE parameter to LPM_DIVIDE.  This is a
53
--    non-LPM 220 standard parameter.  It defaults to TRUE for LPM 220
54
--    behaviour.
55
--15. Changed default value of CIN port of LPM_ADD_SUB when subtract.
56
--16. Changed output pipelines of LPM_ADD_SUB to be initialized with 0's.
57
--17. Corrected the interpretation of CIN port of LPM_COUNTER.
58
--18. Fixed COUT port of LPM_COUNTER to go high when count is all 1's.
59
--19. Changed Q port of LPM_ROM to be initialized with 0's.
60
--------------------------------------------------------------------------
61
-- Version 2.0 (lpm 220)      Date 01/11/00
62
--
63
-- 1. Fixed LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO and LPM_ROM to correctly
64
--    read in values from LPM_FILE (*.hex) when the DATA width is greater
65
--    than 16 bits.
66
-- 2. Explicit sign conversions are added to standard logic vector
67
--    comparisons in LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO, LPM_ROM, and
68
--    LPM_COMPARE.
69
-- 3. LPM_FIFO_DC is rewritten to have correct outputs.
70
-- 4. LPM_FIFO outputs zeros when nothing has been read from it, and
71
--    outputs LPM_NUMWORDS mod exp(2, LPM_WIDTHU) when it is full.
72
-- 5. Fixed LPM_DIVIDE to divide correctly.
73
--------------------------------------------------------------------------
74
-- Version 1.9 (lpm 220)      Date 11/30/99
75
--
76
-- 1. Fixed UNUSED file not found problem and initialization problem
77
--    with LPM_RAM_DP, LPM_RAM_DQ, and LPM_RAM_IO.
78
-- 2. Fixed LPM_MULT when SUM port is not used.
79
-- 3. Fixed LPM_FIFO_DC to enable read when rdclock and wrclock rise
80
--    at the same time.
81
-- 4. Fixed LPM_COUNTER comparison problem when signed library is loaded
82
--    and counter is incrementing.
83
-- 5. Got rid of "Illegal Character" error message at time = 0 ns when
84
--    simulating LPM_COUNTER.
85
--------------------------------------------------------------------------
86
-- Version 1.8 (lpm 220)      Date 10/25/99
87
--
88
-- 1. Some LPM_PVALUE implementations were missing, and now implemented.
89
-- 2. Fixed LPM_COUNTER to count correctly without conversion overflow,
90
--    that is, when LPM_MODULUS = 2 ** LPM_WIDTH.
91
-- 3. Fixed LPM_RAM_DP sync process sensitivity list to detect wraddress
92
--    changes.
93
--------------------------------------------------------------------------
94
-- Version 1.7 (lpm 220)      Date 07/13/99
95
--
96
-- Changed LPM_RAM_IO so that it can be used to simulate both MP2 and
97
--   Quartus behaviour and LPM220-compliant behaviour.
98
--------------------------------------------------------------------------
99
-- Version 1.6 (lpm 220)      Date 06/15/99
100
--
101
-- 1. Fixed LPM_ADD_SUB sign extension problem and subtraction bug.
102
-- 2. Fixed LPM_COUNTER to use LPM_MODULUS value.
103
-- 3. Added CIN and COUT port, and discarded EQ port in LPM_COUNTER to
104
--    comply with the specfication.
105
-- 4. Included LPM_RAM_DP, LPM_RAM_DQ, LPM_RAM_IO, LPM_ROM, LPM_FIFO, and
106
--    LPM_FIFO_DC; they are all initialized to 0's.
107
--------------------------------------------------------------------------
108
-- Version 1.5 (lpm 220)      Date 05/10/99
109
--
110
-- Changed LPM_MODULUS from string type to integer.
111
--------------------------------------------------------------------------
112
-- Version 1.4 (lpm 220)      Date 02/05/99
113
-- 
114
-- 1. Added LPM_DIVIDE module.
115
-- 2. Added CLKEN port to LPM_MUX, LPM_DECODE, LPM_ADD_SUB, LPM_MULT
116
--    and LPM_COMPARE
117
-- 3. Replaced the constants holding string with the actual string.
118
--------------------------------------------------------------------------
119
-- Version 1.3                Date 07/30/96
120
--
121
-- Modification History
122
--
123
-- 1. Changed the DEFAULT value to "UNUSED" for LPM_SVALUE, LPM_AVALUE,
124
-- LPM_MODULUS, and LPM_NUMWORDS, LPM_HINT,LPM_STRENGTH, LPM_DIRECTION,
125
-- and LPM_PVALUE
126
--
127
-- 2. Added the two dimentional port components (AND, OR, XOR, and MUX).
128
--------------------------------------------------------------------------
129
-- Excluded Functions:
130
--
131
--   LPM_FSM and LPM_TTABLE
132
--
133
--------------------------------------------------------------------------
134
-- Assumptions:
135
--
136
-- 1. All ports and signal types are std_logic or std_logic_vector
137
--    from IEEE 1164 package.
138
-- 2. Synopsys std_logic_arith, std_logic_unsigned, and std_logic_signed
139
--    package are assumed to be accessible from IEEE library.
140
-- 3. lpm_component_package must be accessible from library work.
141
-- 4. The default value of LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, LPM_HINT,
142
--    LPM_NUMWORDS, LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE is
143
--    string "UNUSED".
144
--------------------------------------------------------------------------
145
 
146
library IEEE;
147
use IEEE.std_logic_1164.all;
148
use IEEE.std_logic_arith.all;
149
use IEEE.std_logic_unsigned.all;
150
use work.LPM_COMPONENTS.all;
151
 
152
entity LPM_CONSTANT is
153
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
154
                         LPM_CVALUE : natural;
155
                         LPM_STRENGTH : string := "UNUSED";
156
                         LPM_TYPE : string := "LPM_CONSTANT";
157
                         LPM_HINT : string := "UNUSED");
158
        port (RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
159
end LPM_CONSTANT;
160
 
161
architecture LPM_SYN of LPM_CONSTANT is
162
begin
163
 
164
        RESULT <= conv_std_logic_vector(LPM_CVALUE, LPM_WIDTH);
165
 
166
end LPM_SYN;
167
 
168
 
169
--------------------------------------------------------------------------
170
 
171
library IEEE;
172
use IEEE.std_logic_1164.all;
173
use IEEE.std_logic_unsigned.all;
174
use work.LPM_COMPONENTS.all;
175
 
176
entity LPM_INV is
177
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
178
                         LPM_TYPE : string := "LPM_INV";
179
                         LPM_HINT : string := "UNUSED");
180
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
181
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
182
end LPM_INV;
183
 
184
architecture LPM_SYN of LPM_INV is
185
begin
186
 
187
        RESULT <= not DATA;
188
 
189
end LPM_SYN;
190
 
191
 
192
--------------------------------------------------------------------------
193
 
194
library IEEE;
195
use IEEE.std_logic_1164.all;
196
use work.LPM_COMPONENTS.all;
197
 
198
entity LPM_AND is
199
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
200
             LPM_SIZE : natural;    -- MUST be greater than 0
201
                         LPM_TYPE : string := "LPM_AND";
202
                         LPM_HINT : string := "UNUSED");
203
        port (DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0);
204
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
205
end LPM_AND;
206
 
207
architecture LPM_SYN of LPM_AND is
208
 
209
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
210
 
211
begin
212
 
213
L1: for i in 0 to LPM_WIDTH-1 generate
214
                RESULT_INT(0,i) <= DATA(0,i);
215
L2:     for j in 0 to LPM_SIZE-2 generate
216
                        RESULT_INT(j+1,i) <=  RESULT_INT(j,i) and DATA(j+1,i);
217
L3:         if j = LPM_SIZE-2 generate
218
                                RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
219
                        end generate L3;
220
                end generate L2;
221
        end generate L1;
222
 
223
end LPM_SYN;
224
 
225
 
226
--------------------------------------------------------------------------
227
 
228
library IEEE;
229
use IEEE.std_logic_1164.all;
230
use work.LPM_COMPONENTS.all;
231
 
232
entity LPM_OR is
233
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
234
             LPM_SIZE : natural;    -- MUST be greater than 0 
235
                         LPM_TYPE : string := "LPM_OR";
236
                         LPM_HINT : string := "UNUSED");
237
        port (DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0);
238
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
239
end LPM_OR;
240
 
241
architecture LPM_SYN of LPM_OR is
242
 
243
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
244
 
245
begin
246
 
247
L1: for i in 0 to LPM_WIDTH-1 generate
248
                RESULT_INT(0,i) <= DATA(0,i);
249
L2:     for j in 0 to LPM_SIZE-2 generate
250
                        RESULT_INT(j+1,i) <=  RESULT_INT(j,i) or DATA(j+1,i);
251
L3:         if j = LPM_SIZE-2 generate
252
                                RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
253
                        end generate L3;
254
                end generate L2;
255
        end generate L1;
256
 
257
end LPM_SYN;
258
 
259
 
260
--------------------------------------------------------------------------
261
 
262
library IEEE;
263
use IEEE.std_logic_1164.all;
264
use work.LPM_COMPONENTS.all;
265
 
266
entity LPM_XOR is
267
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
268
             LPM_SIZE : natural;    -- MUST be greater than 0 
269
                         LPM_TYPE : string := "LPM_XOR";
270
                         LPM_HINT : string := "UNUSED");
271
        port (DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0);
272
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
273
end LPM_XOR;
274
 
275
architecture LPM_SYN of LPM_XOR is
276
 
277
signal RESULT_INT : std_logic_2d(LPM_SIZE-1 downto 0,LPM_WIDTH-1 downto 0);
278
 
279
begin
280
 
281
L1: for i in 0 to LPM_WIDTH-1 generate
282
                RESULT_INT(0,i) <= DATA(0,i);
283
L2:     for j in 0 to LPM_SIZE-2 generate
284
                        RESULT_INT(j+1,i) <=  RESULT_INT(j,i) xor DATA(j+1,i);
285
L3:         if j = LPM_SIZE-2 generate
286
                                RESULT(i) <= RESULT_INT(LPM_SIZE-1,i);
287
                        end generate L3;
288
                end generate L2;
289
        end generate L1;
290
 
291
end LPM_SYN;
292
 
293
 
294
--------------------------------------------------------------------------
295
 
296
library IEEE;
297
use IEEE.std_logic_1164.all;
298
use IEEE.std_logic_unsigned.all;
299
use work.LPM_COMPONENTS.all;
300
 
301
entity LPM_BUSTRI is
302
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
303
                         LPM_TYPE : string := "LPM_BUSTRI";
304
                         LPM_HINT : string := "UNUSED");
305
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
306
                  ENABLEDT : in std_logic := '0';
307
                  ENABLETR : in std_logic := '0';
308
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
309
                  TRIDATA : inout std_logic_vector(LPM_WIDTH-1 downto 0));
310
end LPM_BUSTRI;
311
 
312
architecture LPM_SYN of LPM_BUSTRI is
313
begin
314
 
315
        process(DATA, TRIDATA, ENABLETR, ENABLEDT)
316
        begin
317
                if ENABLEDT = '0' and ENABLETR = '1' then
318
                        RESULT <= TRIDATA;
319
                        TRIDATA <= (OTHERS => 'Z');
320
                elsif ENABLEDT = '1' and ENABLETR = '0' then
321
                        RESULT <= (OTHERS => 'Z');
322
                        TRIDATA <= DATA;
323
                elsif ENABLEDT = '1' and ENABLETR = '1' then
324
                        RESULT <= DATA;
325
                        TRIDATA <= DATA;
326
                else
327
                        RESULT <= (OTHERS => 'Z');
328
                        TRIDATA <= (OTHERS => 'Z');
329
                end if;
330
        end process;
331
 
332
end LPM_SYN;
333
 
334
 
335
--------------------------------------------------------------------------
336
 
337
library IEEE;
338
use IEEE.std_logic_1164.all;
339
use IEEE.std_logic_arith.all;
340
use IEEE.std_logic_unsigned.all;
341
use work.LPM_COMPONENTS.all;
342
 
343
entity LPM_MUX is
344
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0 
345
             LPM_SIZE : natural;    -- MUST be greater than 0 
346
             LPM_WIDTHS : natural;    -- MUST be greater than 0 
347
             LPM_PIPELINE : natural := 0;
348
                         LPM_TYPE : string := "LPM_MUX";
349
                         LPM_HINT : string := "UNUSED");
350
        port (DATA : in std_logic_2D(LPM_SIZE-1 downto 0, LPM_WIDTH-1 downto 0);
351
                  ACLR : in std_logic := '0';
352
                  CLOCK : in std_logic := '0';
353
                  CLKEN : in std_logic := '1';
354
                  SEL : in std_logic_vector(LPM_WIDTHS-1 downto 0);
355
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
356
end LPM_MUX;
357
 
358
architecture LPM_SYN of LPM_MUX is
359
 
360
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH-1 downto 0);
361
 
362
begin
363
 
364
        process (ACLR, CLOCK, SEL, DATA)
365
        variable resulttmp : t_resulttmp;
366
        variable ISEL : integer;
367
        begin
368
                if LPM_PIPELINE >= 0 then
369
                        ISEL := conv_integer(SEL);
370
 
371
                        for i in 0 to LPM_WIDTH-1 loop
372
                                resulttmp(LPM_PIPELINE)(i) := DATA(ISEL,i);
373
                        end loop;
374
 
375
                        if LPM_PIPELINE > 0 then
376
                                if ACLR = '1' then
377
                                        for i in 0 to LPM_PIPELINE loop
378
                                                resulttmp(i) := (OTHERS => '0');
379
                                        end loop;
380
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1'  then
381
                                        resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
382
                                end if;
383
                        end if;
384
 
385
                        RESULT <= resulttmp(0);
386
                end if;
387
        end process;
388
 
389
end LPM_SYN;
390
 
391
 
392
--------------------------------------------------------------------------
393
 
394
library IEEE;
395
use IEEE.std_logic_1164.all;
396
use IEEE.std_logic_unsigned.all;
397
use work.LPM_COMPONENTS.all;
398
 
399
 
400
entity LPM_DECODE is
401
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
402
             LPM_DECODES : natural;    -- MUST be greater than 0
403
             LPM_PIPELINE : natural := 0;
404
                         LPM_TYPE : string := "LPM_DECODE";
405
                         LPM_HINT : string := "UNUSED");
406
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
407
                  CLOCK : in std_logic := '0';
408
                  CLKEN : in std_logic := '1';
409
                  ACLR : in std_logic := '0';
410
                  ENABLE : in std_logic := '1';
411
                  EQ : out std_logic_vector(LPM_DECODES-1 downto 0));
412
end LPM_DECODE;
413
 
414
architecture LPM_SYN of LPM_DECODE is
415
 
416
type t_eqtmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_DECODES-1 downto 0);
417
 
418
begin
419
 
420
        process(ACLR, CLOCK, DATA, ENABLE)
421
        variable eqtmp : t_eqtmp;
422
        begin
423
 
424
                if LPM_PIPELINE >= 0 then
425
                        for i in 0 to LPM_DECODES-1 loop
426
                                if conv_integer(DATA) = i then
427
                                        if ENABLE = '1' then
428
                                                eqtmp(LPM_PIPELINE)(i) := '1';
429
                                        else
430
                                                eqtmp(LPM_PIPELINE)(i) := '0';
431
                                        end if;
432
                                else
433
                                        eqtmp(LPM_PIPELINE)(i) := '0';
434
                                end if;
435
                        end loop;
436
 
437
                        if LPM_PIPELINE > 0 then
438
                                if ACLR = '1' then
439
                                        for i in 0 to LPM_PIPELINE loop
440
                                                eqtmp(i) := (OTHERS => '0');
441
                                        end loop;
442
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
443
                                        eqtmp(0 to LPM_PIPELINE - 1) := eqtmp(1 to LPM_PIPELINE);
444
                                end if;
445
                        end if;
446
                end if;
447
 
448
                EQ <= eqtmp(0);
449
        end process;
450
 
451
end LPM_SYN;
452
 
453
 
454
--------------------------------------------------------------------------
455
 
456
library IEEE;
457
use IEEE.std_logic_1164.all;
458
use IEEE.std_logic_arith.all;
459
use IEEE.std_logic_unsigned.all;
460
use work.LPM_COMPONENTS.all;
461
 
462
entity LPM_CLSHIFT is
463
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
464
             LPM_WIDTHDIST : natural;    -- MUST be greater than 0
465
                         LPM_SHIFTTYPE : string := "LOGICAL";
466
                         LPM_TYPE : string := "LPM_CLSHIFT";
467
                         LPM_HINT : string := "UNUSED");
468
        port (DATA : in STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0);
469
                  DISTANCE : in STD_LOGIC_VECTOR(LPM_WIDTHDIST-1 downto 0);
470
                  DIRECTION : in STD_LOGIC := '0';
471
                  RESULT : out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0);
472
                  UNDERFLOW : out STD_LOGIC;
473
                  OVERFLOW : out STD_LOGIC);
474
end LPM_CLSHIFT;
475
 
476
architecture LPM_SYN of LPM_CLSHIFT is
477
 
478
signal IRESULT : std_logic_vector(LPM_WIDTH-1 downto 0);
479
 
480
begin
481
 
482
        process(DATA, DISTANCE, DIRECTION)
483
    variable tmpdata : std_logic_vector(LPM_WIDTH-1 downto 0);
484
    variable tmpdist : integer;
485
        begin
486
        if LPM_SHIFTTYPE = "ARITHMETIC" or LPM_SHIFTTYPE = "LOGICAL" then
487
            tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
488
            tmpdist := conv_integer(unsigned(DISTANCE));
489
            for i in LPM_WIDTH-1 downto 0 loop
490
                if DIRECTION = '0' then
491
                    if i >= tmpdist then
492
                        IRESULT(i) <= tmpdata(i-tmpdist);
493
                    else
494
                        IRESULT(i) <= '0';
495
                    end if;
496
                elsif DIRECTION = '1' then
497
                    if i+tmpdist < LPM_WIDTH then
498
                        IRESULT(i) <= tmpdata(i+tmpdist);
499
                    elsif LPM_SHIFTTYPE = "ARITHMETIC" then
500
                        IRESULT(i) <= DATA(LPM_WIDTH-1);
501
                    else
502
                        IRESULT(i) <= '0';
503
                    end if;
504
                end if;
505
            end loop;
506
                elsif LPM_SHIFTTYPE = "ROTATE" then
507
            tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
508
            tmpdist := conv_integer(unsigned(DISTANCE)) mod LPM_WIDTH;
509
            for i in LPM_WIDTH-1 downto 0 loop
510
                if DIRECTION = '0' then
511
                    if i >= tmpdist then
512
                        IRESULT(i) <= tmpdata(i-tmpdist);
513
                    else
514
                        IRESULT(i) <= tmpdata(i+LPM_WIDTH-tmpdist);
515
                    end if;
516
                elsif DIRECTION = '1' then
517
                    if i+tmpdist < LPM_WIDTH then
518
                        IRESULT(i) <= tmpdata(i+tmpdist);
519
                    else
520
                        IRESULT(i) <= tmpdata(i-LPM_WIDTH+tmpdist);
521
                    end if;
522
                end if;
523
            end loop;
524
        else
525
            ASSERT FALSE
526
            REPORT "Illegal LPM_SHIFTTYPE property value for LPM_CLSHIFT!"
527
            SEVERITY ERROR;
528
                end if;
529
        end process;
530
 
531
    process(DATA, DISTANCE, DIRECTION, IRESULT)
532
    variable neg_one : signed(LPM_WIDTH-1 downto 0) := (OTHERS => '1');
533
    variable tmpdata : std_logic_vector(LPM_WIDTH-1 downto 0);
534
    variable tmpdist : integer;
535
    variable msb_cnt, lsb_cnt : integer := 0;
536
    variable sgn_bit : std_logic;
537
        begin
538
        tmpdata := conv_std_logic_vector(unsigned(DATA), LPM_WIDTH);
539
        tmpdist := conv_integer(DISTANCE);
540
 
541
        OVERFLOW <= '0';
542
        UNDERFLOW <= '0';
543
 
544
        if (tmpdist /= 0 and tmpdata /= 0) then
545
            if LPM_SHIFTTYPE = "ROTATE" then
546
                OVERFLOW <= 'U';
547
                UNDERFLOW <= 'U';
548
            else
549
                if (tmpdist < LPM_WIDTH) then
550
                    if LPM_SHIFTTYPE = "LOGICAL" then
551
                        msb_cnt := 0;
552
                        while (msb_cnt < LPM_WIDTH) and (tmpdata(LPM_WIDTH-msb_cnt-1) = '0') loop
553
                            msb_cnt := msb_cnt + 1;
554
                        end loop;
555
 
556
                        if ((tmpdist > msb_cnt) and (DIRECTION = '0')) then
557
                            OVERFLOW <= '1';
558
                        elsif ((tmpdist + msb_cnt >= LPM_WIDTH) and (DIRECTION = '1')) then
559
                            UNDERFLOW <= '1';
560
                        end if;
561
                    elsif LPM_SHIFTTYPE = "ARITHMETIC" then
562
                        sgn_bit := '0';
563
                        if (tmpdata(LPM_WIDTH-1) = '1') then
564
                            sgn_bit := '1';
565
                        end if;
566
 
567
                        msb_cnt := 0;
568
                        while (msb_cnt < LPM_WIDTH) and (tmpdata(LPM_WIDTH-msb_cnt-1) = sgn_bit) loop
569
                            msb_cnt := msb_cnt + 1;
570
                        end loop;
571
 
572
                        lsb_cnt := 0;
573
                        while (lsb_cnt < LPM_WIDTH) and (tmpdata(lsb_cnt) = '0') loop
574
                            lsb_cnt := lsb_cnt + 1;
575
                        end loop;
576
 
577
                        if (DIRECTION = '1') then         -- shift right
578
                            if (tmpdata(LPM_WIDTH-1) = '1') then  -- negative
579
                                --Use the following line if 1110 asr 1 yields NO underflow is desired.
580
                                --if (msb_cnt + tmpdist > LPM_WIDTH) or ((msb_cnt + tmpdist = LPM_WIDTH) and (tmpdist > lsb_cnt)) then
581
                                -- SPR76524 comments/replaces out the line below
582
                                -- if (msb_cnt + tmpdist > LPM_WIDTH) or ((msb_cnt + tmpdist = LPM_WIDTH) and (tmpdist >= lsb_cnt)) then
583
                                if (msb_cnt + tmpdist >= LPM_WIDTH) and (msb_cnt /= LPM_WIDTH) then
584
                                    UNDERFLOW <= '1';
585
                                end if;
586
                            else  -- non-neg
587
                                -- SPR76524 comments/replaces out the line below
588
                                -- if (msb_cnt + tmpdist >= LPM_WIDTH) then
589
                                if (msb_cnt + tmpdist >= LPM_WIDTH) and (msb_cnt /= LPM_WIDTH) then
590
                                    UNDERFLOW <= '1';
591
                                end if;
592
                            end if;
593
                        elsif (DIRECTION = '0') then      -- shift left
594
                            if (tmpdata(LPM_WIDTH-1) = '1') then -- negative
595
                                if ((signed(tmpdata) /= neg_one) and (tmpdist >= LPM_WIDTH)) or (tmpdist >= msb_cnt) then
596
                                    OVERFLOW <= '1';
597
                                end if;
598
                            else  -- non-neg
599
                                if ((tmpdata /= 0) and (tmpdist >= LPM_WIDTH-1)) or (tmpdist >= msb_cnt) then
600
                                    OVERFLOW <= '1';
601
                                end if;
602
                            end if;
603
                        end if;
604
                    end if;
605
                else
606
                    if DIRECTION = '0' then
607
                        OVERFLOW <= '1';
608
                    elsif DIRECTION = '1' then
609
                        UNDERFLOW <= '1';
610
                    end if;
611
                end if;  -- tmpdist < LPM_WIDTH
612
            end if;  -- LPM_SHIFTTYPE = "ROTATE"
613
        end if;  -- tmpdist /= 0 and tmpdata /= 0
614
        end process;
615
 
616
        RESULT <= IRESULT;
617
 
618
end LPM_SYN;
619
 
620
 
621
--------------------------------------------------------------------------
622
 
623
library IEEE;
624
use IEEE.std_logic_1164.all;
625
use IEEE.std_logic_signed.all;
626
use work.LPM_COMPONENTS.all;
627
 
628
entity LPM_ADD_SUB_SIGNED is
629
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
630
                         LPM_DIRECTION : string := "UNUSED";
631
             LPM_PIPELINE : natural := 0;
632
                         LPM_TYPE : string := "LPM_ADD_SUB";
633
                         LPM_HINT : string := "UNUSED");
634
        port (DATAA : in std_logic_vector(LPM_WIDTH downto 1);
635
                  DATAB : in std_logic_vector(LPM_WIDTH downto 1);
636
                  ACLR : in std_logic := '0';
637
                  CLOCK : in std_logic := '0';
638
                  CLKEN : in std_logic := '1';
639
          CIN : in std_logic := 'Z';
640
                  ADD_SUB : in std_logic := '1';
641
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
642
                  COUT : out std_logic;
643
                  OVERFLOW : out std_logic);
644
end LPM_ADD_SUB_SIGNED;
645
 
646
architecture LPM_SYN of LPM_ADD_SUB_SIGNED is
647
 
648
signal A, B : std_logic_vector(LPM_WIDTH downto 0);
649
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH downto 0);
650
 
651
begin
652
 
653
        A <= (DATAA(LPM_WIDTH) & DATAA);
654
        B <= (DATAB(LPM_WIDTH) & DATAB);
655
 
656
        process(ACLR, CLOCK, A, B, CIN, ADD_SUB)
657
    variable resulttmp : t_resulttmp := (OTHERS => (OTHERS => '0'));
658
    variable couttmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
659
    variable overflowtmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
660
    variable i_cin : std_logic;
661
        begin
662
                if LPM_PIPELINE >= 0 then
663
                        if LPM_DIRECTION = "ADD" or
664
               (LPM_DIRECTION = "UNUSED" and ADD_SUB = '1') then
665
                if (CIN = 'Z') then
666
                    i_cin := '0';
667
                else
668
                    i_cin := CIN;
669
                end if;
670
 
671
                resulttmp(LPM_PIPELINE) := A + B + i_cin;
672
                                couttmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH)
673
                                                                                        xor DATAA(LPM_WIDTH)
674
                                                                                        xor DATAB(LPM_WIDTH);
675
            elsif LPM_DIRECTION = "SUB" or
676
                  (LPM_DIRECTION = "UNUSED" and ADD_SUB = '0') then
677
                if (CIN = 'Z') then
678
                    i_cin := '1';
679
                else
680
                    i_cin := CIN;
681
                end if;
682
 
683
                resulttmp(LPM_PIPELINE) := A - B + i_cin - 1;
684
                                couttmp(LPM_PIPELINE) := not resulttmp(LPM_PIPELINE)(LPM_WIDTH)
685
                                                                                        xor DATAA(LPM_WIDTH)
686
                                                                                        xor DATAB(LPM_WIDTH);
687
            elsif LPM_DIRECTION /= "UNUSED" then
688
                ASSERT FALSE
689
                REPORT "Illegal LPM_DIRECTION property value for LPM_ADD_SUB!"
690
                SEVERITY ERROR;
691
            end if;
692
 
693
                        if (resulttmp(LPM_PIPELINE) > (2 ** (LPM_WIDTH-1)) -1) or
694
                           (resulttmp(LPM_PIPELINE) < -2 ** (LPM_WIDTH-1)) then
695
 
696
                                overflowtmp(LPM_PIPELINE) := '1';
697
                        else
698
                                overflowtmp(LPM_PIPELINE) := '0';
699
                        end if;
700
 
701
                        if LPM_PIPELINE > 0 then
702
                                if ACLR = '1' then
703
                                        overflowtmp := (OTHERS => '0');
704
                                        couttmp := (OTHERS => '0');
705
                                        for i in 0 to LPM_PIPELINE loop
706
                                                resulttmp(i) := (OTHERS => '0');
707
                                        end loop;
708
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
709
                                        overflowtmp(0 to LPM_PIPELINE - 1) := overflowtmp(1 to LPM_PIPELINE);
710
                                        couttmp(0 to LPM_PIPELINE - 1) := couttmp(1 to LPM_PIPELINE);
711
                                        resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
712
                                end if;
713
                        end if;
714
 
715
            COUT <= couttmp(0);
716
                        OVERFLOW <= overflowtmp(0);
717
                        RESULT <= resulttmp(0)(LPM_WIDTH-1 downto 0);
718
                end if;
719
        end process;
720
 
721
end LPM_SYN;
722
 
723
 
724
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
725
 
726
library IEEE;
727
use IEEE.std_logic_1164.all;
728
use IEEE.std_logic_unsigned.all;
729
use work.LPM_COMPONENTS.all;
730
 
731
entity LPM_ADD_SUB_UNSIGNED is
732
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
733
                         LPM_DIRECTION : string := "UNUSED";
734
             LPM_PIPELINE : natural := 0;
735
                         LPM_TYPE : string := "LPM_ADD_SUB";
736
                         LPM_HINT : string := "UNUSED");
737
        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
738
                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
739
                  ACLR : in std_logic := '0';
740
                  CLOCK : in std_logic := '0';
741
                  CLKEN : in std_logic := '1';
742
          CIN : in std_logic := 'Z';
743
                  ADD_SUB : in std_logic := '1';
744
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
745
                  COUT : out std_logic;
746
                  OVERFLOW : out std_logic);
747
end LPM_ADD_SUB_UNSIGNED;
748
 
749
architecture LPM_SYN of LPM_ADD_SUB_UNSIGNED is
750
signal A, B : std_logic_vector(LPM_WIDTH downto 0);
751
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTH downto 0);
752
 
753
begin
754
 
755
        A <= ('0' & DATAA);
756
        B <= ('0' & DATAB);
757
 
758
        process(ACLR, CLOCK, A, B, CIN, ADD_SUB)
759
    variable resulttmp : t_resulttmp := (OTHERS => (OTHERS => '0'));
760
    variable couttmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
761
    variable overflowtmp : std_logic_vector(0 to LPM_PIPELINE) := (OTHERS => '0');
762
    variable i_cin : std_logic;
763
        begin
764
 
765
                if LPM_PIPELINE >= 0 then
766
                        if LPM_DIRECTION = "ADD" or
767
               (LPM_DIRECTION = "UNUSED" and ADD_SUB = '1') then
768
                if (CIN = 'Z') then
769
                    i_cin := '0';
770
                else
771
                    i_cin := CIN;
772
                end if;
773
 
774
                resulttmp(LPM_PIPELINE) := A + B + i_cin;
775
                                couttmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH);
776
            elsif LPM_DIRECTION = "SUB" or
777
                  (LPM_DIRECTION = "UNUSED" and ADD_SUB = '0') then
778
                if (CIN = 'Z') then
779
                    i_cin := '1';
780
                else
781
                    i_cin := CIN;
782
                end if;
783
 
784
                resulttmp(LPM_PIPELINE) := A - B + i_cin - 1;
785
                                couttmp(LPM_PIPELINE) := not resulttmp(LPM_PIPELINE)(LPM_WIDTH);
786
            elsif LPM_DIRECTION /= "UNUSED" then
787
                ASSERT FALSE
788
                REPORT "Illegal LPM_DIRECTION property value for LPM_ADD_SUB!"
789
                SEVERITY ERROR;
790
                        end if;
791
 
792
                        overflowtmp(LPM_PIPELINE) := resulttmp(LPM_PIPELINE)(LPM_WIDTH);
793
 
794
                        if LPM_PIPELINE > 0 then
795
                                if ACLR = '1' then
796
                                        overflowtmp := (OTHERS => '0');
797
                                        couttmp := (OTHERS => '0');
798
                                        for i in 0 to LPM_PIPELINE loop
799
                                                resulttmp(i) := (OTHERS => '0');
800
                                        end loop;
801
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
802
                                        overflowtmp(0 to LPM_PIPELINE - 1) := overflowtmp(1 to LPM_PIPELINE);
803
                                        couttmp(0 to LPM_PIPELINE - 1) := couttmp(1 to LPM_PIPELINE);
804
                                        resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
805
                                end if;
806
                        end if;
807
 
808
            COUT <= couttmp(0);
809
                        OVERFLOW <= overflowtmp(0);
810
                        RESULT <= resulttmp(0)(LPM_WIDTH-1 downto 0);
811
                end if;
812
        end process;
813
 
814
end LPM_SYN;
815
 
816
 
817
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
818
 
819
library IEEE;
820
use IEEE.std_logic_1164.all;
821
use work.LPM_COMPONENTS.all;
822
 
823
entity LPM_ADD_SUB is
824
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
825
                         LPM_DIRECTION : string := "UNUSED";
826
                         LPM_REPRESENTATION: string := "SIGNED";
827
             LPM_PIPELINE : natural := 0;
828
                         LPM_TYPE : string := "LPM_ADD_SUB";
829
                         LPM_HINT : string := "UNUSED");
830
        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
831
                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
832
                  ACLR : in std_logic := '0';
833
                  CLOCK : in std_logic := '0';
834
                  CLKEN : in std_logic := '1';
835
          CIN : in std_logic := 'Z';
836
                  ADD_SUB : in std_logic := '1';
837
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
838
                  COUT : out std_logic;
839
                  OVERFLOW : out std_logic);
840
end LPM_ADD_SUB;
841
 
842
architecture LPM_SYN of LPM_ADD_SUB is
843
 
844
        component LPM_ADD_SUB_SIGNED
845
            generic (LPM_WIDTH : natural;    -- MUST be greater than 0
846
                                         LPM_DIRECTION : string := "UNUSED";
847
                     LPM_PIPELINE : natural := 0;
848
                                         LPM_TYPE : string := "LPM_ADD_SUB";
849
                                         LPM_HINT : string := "UNUSED");
850
                        port (DATAA : in std_logic_vector(LPM_WIDTH downto 1);
851
                                  DATAB : in std_logic_vector(LPM_WIDTH downto 1);
852
                                  ACLR : in std_logic := '0';
853
                                  CLOCK : in std_logic := '0';
854
                                  CLKEN : in std_logic := '1';
855
                  CIN : in std_logic := 'Z';
856
                                  ADD_SUB : in std_logic := '1';
857
                                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
858
                                  COUT : out std_logic;
859
                                  OVERFLOW : out std_logic);
860
        end component;
861
 
862
        component LPM_ADD_SUB_UNSIGNED
863
            generic (LPM_WIDTH : natural;    -- MUST be greater than 0
864
                                         LPM_DIRECTION : string := "UNUSED";
865
                     LPM_PIPELINE : natural := 0;
866
                                         LPM_TYPE : string := "LPM_ADD_SUB";
867
                                         LPM_HINT : string := "UNUSED");
868
                        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
869
                                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
870
                                  ACLR : in std_logic := '0';
871
                                  CLOCK : in std_logic := '0';
872
                                  CLKEN : in std_logic := '1';
873
                  CIN : in std_logic := 'Z';
874
                                  ADD_SUB : in std_logic := '1';
875
                                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
876
                                  COUT : out std_logic;
877
                                  OVERFLOW : out std_logic);
878
        end component;
879
 
880
 
881
begin
882
 
883
L1: if LPM_REPRESENTATION = "UNSIGNED" generate
884
 
885
U:  LPM_ADD_SUB_UNSIGNED
886
        generic map (LPM_WIDTH => LPM_WIDTH, LPM_DIRECTION => LPM_DIRECTION,
887
                                 LPM_PIPELINE => LPM_PIPELINE, LPM_TYPE => LPM_TYPE,
888
                                 LPM_HINT => LPM_HINT)
889
        port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR, CLOCK => CLOCK,
890
                          CIN => CIN, ADD_SUB => ADD_SUB, RESULT => RESULT, COUT => COUT,
891
                          OVERFLOW => OVERFLOW, CLKEN => CLKEN);
892
        end generate;
893
 
894
L2: if LPM_REPRESENTATION = "SIGNED" generate
895
 
896
V:  LPM_ADD_SUB_SIGNED
897
        generic map (LPM_WIDTH => LPM_WIDTH, LPM_DIRECTION => LPM_DIRECTION,
898
                                 LPM_PIPELINE => LPM_PIPELINE, LPM_TYPE => LPM_TYPE,
899
                                 LPM_HINT => LPM_HINT)
900
        port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR, CLOCK => CLOCK,
901
                          CIN => CIN, ADD_SUB => ADD_SUB, RESULT => RESULT, COUT => COUT,
902
                          OVERFLOW => OVERFLOW, CLKEN => CLKEN);
903
        end generate;
904
 
905
end LPM_SYN;
906
 
907
 
908
--------------------------------------------------------------------------
909
 
910
library IEEE;
911
use IEEE.std_logic_1164.all;
912
use IEEE.std_logic_arith.all;
913
use IEEE.std_logic_signed.all;
914
use work.LPM_COMPONENTS.all;
915
 
916
entity LPM_COMPARE_SIGNED is
917
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
918
             LPM_PIPELINE : natural := 0;
919
                         LPM_TYPE: string := "LPM_COMPARE";
920
                         LPM_HINT : string := "UNUSED");
921
        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
922
                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
923
                  ACLR : in std_logic := '0';
924
                  CLOCK : in std_logic := '0';
925
                  CLKEN : in std_logic := '1';
926
                  AGB : out std_logic;
927
                  AGEB : out std_logic;
928
                  AEB : out std_logic;
929
                  ANEB : out std_logic;
930
                  ALB : out std_logic;
931
                  ALEB : out std_logic);
932
end LPM_COMPARE_SIGNED;
933
 
934
architecture LPM_SYN of LPM_COMPARE_SIGNED is
935
begin
936
 
937
        process(ACLR, CLOCK, DATAA, DATAB)
938
        variable agbtmp : std_logic_vector (0 to LPM_PIPELINE);
939
        variable agebtmp : std_logic_vector (0 to LPM_PIPELINE);
940
        variable aebtmp : std_logic_vector (0 to LPM_PIPELINE);
941
        variable anebtmp : std_logic_vector (0 to LPM_PIPELINE);
942
        variable albtmp : std_logic_vector (0 to LPM_PIPELINE);
943
        variable alebtmp : std_logic_vector (0 to LPM_PIPELINE);
944
 
945
        begin
946
 
947
                if LPM_PIPELINE >= 0 then
948
                        if signed(DATAA) > signed(DATAB) then
949
                                agbtmp(LPM_PIPELINE) := '1';
950
                                agebtmp(LPM_PIPELINE) := '1';
951
                                anebtmp(LPM_PIPELINE) := '1';
952
                                aebtmp(LPM_PIPELINE) := '0';
953
                                albtmp(LPM_PIPELINE) := '0';
954
                                alebtmp(LPM_PIPELINE) := '0';
955
                        elsif signed(DATAA) = signed(DATAB) then
956
                                agbtmp(LPM_PIPELINE) := '0';
957
                                agebtmp(LPM_PIPELINE) := '1';
958
                                anebtmp(LPM_PIPELINE) := '0';
959
                                aebtmp(LPM_PIPELINE) := '1';
960
                                albtmp(LPM_PIPELINE) := '0';
961
                                alebtmp(LPM_PIPELINE) := '1';
962
                        else
963
                                agbtmp(LPM_PIPELINE) := '0';
964
                                agebtmp(LPM_PIPELINE) := '0';
965
                                anebtmp(LPM_PIPELINE) := '1';
966
                                aebtmp(LPM_PIPELINE) := '0';
967
                                albtmp(LPM_PIPELINE) := '1';
968
                                alebtmp(LPM_PIPELINE) := '1';
969
                        end if;
970
 
971
                        if LPM_PIPELINE > 0 then
972
                                if ACLR = '1' then
973
                                        for i in 0 to LPM_PIPELINE loop
974
                                                agbtmp(i) := '0';
975
                                                agebtmp(i) := '0';
976
                                                anebtmp(i) := '0';
977
                                                aebtmp(i) := '0';
978
                                                albtmp(i) := '0';
979
                                                alebtmp(i) := '0';
980
                                        end loop;
981
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
982
                                        agbtmp(0 to LPM_PIPELINE-1) :=  agbtmp(1 to LPM_PIPELINE);
983
                                        agebtmp(0 to LPM_PIPELINE-1) := agebtmp(1 to LPM_PIPELINE) ;
984
                                        anebtmp(0 to LPM_PIPELINE-1) := anebtmp(1 to LPM_PIPELINE);
985
                                        aebtmp(0 to LPM_PIPELINE-1) := aebtmp(1 to LPM_PIPELINE);
986
                                        albtmp(0 to LPM_PIPELINE-1) := albtmp(1 to LPM_PIPELINE);
987
                                        alebtmp(0 to LPM_PIPELINE-1) := alebtmp(1 to LPM_PIPELINE);
988
                                end if;
989
                        end if;
990
                end if;
991
 
992
                AGB <= agbtmp(0);
993
                AGEB <= agebtmp(0);
994
                ANEB <= anebtmp(0);
995
                AEB <= aebtmp(0);
996
                ALB <= albtmp(0);
997
                ALEB <= alebtmp(0);
998
        end process;
999
 
1000
end LPM_SYN;
1001
 
1002
 
1003
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1004
 
1005
library IEEE;
1006
use IEEE.std_logic_1164.all;
1007
use IEEE.std_logic_arith.all;
1008
use IEEE.std_logic_unsigned.all;
1009
use work.LPM_COMPONENTS.all;
1010
 
1011
entity LPM_COMPARE_UNSIGNED is
1012
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1013
             LPM_PIPELINE : natural := 0;
1014
                         LPM_TYPE: string := "LPM_COMPARE";
1015
                         LPM_HINT : string := "UNUSED");
1016
        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1017
                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
1018
                  ACLR : in std_logic := '0';
1019
                  CLOCK : in std_logic := '0';
1020
                  CLKEN : in std_logic := '1';
1021
                  AGB : out std_logic;
1022
                  AGEB : out std_logic;
1023
                  AEB : out std_logic;
1024
                  ANEB : out std_logic;
1025
                  ALB : out std_logic;
1026
                  ALEB : out std_logic);
1027
end LPM_COMPARE_UNSIGNED;
1028
 
1029
architecture LPM_SYN of LPM_COMPARE_UNSIGNED is
1030
begin
1031
 
1032
        process(ACLR, CLOCK, DATAA, DATAB)
1033
        variable agbtmp : std_logic_vector (0 to LPM_PIPELINE);
1034
        variable agebtmp : std_logic_vector (0 to LPM_PIPELINE);
1035
        variable aebtmp : std_logic_vector (0 to LPM_PIPELINE);
1036
        variable anebtmp : std_logic_vector (0 to LPM_PIPELINE);
1037
        variable albtmp : std_logic_vector (0 to LPM_PIPELINE);
1038
        variable alebtmp : std_logic_vector (0 to LPM_PIPELINE);
1039
 
1040
        begin
1041
                if LPM_PIPELINE >= 0 then
1042
                        if unsigned(DATAA) > unsigned(DATAB) then
1043
                                agbtmp(LPM_PIPELINE) := '1';
1044
                                agebtmp(LPM_PIPELINE) := '1';
1045
                                anebtmp(LPM_PIPELINE) := '1';
1046
                                aebtmp(LPM_PIPELINE) := '0';
1047
                                albtmp(LPM_PIPELINE) := '0';
1048
                                alebtmp(LPM_PIPELINE) := '0';
1049
                        elsif unsigned(DATAA) = unsigned(DATAB) then
1050
                                agbtmp(LPM_PIPELINE) := '0';
1051
                                agebtmp(LPM_PIPELINE) := '1';
1052
                                anebtmp(LPM_PIPELINE) := '0';
1053
                                aebtmp(LPM_PIPELINE) := '1';
1054
                                albtmp(LPM_PIPELINE) := '0';
1055
                                alebtmp(LPM_PIPELINE) := '1';
1056
                        else
1057
                                agbtmp(LPM_PIPELINE) := '0';
1058
                                agebtmp(LPM_PIPELINE) := '0';
1059
                                anebtmp(LPM_PIPELINE) := '1';
1060
                                aebtmp(LPM_PIPELINE) := '0';
1061
                                albtmp(LPM_PIPELINE) := '1';
1062
                                alebtmp(LPM_PIPELINE) := '1';
1063
                        end if;
1064
 
1065
                        if LPM_PIPELINE > 0 then
1066
                                if ACLR = '1' then
1067
                                        for i in 0 to LPM_PIPELINE loop
1068
                                                agbtmp(i) := '0';
1069
                                                agebtmp(i) := '0';
1070
                                                anebtmp(i) := '0';
1071
                                                aebtmp(i) := '0';
1072
                                                albtmp(i) := '0';
1073
                                                alebtmp(i) := '0';
1074
                                        end loop;
1075
                                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' then
1076
                                        agbtmp(0 to LPM_PIPELINE-1) :=  agbtmp(1 to LPM_PIPELINE);
1077
                                        agebtmp(0 to LPM_PIPELINE-1) := agebtmp(1 to LPM_PIPELINE) ;
1078
                                        anebtmp(0 to LPM_PIPELINE-1) := anebtmp(1 to LPM_PIPELINE);
1079
                                        aebtmp(0 to LPM_PIPELINE-1) := aebtmp(1 to LPM_PIPELINE);
1080
                                        albtmp(0 to LPM_PIPELINE-1) := albtmp(1 to LPM_PIPELINE);
1081
                                        alebtmp(0 to LPM_PIPELINE-1) := alebtmp(1 to LPM_PIPELINE);
1082
                                end if;
1083
                        end if;
1084
                end if;
1085
 
1086
                AGB <= agbtmp(0);
1087
                AGEB <= agebtmp(0);
1088
                ANEB <= anebtmp(0);
1089
                AEB <= aebtmp(0);
1090
                ALB <= albtmp(0);
1091
                ALEB <= alebtmp(0);
1092
        end process;
1093
 
1094
end LPM_SYN;
1095
 
1096
 
1097
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1098
 
1099
library IEEE;
1100
use IEEE.std_logic_1164.all;
1101
use work.LPM_COMPONENTS.all;
1102
 
1103
entity LPM_COMPARE is
1104
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1105
                         LPM_REPRESENTATION : string := "UNSIGNED";
1106
             LPM_PIPELINE : natural := 0;
1107
                         LPM_TYPE: string := "LPM_COMPARE";
1108
                         LPM_HINT : string := "UNUSED");
1109
        port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1110
                  DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
1111
                  ACLR : in std_logic := '0';
1112
                  CLOCK : in std_logic := '0';
1113
                  CLKEN : in std_logic := '1';
1114
                  AGB : out std_logic;
1115
                  AGEB : out std_logic;
1116
                  AEB : out std_logic;
1117
                  ANEB : out std_logic;
1118
                  ALB : out std_logic;
1119
                  ALEB : out std_logic);
1120
end LPM_COMPARE;
1121
 
1122
architecture LPM_SYN of LPM_COMPARE is
1123
 
1124
        component LPM_COMPARE_SIGNED
1125
        generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1126
                 LPM_PIPELINE : natural := 0;
1127
                                 LPM_TYPE: string := "LPM_COMPARE";
1128
                                 LPM_HINT : string := "UNUSED");
1129
                port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1130
                          DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
1131
                          ACLR : in std_logic := '0';
1132
                          CLOCK : in std_logic := '0';
1133
                          CLKEN : in std_logic := '1';
1134
                          AGB : out std_logic;
1135
                          AGEB : out std_logic;
1136
                          AEB : out std_logic;
1137
                          ANEB : out std_logic;
1138
                          ALB : out std_logic;
1139
                          ALEB : out std_logic);
1140
        end component;
1141
 
1142
        component LPM_COMPARE_UNSIGNED
1143
        generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1144
                 LPM_PIPELINE : natural := 0;
1145
                                 LPM_TYPE: string := "LPM_COMPARE";
1146
                                 LPM_HINT : string := "UNUSED");
1147
                port (DATAA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1148
                          DATAB : in std_logic_vector(LPM_WIDTH-1 downto 0);
1149
                          ACLR : in std_logic := '0';
1150
                          CLOCK : in std_logic := '0';
1151
                          CLKEN : in std_logic := '1';
1152
                          AGB : out std_logic;
1153
                          AGEB : out std_logic;
1154
                          AEB : out std_logic;
1155
                          ANEB : out std_logic;
1156
                          ALB : out std_logic;
1157
                          ALEB : out std_logic);
1158
        end component;
1159
 
1160
begin
1161
 
1162
L1: if LPM_REPRESENTATION = "UNSIGNED" generate
1163
 
1164
U1: LPM_COMPARE_UNSIGNED
1165
        generic map (LPM_WIDTH => LPM_WIDTH, LPM_PIPELINE => LPM_PIPELINE,
1166
                                 LPM_TYPE => LPM_TYPE, LPM_HINT => LPM_HINT)
1167
        port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR,
1168
                          CLOCK => CLOCK, AGB => AGB, AGEB => AGEB, CLKEN => CLKEN,
1169
                          AEB => AEB, ANEB => ANEB, ALB => ALB, ALEB => ALEB);
1170
        end generate;
1171
 
1172
L2: if LPM_REPRESENTATION = "SIGNED" generate
1173
 
1174
U2: LPM_COMPARE_SIGNED
1175
        generic map (LPM_WIDTH => LPM_WIDTH, LPM_PIPELINE => LPM_PIPELINE,
1176
                                 LPM_TYPE => LPM_TYPE, LPM_HINT => LPM_HINT)
1177
        port map (DATAA => DATAA, DATAB => DATAB, ACLR => ACLR,
1178
                          CLOCK => CLOCK, AGB => AGB, AGEB => AGEB, CLKEN => CLKEN,
1179
                          AEB => AEB, ANEB => ANEB, ALB => ALB, ALEB => ALEB);
1180
        end generate;
1181
 
1182
end LPM_SYN;
1183
 
1184
 
1185
--------------------------------------------------------------------------
1186
 
1187
library IEEE;
1188
use IEEE.std_logic_1164.all;
1189
use IEEE.std_logic_arith.all;
1190
use work.LPM_COMPONENTS.all;
1191
 
1192
entity LPM_MULT is
1193
    generic (LPM_WIDTHA : natural;    -- MUST be greater than 0
1194
             LPM_WIDTHB : natural;    -- MUST be greater than 0
1195
                         LPM_WIDTHS : natural := 0;
1196
             LPM_WIDTHP : natural;    -- MUST be greater than 0
1197
                         LPM_REPRESENTATION : string := "UNSIGNED";
1198
             LPM_PIPELINE : natural := 0;
1199
                         LPM_TYPE: string := "LPM_MULT";
1200
                         LPM_HINT : string := "UNUSED");
1201
        port (DATAA : in std_logic_vector(LPM_WIDTHA-1 downto 0);
1202
                  DATAB : in std_logic_vector(LPM_WIDTHB-1 downto 0);
1203
                  ACLR : in std_logic := '0';
1204
                  CLOCK : in std_logic := '0';
1205
                  CLKEN : in std_logic := '1';
1206
                  SUM : in std_logic_vector(LPM_WIDTHS-1 downto 0) := (OTHERS => '0');
1207
                  RESULT : out std_logic_vector(LPM_WIDTHP-1 downto 0));
1208
end LPM_MULT;
1209
 
1210
architecture LPM_SYN of LPM_MULT is
1211
 
1212
type t_resulttmp IS ARRAY (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHP-1 downto 0);
1213
 
1214
begin
1215
 
1216
        process (CLOCK, ACLR, DATAA, DATAB, SUM)
1217
        variable resulttmp : t_resulttmp;
1218
    variable tmp_prod_ab : std_logic_vector(LPM_WIDTHA+LPM_WIDTHB downto 0);
1219
    variable tmp_prod_s : std_logic_vector(LPM_WIDTHS downto 0);
1220
    variable tmp_prod_p : std_logic_vector(LPM_WIDTHP-1 downto 0);
1221
    variable tmp_use : integer;
1222
        begin
1223
                if LPM_PIPELINE >= 0 then
1224
 
1225
            if LPM_REPRESENTATION = "SIGNED" then
1226
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto 0) := signed(DATAA) * signed(DATAB);
1227
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB) := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1);
1228
            elsif LPM_REPRESENTATION = "UNSIGNED" then
1229
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto 0) := unsigned(DATAA) * unsigned(DATAB);
1230
                tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB) := '0';
1231
            else
1232
                ASSERT FALSE
1233
                REPORT "Illegal LPM_REPRESENTATION property value for LPM_MULT!"
1234
                SEVERITY ERROR;
1235
            end if;
1236
            tmp_use := 1; --AB
1237
            if (LPM_WIDTHS > LPM_WIDTHA+LPM_WIDTHB) then
1238
                if LPM_REPRESENTATION = "SIGNED" then
1239
                    tmp_prod_s := (OTHERS => tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB));
1240
                    tmp_prod_s(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab;
1241
                    tmp_prod_s := signed(tmp_prod_s) + signed(SUM);
1242
                    tmp_prod_p := (OTHERS => tmp_prod_s(LPM_WIDTHS));
1243
                else
1244
                    tmp_prod_s := (OTHERS => '0');
1245
                    tmp_prod_s(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab;
1246
                    tmp_prod_s := unsigned(tmp_prod_s) + unsigned(SUM);
1247
                    tmp_prod_p := (OTHERS => '0');
1248
                end if;
1249
                tmp_use := 2; --S
1250
            elsif (LPM_WIDTHS > 0) then
1251
                if LPM_REPRESENTATION = "SIGNED" then
1252
                    tmp_prod_ab := signed(tmp_prod_ab) + signed(SUM);
1253
                    tmp_prod_p := (OTHERS => tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB));
1254
                else
1255
                    tmp_prod_ab := unsigned(tmp_prod_ab) + unsigned(SUM);
1256
                    tmp_prod_p := (OTHERS => '0');
1257
                end if;
1258
            end if;
1259
 
1260
            if (tmp_use = 2) then --S
1261
                if (LPM_WIDTHP > LPM_WIDTHS) then
1262
                    tmp_prod_p(LPM_WIDTHS downto 0) := tmp_prod_s;
1263
                elsif (LPM_WIDTHP = LPM_WIDTHS) then
1264
                    tmp_prod_p := tmp_prod_s(LPM_WIDTHP-1 downto 0);
1265
                else
1266
                    tmp_prod_p := tmp_prod_s(LPM_WIDTHS-1 downto LPM_WIDTHS-LPM_WIDTHP);
1267
                end if;
1268
            else --AB
1269
                if (LPM_WIDTHP > LPM_WIDTHA+LPM_WIDTHB) then
1270
                    tmp_prod_p(LPM_WIDTHA+LPM_WIDTHB downto 0) := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB downto 0);
1271
                elsif (LPM_WIDTHP = LPM_WIDTHA+LPM_WIDTHB) then
1272
                    tmp_prod_p := tmp_prod_ab(LPM_WIDTHP-1 downto 0);
1273
                else
1274
                    tmp_prod_p := tmp_prod_ab(LPM_WIDTHA+LPM_WIDTHB-1 downto LPM_WIDTHA+LPM_WIDTHB-LPM_WIDTHP);
1275
                end if;
1276
            end if;
1277
 
1278
            resulttmp(LPM_PIPELINE) := tmp_prod_p;
1279
 
1280
                        if LPM_PIPELINE > 0 then
1281
                                if ACLR = '1' then
1282
                                        for i in 0 to LPM_PIPELINE loop
1283
                                                resulttmp(i) := (OTHERS => '0');
1284
                                        end loop;
1285
                elsif CLOCK'event and CLOCK = '1' and CLKEN = '1' and now > 0 ns then
1286
                                        resulttmp(0 to LPM_PIPELINE - 1) := resulttmp(1 to LPM_PIPELINE);
1287
                                end if;
1288
                        end if;
1289
                end if;
1290
 
1291
                RESULT <= resulttmp(0);
1292
        end process;
1293
 
1294
end LPM_SYN;
1295
 
1296
 
1297
--------------------------------------------------------------------------
1298
 
1299
library IEEE;
1300
use IEEE.std_logic_1164.all;
1301
use IEEE.std_logic_arith.all;
1302
use work.LPM_COMPONENTS.all;
1303
 
1304
entity LPM_DIVIDE is
1305
    generic (LPM_WIDTHN : natural;    -- MUST be greater than 0
1306
             LPM_WIDTHD : natural;    -- MUST be greater than 0
1307
                         LPM_NREPRESENTATION : string := "UNSIGNED";
1308
                         LPM_DREPRESENTATION : string := "UNSIGNED";
1309
                         LPM_REMAINDERPOSITIVE : string := "TRUE";
1310
             LPM_PIPELINE : natural := 0;
1311
                         LPM_TYPE : string := "LPM_DIVIDE";
1312
                         LPM_HINT : string := "UNUSED");
1313
        port (NUMER : in std_logic_vector(LPM_WIDTHN-1 downto 0);
1314
                  DENOM : in std_logic_vector(LPM_WIDTHD-1 downto 0);
1315
                  ACLR : in std_logic := '0';
1316
                  CLOCK : in std_logic := '0';
1317
                  CLKEN : in std_logic := '1';
1318
                  QUOTIENT : out std_logic_vector(LPM_WIDTHN-1 downto 0);
1319
                  REMAIN : out std_logic_vector(LPM_WIDTHD-1 downto 0));
1320
end LPM_DIVIDE;
1321
 
1322
architecture behave of lpm_divide is
1323
 
1324
type qpipeline is array (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHN-1 downto 0);
1325
type rpipeline is array (0 to LPM_PIPELINE) of std_logic_vector(LPM_WIDTHD-1 downto 0);
1326
 
1327
begin
1328
 
1329
        process (aclr, clock, numer, denom)
1330
        variable tmp_quotient : qpipeline;
1331
        variable tmp_remain : rpipeline;
1332
    variable int_numer, int_denom, int_quotient, int_remain : integer := 0;
1333
        variable signed_quotient : signed(LPM_WIDTHN-1 downto 0);
1334
        variable unsigned_quotient : unsigned(LPM_WIDTHN-1 downto 0);
1335
        begin
1336
        if (LPM_NREPRESENTATION = "UNSIGNED") then
1337
                        int_numer := conv_integer(unsigned(numer));
1338
        elsif (LPM_NREPRESENTATION = "SIGNED") then
1339
                        int_numer := conv_integer(signed(numer));
1340
        else
1341
            ASSERT FALSE
1342
            REPORT "Illegal LPM_NREPRESENTATION property value for LPM_DIVIDE!"
1343
            SEVERITY ERROR;
1344
                end if;
1345
        if (LPM_DREPRESENTATION = "UNSIGNED" ) then
1346
                        int_denom := conv_integer(unsigned(denom));
1347
        elsif (LPM_DREPRESENTATION = "SIGNED") then
1348
                        int_denom := conv_integer(signed(denom));
1349
        else
1350
            ASSERT FALSE
1351
            REPORT "Illegal LPM_DREPRESENTATION property value for LPM_DIVIDE!"
1352
            SEVERITY ERROR;
1353
                end if;
1354
                if int_denom = 0 then
1355
                        int_quotient := 0;
1356
                        int_remain := 0;
1357
                else
1358
            int_quotient := int_numer / int_denom;
1359
            int_remain := int_numer rem int_denom;
1360
 
1361
            -- LPM 220 standard
1362
            if ((LPM_REMAINDERPOSITIVE = "TRUE") and (int_remain < 0)) then
1363
                if int_denom < 0 then
1364
                    int_quotient := int_quotient + 1;
1365
                else
1366
                    int_quotient := int_quotient - 1;
1367
                end if;
1368
                int_remain := int_numer - int_quotient*int_denom;
1369
            end if;
1370
                end if;
1371
                signed_quotient := conv_signed(int_quotient, LPM_WIDTHN);
1372
                unsigned_quotient := conv_unsigned(int_quotient, LPM_WIDTHN);
1373
 
1374
        tmp_remain(LPM_PIPELINE) := conv_std_logic_vector(int_Remain, LPM_WIDTHD);
1375
        if ((LPM_NREPRESENTATION = "UNSIGNED") and (LPM_DREPRESENTATION = "UNSIGNED")) then
1376
            tmp_quotient(LPM_PIPELINE) := conv_std_logic_vector(unsigned_quotient, LPM_WIDTHN);
1377
                else
1378
            tmp_quotient(LPM_PIPELINE) := conv_std_logic_vector(signed_quotient, LPM_WIDTHN);
1379
                end if;
1380
 
1381
        if LPM_PIPELINE > 0 then
1382
                        if aclr = '1' then
1383
                for i in 0 to LPM_PIPELINE loop
1384
                                        tmp_quotient(i) := (OTHERS => '0');
1385
                                        tmp_remain(i) := (OTHERS => '0');
1386
                                end loop;
1387
                        elsif clock'event and clock = '1' then
1388
                                if clken = '1' then
1389
                    tmp_quotient(0 to LPM_PIPELINE-1) := tmp_quotient(1 to LPM_PIPELINE);
1390
                    tmp_remain(0 to LPM_PIPELINE-1) := tmp_remain(1 to LPM_PIPELINE);
1391
                                end if;
1392
                        end if;
1393
                end if;
1394
 
1395
                quotient <= tmp_quotient(0);
1396
                remain <= tmp_remain(0);
1397
        end process;
1398
 
1399
end behave;
1400
 
1401
 
1402
--------------------------------------------------------------------------
1403
 
1404
library IEEE;
1405
use IEEE.std_logic_1164.all;
1406
use IEEE.std_logic_signed.all;
1407
use work.LPM_COMPONENTS.all;
1408
 
1409
entity LPM_ABS is
1410
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1411
                         LPM_TYPE: string := "LPM_ABS";
1412
                         LPM_HINT : string := "UNUSED");
1413
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1414
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
1415
                  OVERFLOW : out std_logic);
1416
end LPM_ABS;
1417
 
1418
architecture LPM_SYN of LPM_ABS is
1419
begin
1420
 
1421
        process(DATA)
1422
        begin
1423
                if (DATA = -2 ** (LPM_WIDTH-1)) then
1424
                        OVERFLOW <= '1';
1425
                        RESULT <= (OTHERS => 'X');
1426
                elsif DATA < 0 then
1427
                        RESULT <= 0 - DATA;
1428
                        OVERFLOW <= '0';
1429
                else
1430
                        RESULT <= DATA;
1431
                        OVERFLOW <= '0';
1432
                end if;
1433
        end process;
1434
 
1435
end LPM_SYN;
1436
 
1437
 
1438
--------------------------------------------------------------------------
1439
 
1440
library IEEE;
1441
use IEEE.std_logic_1164.all;
1442
use IEEE.std_logic_arith.all;
1443
use IEEE.std_logic_unsigned.all;
1444
use work.LPM_COMPONENTS.all;
1445
 
1446
entity LPM_COUNTER is
1447
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1448
                         LPM_MODULUS: natural := 0;
1449
                         LPM_DIRECTION : string := "UNUSED";
1450
                         LPM_AVALUE : string := "UNUSED";
1451
                         LPM_SVALUE : string := "UNUSED";
1452
                         LPM_PVALUE : string := "UNUSED";
1453
                         LPM_TYPE: string := "LPM_COUNTER";
1454
                         LPM_HINT : string := "UNUSED");
1455
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0):= (OTHERS => '0');
1456
                  CLOCK : in std_logic;
1457
                  CLK_EN : in std_logic := '1';
1458
                  CNT_EN : in std_logic := '1';
1459
                  UPDOWN : in std_logic := '1';
1460
                  SLOAD : in std_logic := '0';
1461
                  SSET : in std_logic := '0';
1462
                  SCLR : in std_logic := '0';
1463
                  ALOAD : in std_logic := '0';
1464
                  ASET : in std_logic := '0';
1465
                  ACLR : in std_logic := '0';
1466
          CIN : in std_logic := '1';
1467
          COUT : out std_logic := '0';
1468
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
1469
 
1470
end LPM_COUNTER;
1471
 
1472
architecture LPM_SYN of LPM_COUNTER is
1473
 
1474
signal COUNT : std_logic_vector(LPM_WIDTH downto 0);
1475
signal INIT : std_logic := '0';
1476
signal DIR : std_logic_vector(1 downto 0);
1477
 
1478
begin
1479
 
1480
    Direction: process (UPDOWN)
1481
    begin
1482
        if LPM_DIRECTION = "UP" then
1483
            DIR <= "01";    -- increment
1484
        elsif LPM_DIRECTION = "DOWN" then
1485
            DIR <= "00";    -- decrement
1486
        else
1487
            DIR(0) <= UPDOWN;
1488
            if UPDOWN = '0' or UPDOWN = '1' then
1489
                DIR(1) <= '0';  -- increment or decrement
1490
            else
1491
                DIR(1) <= '1';  -- unknown
1492
            end if;
1493
        end if;
1494
    end process Direction;
1495
 
1496
    Counter: process (CLOCK, ACLR, ASET, ALOAD, DATA, INIT)
1497
        variable IAVALUE, ISVALUE : integer;
1498
        variable IMODULUS : integer;
1499
        begin
1500
                if INIT = '0' then
1501
 
1502
            -- INITIALIZE TO PVALUE & SETUP VARIABLES --
1503
                        if LPM_PVALUE /= "UNUSED" then
1504
                                COUNT <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH+1);
1505
                        else
1506
                                COUNT <= (OTHERS => '0');
1507
                        end if;
1508
 
1509
                        if LPM_MODULUS = 0 then
1510
                            if LPM_WIDTH >= 32 then -- 32 bit integer limit
1511
                                IMODULUS := 0;
1512
                            else
1513
                                IMODULUS := 2 ** LPM_WIDTH ;
1514
                            end if;
1515
                        else
1516
                                IMODULUS := LPM_MODULUS;
1517
                        end if;
1518
 
1519
            -- CHECK PARAMETERS VALIDITY --
1520
            if (LPM_DIRECTION /= "UNUSED" and LPM_DIRECTION /= "UP" and LPM_DIRECTION /= "DOWN") then
1521
                ASSERT FALSE
1522
                REPORT "Illegal LPM_DIRECTION property value for LPM_COUNTER!"
1523
                SEVERITY ERROR;
1524
            end if;
1525
 
1526
                        INIT <= '1';
1527
                else
1528
                        if ACLR =  '1' then
1529
                                COUNT <= (OTHERS => '0');
1530
                        elsif ASET = '1' then
1531
                                if LPM_AVALUE = "UNUSED" then
1532
                                        COUNT <= (OTHERS => '1');
1533
                                else
1534
                                        IAVALUE := str_to_int(LPM_AVALUE);
1535
                                        COUNT <= conv_std_logic_vector(IAVALUE, LPM_WIDTH+1);
1536
                                end if;
1537
                        elsif ALOAD = '1' then
1538
                                COUNT(LPM_WIDTH-1 downto 0) <= DATA;
1539
                        elsif CLOCK'event and CLOCK = '1' then
1540
                                if CLK_EN = '1' then
1541
                                        if SCLR = '1' then
1542
                                                COUNT <= (OTHERS => '0');
1543
                                        elsif SSET = '1' then
1544
                                                if LPM_SVALUE = "UNUSED" then
1545
                                                        COUNT <= (OTHERS => '1');
1546
                                                else
1547
                                                        ISVALUE := str_to_int(LPM_SVALUE);
1548
                                                        COUNT <= conv_std_logic_vector(ISVALUE, LPM_WIDTH+1);
1549
                                                end if;
1550
                                        elsif SLOAD = '1' then
1551
                                                COUNT(LPM_WIDTH-1 downto 0) <= DATA;
1552
                                        elsif CNT_EN = '1' then
1553
                                                if IMODULUS = 1 then
1554
                                                        COUNT <= (OTHERS => '0');
1555
                        elsif CIN = '1' then
1556
                            if DIR(0) = '1' and DIR(1) = '0' then
1557
                                -- INCREMENT --
1558
                                if COUNT + 1 = IMODULUS then
1559
                                    COUNT <= conv_std_logic_vector(0, LPM_WIDTH+1);
1560
                                else
1561
                                    COUNT <= COUNT + 1;
1562
                                end if;
1563
                            elsif DIR(0) = '0' and DIR(1) = '0' then
1564
                                -- DECREMENT --
1565
                                if COUNT = 0 then
1566
                                    COUNT <= conv_std_logic_vector(IMODULUS-1, LPM_WIDTH+1);
1567
                                else
1568
                                    COUNT <= COUNT - 1;
1569
                                end if;
1570
                            end if;
1571
                                                end if;
1572
                                        end if;
1573
                                end if;
1574
                        end if;
1575
                end if;
1576
 
1577
                COUNT(LPM_WIDTH) <= '0';
1578
        end process Counter;
1579
 
1580
    CarryOut: process (COUNT, CIN, INIT, DIR)
1581
        variable IMODULUS : integer;
1582
        begin
1583
                if INIT = '1' then
1584
                        if LPM_MODULUS = 0 then
1585
                                IMODULUS := 2 ** LPM_WIDTH;
1586
                        else
1587
                                IMODULUS := LPM_MODULUS;
1588
                        end if;
1589
 
1590
            if (DIR(1) = '0') then
1591
                COUT <= '0';
1592
                if IMODULUS = 1 then
1593
                    COUT <= '1';
1594
                elsif CIN = '1' then
1595
                    if ((DIR(0) = '0' and COUNT = 0) or
1596
                        (DIR(0) = '1' and (COUNT = IMODULUS - 1 or
1597
                                           COUNT = 2**LPM_WIDTH-1) )) then
1598
                        COUT <= '1';
1599
                    end if;
1600
                end if;
1601
            end if;
1602
                end if;
1603
        end process CarryOut;
1604
 
1605
        Q <= COUNT(LPM_WIDTH-1 downto 0);
1606
 
1607
end LPM_SYN;
1608
 
1609
 
1610
--------------------------------------------------------------------------
1611
 
1612
library IEEE;
1613
use IEEE.std_logic_1164.all;
1614
use IEEE.std_logic_arith.all;
1615
use work.LPM_COMPONENTS.all;
1616
 
1617
entity LPM_LATCH is
1618
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1619
                         LPM_AVALUE : string := "UNUSED";
1620
                         LPM_PVALUE : string := "UNUSED";
1621
                         LPM_TYPE: string := "LPM_LATCH";
1622
                         LPM_HINT : string := "UNUSED");
1623
    port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
1624
                  GATE : in std_logic;
1625
                  ASET : in std_logic := '0';
1626
                  ACLR : in std_logic := '0';
1627
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
1628
end LPM_LATCH;
1629
 
1630
architecture LPM_SYN of LPM_LATCH is
1631
 
1632
signal INIT : std_logic := '0';
1633
 
1634
begin
1635
 
1636
        process (DATA, GATE, ACLR, ASET, INIT)
1637
        variable IAVALUE : integer;
1638
        begin
1639
 
1640
                -- INITIALIZE TO PVALUE --
1641
                if INIT = '0' then
1642
                        if LPM_PVALUE /= "UNUSED" then
1643
                                Q <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
1644
                        end if;
1645
                        INIT <= '1';
1646
                else
1647
                        if ACLR =  '1' then
1648
                                Q <= (OTHERS => '0');
1649
                        elsif ASET = '1' then
1650
                                if LPM_AVALUE = "UNUSED" then
1651
                                        Q <= (OTHERS => '1');
1652
                                else
1653
                                        IAVALUE := str_to_int(LPM_AVALUE);
1654
                                        Q <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
1655
                                end if;
1656
                        elsif GATE = '1' then
1657
                                Q <= DATA;
1658
                        end if;
1659
                end if;
1660
        end process;
1661
 
1662
end LPM_SYN;
1663
 
1664
 
1665
--------------------------------------------------------------------------
1666
 
1667
library IEEE;
1668
use IEEE.std_logic_1164.all;
1669
use IEEE.std_logic_arith.all;
1670
use work.LPM_COMPONENTS.all;
1671
 
1672
entity LPM_FF is
1673
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1674
                         LPM_AVALUE : string := "UNUSED";
1675
                         LPM_SVALUE : string := "UNUSED";
1676
                         LPM_PVALUE : string := "UNUSED";
1677
                         LPM_FFTYPE: string := "DFF";
1678
                         LPM_TYPE: string := "LPM_FF";
1679
                         LPM_HINT : string := "UNUSED");
1680
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1681
                  CLOCK : in std_logic;
1682
                  ENABLE : in std_logic := '1';
1683
                  SLOAD : in std_logic := '0';
1684
                  SCLR : in std_logic := '0';
1685
                  SSET : in std_logic := '0';
1686
                  ALOAD : in std_logic := '0';
1687
                  ACLR : in std_logic := '0';
1688
                  ASET : in std_logic := '0';
1689
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
1690
end LPM_FF;
1691
 
1692
architecture LPM_SYN of LPM_FF is
1693
 
1694
signal IQ : std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
1695
signal INIT : std_logic := '0';
1696
 
1697
begin
1698
 
1699
        process (DATA, CLOCK, ACLR, ASET, ALOAD, INIT)
1700
        variable IAVALUE, ISVALUE : integer;
1701
        begin
1702
                -- INITIALIZE TO PVALUE --
1703
                if INIT = '0' then
1704
                        if LPM_PVALUE /= "UNUSED" then
1705
                                IQ <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
1706
                        end if;
1707
            if LPM_FFTYPE /= "DFF" and LPM_FFTYPE /= "TFF" then
1708
                ASSERT FALSE
1709
                REPORT "Illegal LPM_FFTYPE property value for LPM_FF!"
1710
                SEVERITY ERROR;
1711
            end if;
1712
                        INIT <= '1';
1713
                elsif ACLR =  '1' then
1714
                        IQ <= (OTHERS => '0');
1715
                elsif ASET = '1' then
1716
                        if LPM_AVALUE = "UNUSED" then
1717
                                IQ <= (OTHERS => '1');
1718
                        else
1719
                                IAVALUE := str_to_int(LPM_AVALUE);
1720
                                IQ <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
1721
                        end if;
1722
                elsif ALOAD = '1' then
1723
                        if LPM_FFTYPE = "TFF" then
1724
                                IQ <= DATA;
1725
                        end if;
1726
        elsif CLOCK'event and CLOCK = '1' and NOW > 0 ns then
1727
                        if ENABLE = '1' then
1728
                                if SCLR = '1' then
1729
                                        IQ <= (OTHERS => '0');
1730
                                elsif SSET = '1' then
1731
                                        if LPM_SVALUE = "UNUSED" then
1732
                                                IQ <= (OTHERS => '1');
1733
                                        else
1734
                                                ISVALUE := str_to_int(LPM_SVALUE);
1735
                                                IQ <= conv_std_logic_vector(ISVALUE, LPM_WIDTH);
1736
                                        end if;
1737
                                elsif  SLOAD = '1' then
1738
                                        if LPM_FFTYPE = "TFF" then
1739
                                                IQ <= DATA;
1740
                                        end if;
1741
                                else
1742
                                        if LPM_FFTYPE = "TFF" then
1743
                                                for i in 0 to LPM_WIDTH-1 loop
1744
                                                        if DATA(i) = '1' then
1745
                                                                IQ(i) <= not IQ(i);
1746
                                                        end if;
1747
                                                end loop;
1748
                                        else
1749
                                                IQ <= DATA;
1750
                                        end if;
1751
                                end if;
1752
                        end if;
1753
                end if;
1754
        end process;
1755
 
1756
        Q <= IQ;
1757
 
1758
end LPM_SYN;
1759
 
1760
 
1761
--------------------------------------------------------------------------
1762
 
1763
library IEEE;
1764
use IEEE.std_logic_1164.all;
1765
use IEEE.std_logic_arith.all;
1766
use work.LPM_COMPONENTS.all;
1767
 
1768
entity LPM_SHIFTREG is
1769
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1770
                         LPM_AVALUE : string := "UNUSED";
1771
                         LPM_SVALUE : string := "UNUSED";
1772
                         LPM_PVALUE : string := "UNUSED";
1773
             LPM_DIRECTION: string := "UNUSED";
1774
                         LPM_TYPE: string := "L_SHIFTREG";
1775
                         LPM_HINT : string := "UNUSED");
1776
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
1777
                  CLOCK : in std_logic;
1778
                  ENABLE : in std_logic := '1';
1779
                  SHIFTIN : in std_logic := '1';
1780
                  LOAD : in std_logic := '0';
1781
                  SCLR : in std_logic := '0';
1782
                  SSET : in std_logic := '0';
1783
                  ACLR : in std_logic := '0';
1784
                  ASET : in std_logic := '0';
1785
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
1786
                  SHIFTOUT : out std_logic);
1787
end LPM_SHIFTREG;
1788
 
1789
architecture LPM_SYN of LPM_SHIFTREG is
1790
 
1791
signal i_q : std_logic_vector(LPM_WIDTH-1 downto 0) := (OTHERS => '0');
1792
signal INIT : std_logic := '0';
1793
signal i_shiftout_pos : integer := LPM_WIDTH-1;
1794
 
1795
begin
1796
 
1797
    process (CLOCK, ACLR, ASET, INIT)
1798
        variable IAVALUE, ISVALUE : integer;
1799
        begin
1800
                -- INITIALIZE TO PVALUE --
1801
                if INIT = '0' then
1802
                        if LPM_PVALUE /= "UNUSED" then
1803
                i_q <= conv_std_logic_vector(str_to_int(LPM_PVALUE), LPM_WIDTH);
1804
                        end if;
1805
            if LPM_DIRECTION = "LEFT" or LPM_DIRECTION = "UNUSED" then
1806
                i_shiftout_pos <= LPM_WIDTH-1;
1807
            elsif LPM_DIRECTION = "RIGHT" then
1808
                i_shiftout_pos <= 0;
1809
            else
1810
                ASSERT FALSE
1811
                REPORT "Illegal LPM_DIRECTION property value for LPM_SHIFTREG!"
1812
                SEVERITY ERROR;
1813
            end if;
1814
                        INIT <= '1';
1815
                elsif ACLR =  '1' then
1816
            i_q <= (OTHERS => '0');
1817
                elsif ASET = '1' then
1818
                        if LPM_AVALUE = "UNUSED" then
1819
                i_q <= (OTHERS => '1');
1820
                        else
1821
                                IAVALUE := str_to_int(LPM_AVALUE);
1822
                i_q <= conv_std_logic_vector(IAVALUE, LPM_WIDTH);
1823
                        end if;
1824
                elsif CLOCK'event and CLOCK = '1' then
1825
                        if ENABLE = '1' then
1826
                                if SCLR = '1' then
1827
                    i_q <= (OTHERS => '0');
1828
                                elsif SSET = '1' then
1829
                                        if LPM_SVALUE = "UNUSED" then
1830
                        i_q <= (OTHERS => '1');
1831
                                        else
1832
                                                ISVALUE := str_to_int(LPM_SVALUE);
1833
                        i_q <= conv_std_logic_vector(ISVALUE, LPM_WIDTH);
1834
                                        end if;
1835
                elsif LOAD = '1' then
1836
                    i_q <= DATA;
1837
                else
1838
                    if LPM_WIDTH < 2 then
1839
                        i_q(0) <= SHIFTIN;
1840
                    elsif LPM_DIRECTION = "LEFT" then
1841
                        i_q <= (i_q(LPM_WIDTH-2 downto 0) & SHIFTIN);
1842
                    else
1843
                        i_q <= (SHIFTIN & i_q(LPM_WIDTH-1 downto 1));
1844
                    end if;
1845
                                end if;
1846
                        end if;
1847
                end if;
1848
        end process;
1849
 
1850
    Q <= i_q;
1851
    SHIFTOUT <= i_q(i_shiftout_pos);
1852
 
1853
end LPM_SYN;
1854
 
1855
 
1856
---------------------------------------------------------------------------
1857
 
1858
library IEEE;
1859
use IEEE.std_logic_1164.all;
1860
use IEEE.std_logic_arith.all;
1861
use IEEE.std_logic_unsigned.all;
1862
use work.LPM_COMPONENTS.all;
1863
use std.textio.all;
1864
 
1865
entity LPM_RAM_DQ is
1866
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
1867
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
1868
                         LPM_NUMWORDS : natural := 0;
1869
                         LPM_INDATA : string := "REGISTERED";
1870
                         LPM_ADDRESS_CONTROL: string := "REGISTERED";
1871
                         LPM_OUTDATA : string := "REGISTERED";
1872
                         LPM_FILE : string := "UNUSED";
1873
                         LPM_TYPE : string := L_RAM_DQ;
1874
                         USE_EAB  : string := "OFF";
1875
                         INTENDED_DEVICE_FAMILY  : string := "UNUSED";
1876
                         LPM_HINT : string := "UNUSED");
1877
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
1878
                  ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
1879
                  INCLOCK : in std_logic := '0';
1880
                  OUTCLOCK : in std_logic := '0';
1881
                  WE : in std_logic;
1882
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
1883
 
1884
        function int_to_str( value : integer ) return string is
1885
        variable ivalue,index : integer;
1886
        variable digit : integer;
1887
        variable line_no: string(8 downto 1) := "        ";
1888
        begin
1889
                ivalue := value;
1890
                index := 1;
1891
                while (ivalue > 0) loop
1892
                        digit := ivalue MOD 10;
1893
                        ivalue := ivalue/10;
1894
                        case digit is
1895
                                when 0 =>
1896
                                        line_no(index) := '0';
1897
                                when 1 =>
1898
                                        line_no(index) := '1';
1899
                                when 2 =>
1900
                                        line_no(index) := '2';
1901
                                when 3 =>
1902
                                        line_no(index) := '3';
1903
                                when 4 =>
1904
                                        line_no(index) := '4';
1905
                                when 5 =>
1906
                                        line_no(index) := '5';
1907
                                when 6 =>
1908
                                        line_no(index) := '6';
1909
                                when 7 =>
1910
                                        line_no(index) := '7';
1911
                                when 8 =>
1912
                                        line_no(index) := '8';
1913
                                when 9 =>
1914
                                        line_no(index) := '9';
1915
                                when others =>
1916
                                        ASSERT FALSE
1917
                                        REPORT "Illegal number!"
1918
                                        SEVERITY ERROR;
1919
                        end case;
1920
                        index := index + 1;
1921
                end loop;
1922
                return line_no;
1923
        end;
1924
 
1925
        function hex_str_to_int( str : string ) return integer is
1926
        variable len : integer := str'length;
1927
        variable ivalue : integer := 0;
1928
        variable digit : integer;
1929
        begin
1930
                for i in len downto 1 loop
1931
                        case str(i) is
1932
                                when '0' =>
1933
                                        digit := 0;
1934
                                when '1' =>
1935
                                        digit := 1;
1936
                                when '2' =>
1937
                                        digit := 2;
1938
                                when '3' =>
1939
                                        digit := 3;
1940
                                when '4' =>
1941
                                        digit := 4;
1942
                                when '5' =>
1943
                                        digit := 5;
1944
                                when '6' =>
1945
                                        digit := 6;
1946
                                when '7' =>
1947
                                        digit := 7;
1948
                                when '8' =>
1949
                                        digit := 8;
1950
                                when '9' =>
1951
                                        digit := 9;
1952
                                when 'A' =>
1953
                                        digit := 10;
1954
                                when 'a' =>
1955
                                        digit := 10;
1956
                                when 'B' =>
1957
                                        digit := 11;
1958
                                when 'b' =>
1959
                                        digit := 11;
1960
                                when 'C' =>
1961
                                        digit := 12;
1962
                                when 'c' =>
1963
                                        digit := 12;
1964
                                when 'D' =>
1965
                                        digit := 13;
1966
                                when 'd' =>
1967
                                        digit := 13;
1968
                                when 'E' =>
1969
                                        digit := 14;
1970
                                when 'e' =>
1971
                                        digit := 14;
1972
                                when 'F' =>
1973
                                        digit := 15;
1974
                                when 'f' =>
1975
                                        digit := 15;
1976
                                when others =>
1977
                                        ASSERT FALSE
1978
                                        REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
1979
                                        SEVERITY ERROR;
1980
                        end case;
1981
                        ivalue := ivalue * 16 + digit;
1982
                end loop;
1983
                return ivalue;
1984
        end;
1985
 
1986
        procedure Shrink_line(L : inout LINE; pos : in integer) is
1987
        subtype nstring is string(1 to pos);
1988
        variable stmp : nstring;
1989
        begin
1990
                if pos >= 1 then
1991
                        read(l, stmp);
1992
                end if;
1993
        end;
1994
 
1995
end LPM_RAM_DQ;
1996
 
1997
architecture LPM_SYN of lpm_ram_dq is
1998
 
1999
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2000
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2001
 
2002
signal data_tmp : std_logic_vector(lpm_width-1 downto 0);
2003
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2004
signal q_tmp : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2005
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2006
signal address_tmp : std_logic_vector(lpm_widthad-1 downto 0);
2007
signal address_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
2008
signal we_tmp : std_logic;
2009
signal we_reg : std_logic := '0';
2010
 
2011
begin
2012
 
2013
        sync: process(data, data_reg, address, address_reg,
2014
                                  we, we_reg, q_tmp, q_reg)
2015
        begin
2016
                if (lpm_address_control = "REGISTERED") then
2017
                        address_tmp <= address_reg;
2018
                        we_tmp <= we_reg;
2019
        elsif (lpm_address_control = "UNREGISTERED") then
2020
                        address_tmp <= address;
2021
                        we_tmp <= we;
2022
        else
2023
            ASSERT FALSE
2024
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_DQ!"
2025
            SEVERITY ERROR;
2026
                end if;
2027
                if (lpm_indata = "REGISTERED") then
2028
                        data_tmp <= data_reg;
2029
        elsif (lpm_indata = "UNREGISTERED") then
2030
                        data_tmp <= data;
2031
        else
2032
            ASSERT FALSE
2033
            REPORT "Illegal LPM_INDATA property value for LPM_RAM_DQ!"
2034
            SEVERITY ERROR;
2035
                end if;
2036
                if (lpm_outdata = "REGISTERED") then
2037
                        q <= q_reg;
2038
        elsif (lpm_outdata = "UNREGISTERED") then
2039
                        q <= q_tmp;
2040
        else
2041
            ASSERT FALSE
2042
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_DQ!"
2043
            SEVERITY ERROR;
2044
                end if;
2045
        end process;
2046
 
2047
        input_reg: process (inclock)
2048
        begin
2049
                if inclock'event and inclock = '1' then
2050
                        data_reg <= data;
2051
                        address_reg <= address;
2052
                        we_reg <= we;
2053
                end if;
2054
        end process;
2055
 
2056
        output_reg: process (outclock)
2057
        begin
2058
                if outclock'event and outclock = '1' then
2059
                        q_reg <= q_tmp;
2060
                end if;
2061
        end process;
2062
 
2063
        memory: process(data_tmp, we_tmp, address_tmp, inclock)
2064
        variable mem_data : lpm_memory;
2065
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
2066
        variable mem_init: boolean := false;
2067
        variable i,j,k,n,m,lineno: integer := 0;
2068
        variable buf: line ;
2069
        variable booval: boolean ;
2070
        FILE unused_file: TEXT IS OUT "UNUSED";
2071
        FILE mem_data_file: TEXT IS IN LPM_FILE;
2072
        variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
2073
        variable startadd: string(4 downto 1);
2074
        variable ibase: integer := 0;
2075
        variable ibyte: integer := 0;
2076
        variable istartadd: integer := 0;
2077
        variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
2078
        begin
2079
                -- INITIALIZE --
2080
                if NOT(mem_init) then
2081
                        -- INITIALIZE TO 0 --
2082
                        for i in mem_data'LOW to mem_data'HIGH loop
2083
                                mem_data(i) := (OTHERS => '0');
2084
                        end loop;
2085
 
2086
                        if (LPM_FILE = "UNUSED") then
2087
                                ASSERT FALSE
2088
                                REPORT "Initialization file not found!"
2089
                                SEVERITY WARNING;
2090
                        else
2091
                                WHILE NOT ENDFILE(mem_data_file) loop
2092
                                        booval := true;
2093
                                        READLINE(mem_data_file, buf);
2094
                                        lineno := lineno + 1;
2095
                                        check_sum_vec := (OTHERS => '0');
2096
                                        if (buf(buf'LOW) = ':') then
2097
                                                i := 1;
2098
                                                shrink_line(buf, i);
2099
                                                READ(L=>buf, VALUE=>byte, good=>booval);
2100
                                                if not (booval) then
2101
                                                        ASSERT FALSE
2102
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
2103
                                                        SEVERITY ERROR;
2104
                                                end if;
2105
                                                ibyte := hex_str_to_int(byte);
2106
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
2107
                                                READ(L=>buf, VALUE=>startadd, good=>booval);
2108
                                                if not (booval) then
2109
                                                        ASSERT FALSE
2110
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2111
                                                        SEVERITY ERROR;
2112
                                                end if;
2113
                                                istartadd := hex_str_to_int(startadd);
2114
                                                addr(2) := startadd(4);
2115
                                                addr(1) := startadd(3);
2116
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2117
                                                addr(2) := startadd(2);
2118
                                                addr(1) := startadd(1);
2119
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2120
                                                READ(L=>buf, VALUE=>rec_type, good=>booval);
2121
                                                if not (booval) then
2122
                                                        ASSERT FALSE
2123
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2124
                                                        SEVERITY ERROR;
2125
                                                end if;
2126
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
2127
                                        else
2128
                                                ASSERT FALSE
2129
                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2130
                                                SEVERITY ERROR;
2131
                                        end if;
2132
                                        case rec_type is
2133
                                                when "00"=>     -- Data record
2134
                                                        i := 0;
2135
                                                        k := lpm_width / 8;
2136
                                                        if ((lpm_width MOD 8) /= 0) then
2137
                                                                k := k + 1;
2138
                                                        end if;
2139
                                                        -- k = no. of bytes per CAM entry.
2140
                                                        while (i < ibyte) loop
2141
                                                                mem_data_word := (others => '0');
2142
                                                                n := (k - 1)*8;
2143
                                                                m := lpm_width - 1;
2144
                                                                for j in 1 to k loop
2145
                                                                        READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
2146
                                                                        if not (booval) then
2147
                                                                                ASSERT FALSE
2148
                                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2149
                                                                                SEVERITY ERROR;
2150
                                                                        end if;
2151
                                                                        check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
2152
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
2153
                                                                        m := n - 1;
2154
                                                                        n := n - 8;
2155
                                                                end loop;
2156
                                                                i := i + k;
2157
                                                                mem_data(ibase + istartadd) := mem_data_word;
2158
                                                                istartadd := istartadd + 1;
2159
                                                        end loop;
2160
                                                when "01"=>
2161
                                                        exit;
2162
                                                when "02"=>
2163
                                                        ibase := 0;
2164
                                                        if (ibyte /= 2) then
2165
                                                                ASSERT FALSE
2166
                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
2167
                                                                SEVERITY ERROR;
2168
                                                        end if;
2169
                                                        for i in 0 to (ibyte-1) loop
2170
                                                                READ(L=>buf, VALUE=>base,good=>booval);
2171
                                                                ibase := ibase * 256 + hex_str_to_int(base);
2172
                                                                if not (booval) then
2173
                                                                        ASSERT FALSE
2174
                                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2175
                                                                        SEVERITY ERROR;
2176
                                                                end if;
2177
                                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
2178
                                                        end loop;
2179
                                                        ibase := ibase * 16;
2180
                                                when OTHERS =>
2181
                                                        ASSERT FALSE
2182
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
2183
                                                        SEVERITY ERROR;
2184
                                        end case;
2185
                                        READ(L=>buf, VALUE=>checksum,good=>booval);
2186
                                        if not (booval) then
2187
                                                ASSERT FALSE
2188
                                                REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
2189
                                                SEVERITY ERROR;
2190
                                        end if;
2191
 
2192
                                        check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
2193
                                        check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
2194
 
2195
                                        if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
2196
                                                ASSERT FALSE
2197
                                                REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
2198
                                                SEVERITY ERROR;
2199
                                        end if;
2200
                                end loop;
2201
                        end if;
2202
                        mem_init := TRUE;
2203
                end if;
2204
 
2205
                -- MEMORY FUNCTION --
2206
                if we_tmp = '1' then
2207
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_address_control = "REGISTERED")) then
2208
                            if (inclock = '0') then
2209
                                mem_data (conv_integer(address_tmp)) := data_tmp ;
2210
                            end if;
2211
                        else
2212
                            mem_data (conv_integer(address_tmp)) := data_tmp;
2213
                        end if;
2214
                end if;
2215
                q_tmp <= mem_data(conv_integer(address_tmp));
2216
        end process;
2217
 
2218
end LPM_SYN;
2219
 
2220
 
2221
---------------------------------------------------------------------------
2222
 
2223
library IEEE;
2224
use IEEE.std_logic_1164.all;
2225
use IEEE.std_logic_arith.all;
2226
use IEEE.std_logic_unsigned.all;
2227
use work.LPM_COMPONENTS.all;
2228
use std.textio.all;
2229
 
2230
entity LPM_RAM_DP is
2231
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
2232
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
2233
                         LPM_NUMWORDS : natural := 0;
2234
                         LPM_INDATA : string := "REGISTERED";
2235
                         LPM_OUTDATA : string := "REGISTERED";
2236
                         LPM_RDADDRESS_CONTROL : string := "REGISTERED";
2237
                         LPM_WRADDRESS_CONTROL : string := "REGISTERED";
2238
                         LPM_FILE : string := "UNUSED";
2239
                         LPM_TYPE : string := "LPM_RAM_DP";
2240
                         USE_EAB  : string := "OFF";
2241
                         INTENDED_DEVICE_FAMILY  : string := "UNUSED";
2242
                         RDEN_USED  : string := "TRUE";
2243
                         LPM_HINT : string := "UNUSED");
2244
        port (RDCLOCK : in std_logic := '0';
2245
                  RDCLKEN : in std_logic := '1';
2246
                  RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
2247
                  RDEN : in std_logic := '1';
2248
                  DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
2249
                  WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
2250
                  WREN : in std_logic;
2251
                  WRCLOCK : in std_logic := '0';
2252
                  WRCLKEN : in std_logic := '1';
2253
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
2254
 
2255
        function int_to_str( value : integer ) return string is
2256
        variable ivalue,index : integer;
2257
        variable digit : integer;
2258
        variable line_no: string(8 downto 1) := "        ";
2259
        begin
2260
                ivalue := value;
2261
                index := 1;
2262
                while (ivalue > 0) loop
2263
                        digit := ivalue MOD 10;
2264
                        ivalue := ivalue/10;
2265
                        case digit is
2266
                                when 0 =>
2267
                                        line_no(index) := '0';
2268
                                when 1 =>
2269
                                        line_no(index) := '1';
2270
                                when 2 =>
2271
                                        line_no(index) := '2';
2272
                                when 3 =>
2273
                                        line_no(index) := '3';
2274
                                when 4 =>
2275
                                        line_no(index) := '4';
2276
                                when 5 =>
2277
                                        line_no(index) := '5';
2278
                                when 6 =>
2279
                                        line_no(index) := '6';
2280
                                when 7 =>
2281
                                        line_no(index) := '7';
2282
                                when 8 =>
2283
                                        line_no(index) := '8';
2284
                                when 9 =>
2285
                                        line_no(index) := '9';
2286
                                when others =>
2287
                                        ASSERT FALSE
2288
                                        REPORT "Illegal number!"
2289
                                        SEVERITY ERROR;
2290
                        end case;
2291
                        index := index + 1;
2292
                end loop;
2293
                return line_no;
2294
        end;
2295
 
2296
        function hex_str_to_int( str : string ) return integer is
2297
        variable len : integer := str'length;
2298
        variable ivalue : integer := 0;
2299
        variable digit : integer;
2300
        begin
2301
                for i in len downto 1 loop
2302
                        case str(i) is
2303
                                when '0' =>
2304
                                        digit := 0;
2305
                                when '1' =>
2306
                                        digit := 1;
2307
                                when '2' =>
2308
                                        digit := 2;
2309
                                when '3' =>
2310
                                        digit := 3;
2311
                                when '4' =>
2312
                                        digit := 4;
2313
                                when '5' =>
2314
                                        digit := 5;
2315
                                when '6' =>
2316
                                        digit := 6;
2317
                                when '7' =>
2318
                                        digit := 7;
2319
                                when '8' =>
2320
                                        digit := 8;
2321
                                when '9' =>
2322
                                        digit := 9;
2323
                                when 'A' =>
2324
                                        digit := 10;
2325
                                when 'a' =>
2326
                                        digit := 10;
2327
                                when 'B' =>
2328
                                        digit := 11;
2329
                                when 'b' =>
2330
                                        digit := 11;
2331
                                when 'C' =>
2332
                                        digit := 12;
2333
                                when 'c' =>
2334
                                        digit := 12;
2335
                                when 'D' =>
2336
                                        digit := 13;
2337
                                when 'd' =>
2338
                                        digit := 13;
2339
                                when 'E' =>
2340
                                        digit := 14;
2341
                                when 'e' =>
2342
                                        digit := 14;
2343
                                when 'F' =>
2344
                                        digit := 15;
2345
                                when 'f' =>
2346
                                        digit := 15;
2347
                                when others =>
2348
                                        ASSERT FALSE
2349
                                        REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
2350
                                        SEVERITY ERROR;
2351
                        end case;
2352
                        ivalue := ivalue * 16 + digit;
2353
                end loop;
2354
                return ivalue;
2355
        end;
2356
 
2357
        procedure Shrink_line(L : inout LINE; pos : in integer) is
2358
        subtype nstring is string(1 to pos);
2359
        variable stmp : nstring;
2360
        begin
2361
                if pos >= 1 then
2362
                        read(l, stmp);
2363
                end if;
2364
        end;
2365
 
2366
end LPM_RAM_DP;
2367
 
2368
architecture LPM_SYN of lpm_ram_dp is
2369
 
2370
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2371
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2372
 
2373
signal data_tmp : std_logic_vector(lpm_width-1 downto 0);
2374
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2375
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2376
signal q_tmp : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2377
signal rdaddress_tmp : std_logic_vector(lpm_widthad-1 downto 0);
2378
signal rdaddress_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
2379
signal wraddress_tmp : std_logic_vector(lpm_widthad-1 downto 0);
2380
signal wraddress_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
2381
signal wren_tmp : std_logic;
2382
signal wren_reg : std_logic := '0';
2383
signal rden_tmp : std_logic;
2384
signal rden_reg : std_logic := '0';
2385
 
2386
begin
2387
        rden_tmp <= '1' when rden_used = "FALSE" else rden when lpm_rdaddress_control = "UNREGISTERED" else rden_reg;
2388
        rdaddress_tmp <= rdaddress when lpm_rdaddress_control = "UNREGISTERED" else rdaddress_reg;
2389
        wren_tmp <= wren when lpm_wraddress_control = "UNREGISTERED" else wren_reg;
2390
        wraddress_tmp <= wraddress when lpm_wraddress_control = "UNREGISTERED" else wraddress_reg;
2391
        data_tmp <= data when lpm_indata = "UNREGISTERED" else data_reg;
2392
        q <= q_tmp when lpm_outdata = "UNREGISTERED" else q_reg;
2393
 
2394
        input_reg: process (wrclock)
2395
        begin
2396
                if wrclock'event and wrclock = '1' and wrclken = '1' then
2397
                        data_reg <= data;
2398
                        wraddress_reg <= wraddress;
2399
                        wren_reg <= wren;
2400
                end if;
2401
        end process;
2402
 
2403
        output_reg: process (rdclock)
2404
        begin
2405
                if rdclock'event and rdclock = '1' and rdclken = '1' then
2406
                        rdaddress_reg <= rdaddress;
2407
                        rden_reg <= rden;
2408
                        q_reg <= q_tmp;
2409
                end if;
2410
        end process;
2411
 
2412
        memory: process(data_tmp, wren_tmp, rdaddress_tmp, wraddress_tmp, rden_tmp, wrclock)
2413
        variable mem_data : lpm_memory;
2414
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
2415
        variable mem_init: boolean := false;
2416
        variable i,j,k,n,m,lineno: integer := 0;
2417
        variable buf: line ;
2418
        variable booval: boolean ;
2419
        FILE unused_file: TEXT IS OUT "UNUSED";
2420
        FILE mem_data_file: TEXT IS IN LPM_FILE;
2421
        variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
2422
        variable startadd: string(4 downto 1);
2423
        variable ibase: integer := 0;
2424
        variable ibyte: integer := 0;
2425
        variable istartadd: integer := 0;
2426
        variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
2427
        begin
2428
                -- INITIALIZE --
2429
                if NOT(mem_init) then
2430
                        -- INITIALIZE TO 0 --
2431
                        for i in mem_data'LOW to mem_data'HIGH loop
2432
                                mem_data(i) := (OTHERS => '0');
2433
                        end loop;
2434
 
2435
                        if ((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) then
2436
                            if intended_device_family = "APEX20K" then
2437
                                q_tmp <= (others => '0');
2438
                            else
2439
                                q_tmp <= (others => '1');
2440
                            end if;
2441
                        end if;
2442
 
2443
                        if (LPM_FILE = "UNUSED") then
2444
                                ASSERT FALSE
2445
                                REPORT "Initialization file not found!"
2446
                                SEVERITY WARNING;
2447
                        else
2448
                                WHILE NOT ENDFILE(mem_data_file) loop
2449
                                        booval := true;
2450
                                        READLINE(mem_data_file, buf);
2451
                                        lineno := lineno + 1;
2452
                                        check_sum_vec := (OTHERS => '0');
2453
                                        if (buf(buf'LOW) = ':') then
2454
                                                i := 1;
2455
                                                shrink_line(buf, i);
2456
                                                READ(L=>buf, VALUE=>byte, good=>booval);
2457
                                                if not (booval) then
2458
                                                        ASSERT FALSE
2459
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
2460
                                                        SEVERITY ERROR;
2461
                                                end if;
2462
                                                ibyte := hex_str_to_int(byte);
2463
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
2464
                                                READ(L=>buf, VALUE=>startadd, good=>booval);
2465
                                                if not (booval) then
2466
                                                        ASSERT FALSE
2467
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2468
                                                        SEVERITY ERROR;
2469
                                                end if;
2470
                                                istartadd := hex_str_to_int(startadd);
2471
                                                addr(2) := startadd(4);
2472
                                                addr(1) := startadd(3);
2473
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2474
                                                addr(2) := startadd(2);
2475
                                                addr(1) := startadd(1);
2476
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2477
                                                READ(L=>buf, VALUE=>rec_type, good=>booval);
2478
                                                if not (booval) then
2479
                                                        ASSERT FALSE
2480
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2481
                                                        SEVERITY ERROR;
2482
                                                end if;
2483
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
2484
                                        else
2485
                                                ASSERT FALSE
2486
                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2487
                                                SEVERITY ERROR;
2488
                                        end if;
2489
                                        case rec_type is
2490
                                                when "00"=>     -- Data record
2491
                                                        i := 0;
2492
                                                        k := lpm_width / 8;
2493
                                                        if ((lpm_width MOD 8) /= 0) then
2494
                                                                k := k + 1;
2495
                                                        end if;
2496
                                                        -- k = no. of bytes per CAM entry.
2497
                                                        while (i < ibyte) loop
2498
                                                                mem_data_word := (others => '0');
2499
                                                                n := (k - 1)*8;
2500
                                                                m := lpm_width - 1;
2501
                                                                for j in 1 to k loop
2502
                                                                        READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
2503
                                                                        if not (booval) then
2504
                                                                                ASSERT FALSE
2505
                                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2506
                                                                                SEVERITY ERROR;
2507
                                                                        end if;
2508
                                                                        check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
2509
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
2510
                                                                        m := n - 1;
2511
                                                                        n := n - 8;
2512
                                                                end loop;
2513
                                                                i := i + k;
2514
                                                                mem_data(ibase + istartadd) := mem_data_word;
2515
                                                                istartadd := istartadd + 1;
2516
                                                        end loop;
2517
                                                when "01"=>
2518
                                                        exit;
2519
                                                when "02"=>
2520
                                                        ibase := 0;
2521
                                                        if (ibyte /= 2) then
2522
                                                                ASSERT FALSE
2523
                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
2524
                                                                SEVERITY ERROR;
2525
                                                        end if;
2526
                                                        for i in 0 to (ibyte-1) loop
2527
                                                                READ(L=>buf, VALUE=>base,good=>booval);
2528
                                                                ibase := ibase * 256 + hex_str_to_int(base);
2529
                                                                if not (booval) then
2530
                                                                        ASSERT FALSE
2531
                                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2532
                                                                        SEVERITY ERROR;
2533
                                                                end if;
2534
                                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
2535
                                                        end loop;
2536
                                                        ibase := ibase * 16;
2537
                                                when OTHERS =>
2538
                                                        ASSERT FALSE
2539
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
2540
                                                        SEVERITY ERROR;
2541
                                        end case;
2542
                                        READ(L=>buf, VALUE=>checksum,good=>booval);
2543
                                        if not (booval) then
2544
                                                ASSERT FALSE
2545
                                                REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
2546
                                                SEVERITY ERROR;
2547
                                        end if;
2548
 
2549
                                        check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
2550
                                        check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
2551
 
2552
                                        if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
2553
                                                ASSERT FALSE
2554
                                                REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
2555
                                                SEVERITY ERROR;
2556
                                        end if;
2557
                                end loop;
2558
                        end if;
2559
                        mem_init := TRUE;
2560
                end if;
2561
 
2562
                -- MEMORY FUNCTION --
2563
                if wren_tmp = '1' then
2564
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_wraddress_control = "REGISTERED")) then
2565
                            if (wrclock = '0') then
2566
                                mem_data (conv_integer(wraddress_tmp)) := data_tmp ;
2567
                            end if;
2568
                        else
2569
                            mem_data (conv_integer(wraddress_tmp)) := data_tmp ;
2570
                        end if;
2571
                end if;
2572
                if (rden_tmp = '1') or (rden_used = "FALSE") then
2573
                        q_tmp <= mem_data(conv_integer(rdaddress_tmp));
2574
                else if ((intended_device_family = "APEX20K") and (use_eab = "ON")) then
2575
                        q_tmp <= (OTHERS => '0');
2576
                     end if;
2577
                end if;
2578
        end process;
2579
 
2580
end LPM_SYN;
2581
 
2582
 
2583
---------------------------------------------------------------------------
2584
 
2585
library IEEE;
2586
use IEEE.std_logic_1164.all;
2587
use IEEE.std_logic_arith.all;
2588
use IEEE.std_logic_unsigned.all;
2589
use work.LPM_COMPONENTS.all;
2590
use std.textio.all;
2591
 
2592
entity LPM_RAM_IO is
2593
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
2594
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
2595
                         LPM_NUMWORDS : natural := 0;
2596
                         LPM_INDATA : string := "REGISTERED";
2597
                         LPM_ADDRESS_CONTROL : string := "REGISTERED";
2598
                         LPM_OUTDATA : string := "REGISTERED";
2599
                         LPM_FILE : string := "UNUSED";
2600
                         LPM_TYPE : string := "LPM_RAM_IO";
2601
                         USE_EAB  : string := "OFF";
2602
                         INTENDED_DEVICE_FAMILY  : string := "UNUSED";
2603
                         LPM_HINT : string := "UNUSED");
2604
        port (ADDRESS : in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0);
2605
                  INCLOCK : in STD_LOGIC := '0';
2606
                  OUTCLOCK : in STD_LOGIC := '0';
2607
                  MEMENAB : in STD_LOGIC := '1';
2608
                  OUTENAB : in STD_LOGIC := 'Z';
2609
                  WE : in STD_LOGIC := 'Z';
2610
                  DIO : inout STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0));
2611
 
2612
        function int_to_str( value : integer ) return string is
2613
        variable ivalue,index : integer;
2614
        variable digit : integer;
2615
        variable line_no: string(8 downto 1) := "        ";
2616
        begin
2617
                ivalue := value;
2618
                index := 1;
2619
                while (ivalue > 0 ) loop
2620
                        digit := ivalue MOD 10;
2621
                        ivalue := ivalue/10;
2622
                        case digit is
2623
                                when 0 =>
2624
                                        line_no(index) := '0';
2625
                                when 1 =>
2626
                                        line_no(index) := '1';
2627
                                when 2 =>
2628
                                        line_no(index) := '2';
2629
                                when 3 =>
2630
                                        line_no(index) := '3';
2631
                                when 4 =>
2632
                                        line_no(index) := '4';
2633
                                when 5 =>
2634
                                        line_no(index) := '5';
2635
                                when 6 =>
2636
                                        line_no(index) := '6';
2637
                                when 7 =>
2638
                                        line_no(index) := '7';
2639
                                when 8 =>
2640
                                        line_no(index) := '8';
2641
                                when 9 =>
2642
                                        line_no(index) := '9';
2643
                                when others =>
2644
                                        ASSERT FALSE
2645
                                        REPORT "Illegal number!"
2646
                                        SEVERITY ERROR;
2647
                        end case;
2648
                        index := index + 1;
2649
                end loop;
2650
                return line_no;
2651
        end;
2652
 
2653
        function hex_str_to_int( str : string ) return integer is
2654
        variable len : integer := str'length;
2655
        variable ivalue : integer := 0;
2656
        variable digit : integer;
2657
        begin
2658
                for i in len downto 1 loop
2659
                        case str(i) is
2660
                                when '0' =>
2661
                                        digit := 0;
2662
                                when '1' =>
2663
                                        digit := 1;
2664
                                when '2' =>
2665
                                        digit := 2;
2666
                                when '3' =>
2667
                                        digit := 3;
2668
                                when '4' =>
2669
                                        digit := 4;
2670
                                when '5' =>
2671
                                        digit := 5;
2672
                                when '6' =>
2673
                                        digit := 6;
2674
                                when '7' =>
2675
                                        digit := 7;
2676
                                when '8' =>
2677
                                        digit := 8;
2678
                                when '9' =>
2679
                                        digit := 9;
2680
                                when 'A' =>
2681
                                        digit := 10;
2682
                                when 'a' =>
2683
                                        digit := 10;
2684
                                when 'B' =>
2685
                                        digit := 11;
2686
                                when 'b' =>
2687
                                        digit := 11;
2688
                                when 'C' =>
2689
                                        digit := 12;
2690
                                when 'c' =>
2691
                                        digit := 12;
2692
                                when 'D' =>
2693
                                        digit := 13;
2694
                                when 'd' =>
2695
                                        digit := 13;
2696
                                when 'E' =>
2697
                                        digit := 14;
2698
                                when 'e' =>
2699
                                        digit := 14;
2700
                                when 'F' =>
2701
                                        digit := 15;
2702
                                when 'f' =>
2703
                                        digit := 15;
2704
                                when others =>
2705
                                        ASSERT FALSE
2706
                                        REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
2707
                                        SEVERITY ERROR;
2708
                        end case;
2709
                        ivalue := ivalue * 16 + digit;
2710
                end loop;
2711
                return ivalue;
2712
        end;
2713
 
2714
        procedure Shrink_line(L : inout LINE; pos : in integer) is
2715
        subtype nstring is string(1 to pos);
2716
        variable stmp : nstring;
2717
        begin
2718
                if pos >= 1 then
2719
                        read(l, stmp);
2720
                end if;
2721
        end;
2722
 
2723
end LPM_RAM_IO;
2724
 
2725
architecture LPM_SYN of lpm_ram_io is
2726
 
2727
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2728
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
2729
 
2730
signal data_tmp, di, do : std_logic_vector(lpm_width-1 downto 0);
2731
signal data_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2732
signal q_tmp, q : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2733
signal q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0');
2734
signal address_tmp : std_logic_vector(lpm_widthad-1 downto 0);
2735
signal address_reg : std_logic_vector(lpm_widthad-1 downto 0) := (others => '0');
2736
signal we_tmp : std_logic;
2737
signal we_reg : std_logic := '0';
2738
signal memenab_tmp : std_logic;
2739
signal memenab_reg : std_logic := '0';
2740
 
2741
signal outenab_used : std_logic;
2742
 
2743
-- provided for MP2 compliance
2744
signal we_used : std_logic;
2745
 
2746
begin
2747
        sync: process(di, data_reg, address, address_reg, memenab, memenab_reg,
2748
                                  we,we_reg, q_tmp, q_reg)
2749
        begin
2750
                if (lpm_address_control = "REGISTERED") then
2751
                        address_tmp <= address_reg;
2752
                        we_tmp <= we_reg;
2753
                        memenab_tmp <= memenab_reg;
2754
        elsif (lpm_address_control = "UNREGISTERED") then
2755
                        address_tmp <= address;
2756
                        we_tmp <= we;
2757
                        memenab_tmp <= memenab;
2758
        else
2759
            ASSERT FALSE
2760
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_IO!"
2761
            SEVERITY ERROR;
2762
                end if;
2763
                if (lpm_indata = "REGISTERED") then
2764
                        data_tmp <= data_reg;
2765
        elsif (lpm_indata = "UNREGISTERED") then
2766
                        data_tmp <= di;
2767
        else
2768
            ASSERT FALSE
2769
            REPORT "Illegal LPM_INDATA property value for LPM_RAM_IO!"
2770
            SEVERITY ERROR;
2771
                end if;
2772
                if (lpm_outdata = "REGISTERED") then
2773
                        q <= q_reg;
2774
        elsif (lpm_outdata = "UNREGISTERED") then
2775
                        q <= q_tmp;
2776
        else
2777
            ASSERT FALSE
2778
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_IO!"
2779
            SEVERITY ERROR;
2780
                end if;
2781
        end process;
2782
 
2783
        input_reg: process (inclock)
2784
        begin
2785
                if inclock'event and inclock = '1' then
2786
                        data_reg <= di;
2787
                        address_reg <= address;
2788
                        we_reg <= we;
2789
                        memenab_reg <= memenab;
2790
                end if;
2791
        end process;
2792
 
2793
        output_reg: process (outclock)
2794
        begin
2795
                if outclock'event and outclock = '1' then
2796
                        q_reg <= q_tmp;
2797
                end if;
2798
        end process;
2799
 
2800
        memory: process(data_tmp, we_tmp, memenab_tmp, outenab, address_tmp, inclock)
2801
        variable mem_data : lpm_memory;
2802
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
2803
        variable mem_init: boolean := false;
2804
        variable i,j,k,n,m,lineno: integer := 0;
2805
        variable buf: line ;
2806
        variable booval: boolean ;
2807
        FILE unused_file: TEXT IS OUT "UNUSED";
2808
        FILE mem_data_file: TEXT IS IN LPM_FILE;
2809
        variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
2810
        variable startadd: string(4 downto 1);
2811
        variable ibase: integer := 0;
2812
        variable ibyte: integer := 0;
2813
        variable istartadd: integer := 0;
2814
        variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
2815
        begin
2816
                -- INITIALIZE --
2817
                if NOT(mem_init) then
2818
                        -- INITIALIZE TO 0 --
2819
                        for i in mem_data'LOW to mem_data'HIGH loop
2820
                                mem_data(i) := (OTHERS => '0');
2821
                        end loop;
2822
 
2823
                        if (outenab = 'Z' and we = 'Z') then
2824
                                ASSERT FALSE
2825
                                REPORT "One of OutEnab or WE must be used!"
2826
                                SEVERITY ERROR;
2827
                        end if;
2828
 
2829
                        -- In reality, both are needed in current TDF implementation
2830
                        if (outenab /= 'Z' and we /= 'Z') then
2831
                                ASSERT FALSE
2832
                                REPORT "Only one of OutEnab or WE should be used!"
2833
                                -- Change severity to ERROR for full LPM 220 compliance
2834
                                SEVERITY WARNING;
2835
                        end if;
2836
 
2837
                        -- Comment out the following 5 lines for full LPM 220 compliance
2838
                        if (we = 'Z') then
2839
                                ASSERT FALSE
2840
                                REPORT "WE is required!"
2841
                                SEVERITY WARNING;
2842
                        end if;
2843
 
2844
                        if (outenab = 'Z') then
2845
                                outenab_used <= '0';
2846
                                we_used <= '1';
2847
                        else
2848
                                outenab_used <= '1';
2849
                                we_used <= '0';
2850
                        end if;
2851
 
2852
                        -- Comment out the following 5 lines for full LPM 220 compliance
2853
                        if (we = 'Z') then
2854
                                we_used <= '0';
2855
                        else
2856
                                we_used <= '1';
2857
                        end if;
2858
 
2859
                        if (LPM_FILE = "UNUSED") then
2860
                                ASSERT FALSE
2861
                                REPORT "Initialization file not found!"
2862
                                SEVERITY WARNING;
2863
                        else
2864
                                WHILE NOT ENDFILE(mem_data_file) loop
2865
                                        booval := true;
2866
                                        READLINE(mem_data_file, buf);
2867
                                        lineno := lineno + 1;
2868
                                        check_sum_vec := (OTHERS => '0');
2869
                                        if (buf(buf'LOW) = ':') then
2870
                                                i := 1;
2871
                                                shrink_line(buf, i);
2872
                                                READ(L=>buf, VALUE=>byte, good=>booval);
2873
                                                if not (booval) then
2874
                                                        ASSERT FALSE
2875
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
2876
                                                        SEVERITY ERROR;
2877
                                                end if;
2878
                                                ibyte := hex_str_to_int(byte);
2879
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
2880
                                                READ(L=>buf, VALUE=>startadd, good=>booval);
2881
                                                if not (booval) then
2882
                                                        ASSERT FALSE
2883
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2884
                                                        SEVERITY ERROR;
2885
                                                end if;
2886
                                                istartadd := hex_str_to_int(startadd);
2887
                                                addr(2) := startadd(4);
2888
                                                addr(1) := startadd(3);
2889
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2890
                                                addr(2) := startadd(2);
2891
                                                addr(1) := startadd(1);
2892
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
2893
                                                READ(L=>buf, VALUE=>rec_type, good=>booval);
2894
                                                if not (booval) then
2895
                                                        ASSERT FALSE
2896
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2897
                                                        SEVERITY ERROR;
2898
                                                end if;
2899
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
2900
                                        else
2901
                                                ASSERT FALSE
2902
                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2903
                                                SEVERITY ERROR;
2904
                                        end if;
2905
                                        case rec_type is
2906
                                                when "00"=>     -- Data record
2907
                                                        i := 0;
2908
                                                        k := lpm_width / 8;
2909
                                                        if ((lpm_width MOD 8) /= 0) then
2910
                                                                k := k + 1;
2911
                                                        end if;
2912
                                                        -- k = no. of bytes per CAM entry.
2913
                                                        while (i < ibyte) loop
2914
                                                                mem_data_word := (others => '0');
2915
                                                                n := (k - 1)*8;
2916
                                                                m := lpm_width - 1;
2917
                                                                for j in 1 to k loop
2918
                                                                        READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
2919
                                                                        if not (booval) then
2920
                                                                                ASSERT FALSE
2921
                                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2922
                                                                                SEVERITY ERROR;
2923
                                                                        end if;
2924
                                                                        check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
2925
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
2926
                                                                        m := n - 1;
2927
                                                                        n := n - 8;
2928
                                                                end loop;
2929
                                                                i := i + k;
2930
                                                                mem_data(ibase + istartadd) := mem_data_word;
2931
                                                                istartadd := istartadd + 1;
2932
                                                        end loop;
2933
                                                when "01"=>
2934
                                                        exit;
2935
                                                when "02"=>
2936
                                                        ibase := 0;
2937
                                                        if (ibyte /= 2) then
2938
                                                                ASSERT FALSE
2939
                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
2940
                                                                SEVERITY ERROR;
2941
                                                        end if;
2942
                                                        for i in 0 to (ibyte-1) loop
2943
                                                                READ(L=>buf, VALUE=>base,good=>booval);
2944
                                                                ibase := ibase * 256 + hex_str_to_int(base);
2945
                                                                if not (booval) then
2946
                                                                        ASSERT FALSE
2947
                                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
2948
                                                                        SEVERITY ERROR;
2949
                                                                end if;
2950
                                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
2951
                                                        end loop;
2952
                                                        ibase := ibase * 16;
2953
                                                when OTHERS =>
2954
                                                        ASSERT FALSE
2955
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
2956
                                                        SEVERITY ERROR;
2957
                                        end case;
2958
                                        READ(L=>buf, VALUE=>checksum,good=>booval);
2959
                                        if not (booval) then
2960
                                                ASSERT FALSE
2961
                                                REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
2962
                                                SEVERITY ERROR;
2963
                                        end if;
2964
 
2965
                                        check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
2966
                                        check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
2967
 
2968
                                        if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
2969
                                                ASSERT FALSE
2970
                                                REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
2971
                                                SEVERITY ERROR;
2972
                                        end if;
2973
                                end loop;
2974
                        end if;
2975
                        mem_init := TRUE;
2976
                end if;
2977
 
2978
                -- MEMORY FUNCTION --
2979
                if (((we_used = '1' and we_tmp = '1')
2980
                         or (outenab_used = '1' and we_used = '0' and outenab = '0'))
2981
                        and memenab_tmp = '1') then
2982
                        if (((use_eab = "ON") or (lpm_hint = "USE_EAB=ON")) and (lpm_address_control = "REGISTERED")) then
2983
                            if inclock = '0' then
2984
                                mem_data (conv_integer(address_tmp)) := data_tmp ;
2985
                            end if;
2986
                        else
2987
                            mem_data (conv_integer(address_tmp)) := data_tmp ;
2988
                        end if;
2989
                        q_tmp <= data_tmp ;
2990
                else
2991
                        q_tmp <= mem_data(conv_integer(address_tmp)) ;
2992
                end if;
2993
        end process;
2994
 
2995
        di <= dio when ((outenab_used = '0' and we = '1')
2996
                                        or (outenab_used = '1' and outenab = '0'))
2997
                          else (OTHERS => 'Z');
2998
        do <= q when memenab_tmp = '1' else (OTHERS => 'Z') ;
2999
        dio <= do when ((outenab_used = '0' and we = '0')
3000
                                        or (outenab_used = '1' and outenab = '1'))
3001
                          else (OTHERS => 'Z');
3002
 
3003
end LPM_SYN;
3004
 
3005
 
3006
---------------------------------------------------------------------------
3007
 
3008
library IEEE;
3009
use IEEE.std_logic_1164.all;
3010
use IEEE.std_logic_arith.all;
3011
use IEEE.std_logic_unsigned.all;
3012
use work.LPM_COMPONENTS.all;
3013
use std.textio.all;
3014
 
3015
entity LPM_ROM is
3016
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
3017
             LPM_WIDTHAD : natural;    -- MUST be greater than 0
3018
                         LPM_NUMWORDS : natural := 0;
3019
                         LPM_ADDRESS_CONTROL : string := "REGISTERED";
3020
                         LPM_OUTDATA : string := "REGISTERED";
3021
                         LPM_FILE : string;
3022
                         LPM_TYPE : string := "LPM_ROM";
3023
                         INTENDED_DEVICE_FAMILY  : string := "UNUSED";
3024
                         LPM_HINT : string := "UNUSED");
3025
        port (ADDRESS : in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0);
3026
                  INCLOCK : in STD_LOGIC := '0';
3027
                  OUTCLOCK : in STD_LOGIC := '0';
3028
                  MEMENAB : in STD_LOGIC := '1';
3029
                  Q : out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0));
3030
 
3031
        function int_to_str( value : integer ) return string is
3032
        variable ivalue,index : integer;
3033
        variable digit : integer;
3034
        variable line_no: string(8 downto 1) := "        ";
3035
        begin
3036
                ivalue := value;
3037
                index := 1;
3038
                while (ivalue > 0 ) loop
3039
                        digit := ivalue MOD 10;
3040
                        ivalue := ivalue/10;
3041
                        case digit is
3042
                                when 0 =>
3043
                                        line_no(index) := '0';
3044
                                when 1 =>
3045
                                        line_no(index) := '1';
3046
                                when 2 =>
3047
                                        line_no(index) := '2';
3048
                                when 3 =>
3049
                                        line_no(index) := '3';
3050
                                when 4 =>
3051
                                        line_no(index) := '4';
3052
                                when 5 =>
3053
                                        line_no(index) := '5';
3054
                                when 6 =>
3055
                                        line_no(index) := '6';
3056
                                when 7 =>
3057
                                        line_no(index) := '7';
3058
                                when 8 =>
3059
                                        line_no(index) := '8';
3060
                                when 9 =>
3061
                                        line_no(index) := '9';
3062
                                when others =>
3063
                                        ASSERT FALSE
3064
                                        REPORT "Illegal number!"
3065
                                        SEVERITY ERROR;
3066
                        end case;
3067
                        index := index + 1;
3068
                end loop;
3069
                return line_no;
3070
        end;
3071
 
3072
        function hex_str_to_int( str : string ) return integer is
3073
        variable len : integer := str'length;
3074
        variable ivalue : integer := 0;
3075
        variable digit : integer;
3076
        begin
3077
                for i in len downto 1 loop
3078
                        case str(i) is
3079
                                when '0' =>
3080
                                        digit := 0;
3081
                                when '1' =>
3082
                                        digit := 1;
3083
                                when '2' =>
3084
                                        digit := 2;
3085
                                when '3' =>
3086
                                        digit := 3;
3087
                                when '4' =>
3088
                                        digit := 4;
3089
                                when '5' =>
3090
                                        digit := 5;
3091
                                when '6' =>
3092
                                        digit := 6;
3093
                                when '7' =>
3094
                                        digit := 7;
3095
                                when '8' =>
3096
                                        digit := 8;
3097
                                when '9' =>
3098
                                        digit := 9;
3099
                                when 'A' =>
3100
                                        digit := 10;
3101
                                when 'a' =>
3102
                                        digit := 10;
3103
                                when 'B' =>
3104
                                        digit := 11;
3105
                                when 'b' =>
3106
                                        digit := 11;
3107
                                when 'C' =>
3108
                                        digit := 12;
3109
                                when 'c' =>
3110
                                        digit := 12;
3111
                                when 'D' =>
3112
                                        digit := 13;
3113
                                when 'd' =>
3114
                                        digit := 13;
3115
                                when 'E' =>
3116
                                        digit := 14;
3117
                                when 'e' =>
3118
                                        digit := 14;
3119
                                when 'F' =>
3120
                                        digit := 15;
3121
                                when 'f' =>
3122
                                        digit := 15;
3123
                                when others =>
3124
                                        ASSERT FALSE
3125
                                        REPORT "Illegal character "&  str(i) & "in Intel Hex File! "
3126
                                        SEVERITY ERROR;
3127
                        end case;
3128
                        ivalue := ivalue * 16 + digit;
3129
                end loop;
3130
                return ivalue;
3131
        end;
3132
 
3133
        procedure Shrink_line(L : inout LINE; pos : in integer) is
3134
        subtype nstring is string(1 to pos);
3135
        variable stmp : nstring;
3136
        begin
3137
                if pos >= 1 then
3138
                        read(l, stmp);
3139
                end if;
3140
        end;
3141
 
3142
end LPM_ROM;
3143
 
3144
architecture LPM_SYN of lpm_rom is
3145
 
3146
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
3147
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
3148
 
3149
signal q2, q_tmp, q_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3150
signal address_tmp, address_reg : std_logic_vector(lpm_widthad-1 downto 0);
3151
 
3152
begin
3153
 
3154
        enable_mem: process(memenab, q2)
3155
        begin
3156
                if (memenab = '1') then
3157
                        q <= q2;
3158
                else
3159
                        q <= (OTHERS => 'Z');
3160
                end if;
3161
        end process;
3162
 
3163
        sync: process(address, address_reg, q_tmp, q_reg)
3164
        begin
3165
                if (lpm_address_control = "REGISTERED") then
3166
                        address_tmp <= address_reg;
3167
        elsif (lpm_address_control = "UNREGISTERED") then
3168
                        address_tmp <= address;
3169
        else
3170
            ASSERT FALSE
3171
            REPORT "Illegal LPM_ADDRESS_CONTROL property value for LPM_RAM_ROM!"
3172
            SEVERITY ERROR;
3173
                end if;
3174
                if (lpm_outdata = "REGISTERED") then
3175
                        q2 <= q_reg;
3176
        elsif (lpm_outdata = "UNREGISTERED") then
3177
                        q2 <= q_tmp;
3178
        else
3179
            ASSERT FALSE
3180
            REPORT "Illegal LPM_OUTDATA property value for LPM_RAM_ROM!"
3181
            SEVERITY ERROR;
3182
                end if;
3183
        end process;
3184
 
3185
        input_reg: process (inclock)
3186
        begin
3187
                if inclock'event and inclock = '1' then
3188
                        address_reg <= address;
3189
                end if;
3190
        end process;
3191
 
3192
        output_reg: process (outclock)
3193
        begin
3194
                if outclock'event and outclock = '1' then
3195
                        q_reg <= q_tmp;
3196
                end if;
3197
        end process;
3198
 
3199
        memory: process(memenab, address_tmp)
3200
        variable mem_data : lpm_memory;
3201
        variable mem_data_word : std_logic_vector(lpm_width-1 downto 0);
3202
        variable mem_init: boolean := false;
3203
        variable i, j, k, n, m, lineno : integer := 0;
3204
        variable buf: line ;
3205
        variable booval: boolean ;
3206
        FILE mem_data_file: TEXT IS IN LPM_FILE;
3207
        variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1);
3208
        variable startadd: string(4 downto 1);
3209
        variable ibase: integer := 0;
3210
        variable ibyte: integer := 0;
3211
        variable istartadd: integer := 0;
3212
        variable check_sum_vec, check_sum_vec_tmp: std_logic_vector(7 downto 0);
3213
        begin
3214
                -- INITIALIZE --
3215
                if NOT(mem_init) then
3216
                        -- INITIALIZE TO 0 --
3217
                        for i in mem_data'LOW to mem_data'HIGH loop
3218
                                mem_data(i) := (OTHERS => '0');
3219
                        end loop;
3220
 
3221
            if (LPM_FILE = "UNUSED" or LPM_FILE = "") then
3222
                ASSERT FALSE
3223
                                REPORT "Initialization file not found!"
3224
                                SEVERITY ERROR;
3225
                        else
3226
                                WHILE NOT ENDFILE(mem_data_file) loop
3227
                                        booval := true;
3228
                                        READLINE(mem_data_file, buf);
3229
                                        lineno := lineno + 1;
3230
                                        check_sum_vec := (OTHERS => '0');
3231
                                        if (buf(buf'LOW) = ':') then
3232
                                                i := 1;
3233
                                                shrink_line(buf, i);
3234
                                                READ(L=>buf, VALUE=>byte, good=>booval);
3235
                                                if not (booval) then
3236
                                                        ASSERT FALSE
3237
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!"
3238
                                                        SEVERITY ERROR;
3239
                                                end if;
3240
                                                ibyte := hex_str_to_int(byte);
3241
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(ibyte, 8));
3242
                                                READ(L=>buf, VALUE=>startadd, good=>booval);
3243
                                                if not (booval) then
3244
                                                        ASSERT FALSE
3245
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
3246
                                                        SEVERITY ERROR;
3247
                                                end if;
3248
                                                istartadd := hex_str_to_int(startadd);
3249
                                                addr(2) := startadd(4);
3250
                                                addr(1) := startadd(3);
3251
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
3252
                                                addr(2) := startadd(2);
3253
                                                addr(1) := startadd(1);
3254
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(addr), 8));
3255
                                                READ(L=>buf, VALUE=>rec_type, good=>booval);
3256
                                                if not (booval) then
3257
                                                        ASSERT FALSE
3258
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
3259
                                                        SEVERITY ERROR;
3260
                                                end if;
3261
                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(rec_type), 8));
3262
                                        else
3263
                                                ASSERT FALSE
3264
                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
3265
                                                SEVERITY ERROR;
3266
                                        end if;
3267
                                        case rec_type is
3268
                                                when "00"=>  -- Data record
3269
                                                        i := 0;
3270
                                                        k := lpm_width / 8;
3271
                                                        if ((lpm_width MOD 8) /= 0) then
3272
                                                                k := k + 1;
3273
                                                        end if;
3274
                                                        -- k = no. of bytes per CAM entry.
3275
                                                        while (i < ibyte) loop
3276
                                                                mem_data_word := (others => '0');
3277
                                                                n := (k - 1)*8;
3278
                                                                m := lpm_width - 1;
3279
                                                                for j in 1 to k loop
3280
                                                                        READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time.
3281
                                                                        if not (booval) then
3282
                                                                                ASSERT FALSE
3283
                                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
3284
                                                                                SEVERITY ERROR;
3285
                                                                        end if;
3286
                                                                        check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), 8));
3287
                                                                        mem_data_word(m downto n) := CONV_STD_LOGIC_VECTOR(hex_str_to_int(datain), m-n+1);
3288
                                                                        m := n - 1;
3289
                                                                        n := n - 8;
3290
                                                                end loop;
3291
                                                                i := i + k;
3292
                                                                mem_data(ibase + istartadd) := mem_data_word;
3293
                                                                istartadd := istartadd + 1;
3294
                                                        end loop;
3295
                                                when "01"=>
3296
                                                        exit;
3297
                                                when "02"=>
3298
                                                        ibase := 0;
3299
                                                        if (ibyte /= 2) then
3300
                                                                ASSERT FALSE
3301
                                                                REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! "
3302
                                                                SEVERITY ERROR;
3303
                                                        end if;
3304
                                                        for i in 0 to (ibyte-1) loop
3305
                                                                READ(L=>buf, VALUE=>base,good=>booval);
3306
                                                                ibase := ibase * 256 + hex_str_to_int(base);
3307
                                                                if not (booval) then
3308
                                                                        ASSERT FALSE
3309
                                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! "
3310
                                                                        SEVERITY ERROR;
3311
                                                                end if;
3312
                                                                check_sum_vec := unsigned(check_sum_vec) + unsigned(CONV_STD_LOGIC_VECTOR(hex_str_to_int(base), 8));
3313
                                                        end loop;
3314
                                                        ibase := ibase * 16;
3315
                                                when OTHERS =>
3316
                                                        ASSERT FALSE
3317
                                                        REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! "
3318
                                                        SEVERITY ERROR;
3319
                                        end case;
3320
                                        READ(L=>buf, VALUE=>checksum,good=>booval);
3321
                                        if not (booval) then
3322
                                                ASSERT FALSE
3323
                                                REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! "
3324
                                                SEVERITY ERROR;
3325
                                        end if;
3326
 
3327
                                        check_sum_vec := unsigned(not (check_sum_vec)) + 1 ;
3328
                                        check_sum_vec_tmp := CONV_STD_LOGIC_VECTOR(hex_str_to_int(checksum),8);
3329
 
3330
                                        if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then
3331
                                                ASSERT FALSE
3332
                                                REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!"
3333
                                                SEVERITY ERROR;
3334
                                        end if;
3335
                                end loop;
3336
                        end if;
3337
                        mem_init := TRUE;
3338
                end if;
3339
 
3340
                -- MEMORY FUNCTION --
3341
                --if memenab = '1' then
3342
                        q_tmp <= mem_data(conv_integer(address_tmp));
3343
                --else
3344
                --    q_tmp <= (OTHERS => 'Z');
3345
                --end if;
3346
        end process;
3347
 
3348
end LPM_SYN;
3349
 
3350
 
3351
---------------------------------------------------------------------------
3352
 
3353
library IEEE;
3354
use IEEE.std_logic_1164.all;
3355
use IEEE.std_logic_arith.all;
3356
use IEEE.std_logic_unsigned.all;
3357
use work.LPM_COMPONENTS.all;
3358
 
3359
entity LPM_FIFO is
3360
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
3361
             LPM_WIDTHU : natural := 1;    -- MUST be greater than 0
3362
             LPM_NUMWORDS : natural;    -- MUST be greater than 0
3363
                         LPM_SHOWAHEAD : string := "OFF";
3364
                         LPM_TYPE : string := "LPM_FIFO";
3365
                         LPM_HINT : string := "UNUSED");
3366
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
3367
                  CLOCK : in std_logic;
3368
                  WRREQ : in std_logic;
3369
                  RDREQ : in std_logic;
3370
                  ACLR : in std_logic := '0';
3371
                  SCLR : in std_logic := '0';
3372
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
3373
                  USEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
3374
                  FULL : out std_logic;
3375
                  EMPTY : out std_logic);
3376
end LPM_FIFO;
3377
 
3378
architecture LPM_SYN of lpm_fifo is
3379
 
3380
type lpm_memory is array (lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
3381
 
3382
signal tmp_q : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3383
signal read_id, write_id, count_id : integer := 0;
3384
signal empty_flag : std_logic := '1';
3385
signal full_flag : std_logic := '0';
3386
constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3387
 
3388
begin
3389
 
3390
        process (clock, aclr)
3391
        variable mem_data : lpm_memory := (OTHERS => ZEROS);
3392
 
3393
        begin
3394
        if (LPM_SHOWAHEAD /= "ON" and LPM_SHOWAHEAD /= "OFF") then
3395
            ASSERT FALSE
3396
            REPORT "Illegal LPM_SHOWAHEAD property value for LPM_FIFO!"
3397
            SEVERITY ERROR;
3398
        end if;
3399
 
3400
                if (aclr = '1') then
3401
                        tmp_q <= ZEROS;
3402
                        full_flag <= '0';
3403
                        empty_flag <= '1';
3404
                        read_id <= 0;
3405
                        write_id <= 0;
3406
                        count_id <= 0;
3407
                        if (lpm_showahead = "ON") then
3408
                                tmp_q <= mem_data(0);
3409
                        end if;
3410
                elsif (clock'event and clock = '1') then
3411
                        if (sclr = '1') then
3412
                                tmp_q <= mem_data(read_id);
3413
                                full_flag <= '0';
3414
                                empty_flag <= '1';
3415
                                read_id <= 0;
3416
                                write_id <= 0;
3417
                                count_id <= 0;
3418
                                if (lpm_showahead = "ON") then
3419
                                        tmp_q <= mem_data(0);
3420
                                end if;
3421
                        else
3422
                                ----- IF BOTH READ AND WRITE -----
3423
                                if (wrreq = '1' and full_flag = '0') and
3424
                                        (rdreq = '1' and empty_flag = '0') then
3425
 
3426
                                        mem_data(write_id) := data;
3427
                                        if (write_id >= lpm_numwords-1) then
3428
                                                write_id <= 0;
3429
                                        else
3430
                                                write_id <= write_id + 1;
3431
                                        end if;
3432
 
3433
                                        tmp_q <= mem_data(read_id);
3434
                                        if (read_id >= lpm_numwords-1) then
3435
                                                read_id <= 0;
3436
                                                if (lpm_showahead = "ON") then
3437
                                                        tmp_q <= mem_data(0);
3438
                                                end if;
3439
                                        else
3440
                                                read_id <= read_id + 1;
3441
                                                if (lpm_showahead = "ON") then
3442
                                                        tmp_q <= mem_data(read_id+1);
3443
                                                end if;
3444
                                        end if;
3445
 
3446
                                ----- IF WRITE (ONLY) -----
3447
                                elsif (wrreq = '1' and full_flag = '0') then
3448
 
3449
                                        mem_data(write_id) := data;
3450
                                        if (lpm_showahead = "ON") then
3451
                                                tmp_q <= mem_data(read_id);
3452
                                        end if;
3453
                                        count_id <= count_id + 1;
3454
                                        empty_flag <= '0';
3455
                                        if (count_id >= lpm_numwords-1) then
3456
                                                full_flag <= '1';
3457
                                                count_id <= lpm_numwords;
3458
                                        end if;
3459
                                        if (write_id >= lpm_numwords-1) then
3460
                                                write_id <= 0;
3461
                                        else
3462
                                                write_id <= write_id + 1;
3463
                                        end if;
3464
 
3465
                                ----- IF READ (ONLY) -----
3466
                                elsif (rdreq = '1' and empty_flag = '0') then
3467
 
3468
                                        tmp_q <= mem_data(read_id);
3469
                                        count_id <= count_id - 1;
3470
                                        full_flag <= '0';
3471
                                        if (count_id <= 1) then
3472
                                                empty_flag <= '1';
3473
                                                count_id <= 0;
3474
                                        end if;
3475
                                        if (read_id >= lpm_numwords-1) then
3476
                                                read_id <= 0;
3477
                                                if (lpm_showahead = "ON") then
3478
                                                        tmp_q <= mem_data(0);
3479
                                                end if;
3480
                                        else
3481
                                                read_id <= read_id + 1;
3482
                                                if (lpm_showahead = "ON") then
3483
                                                        tmp_q <= mem_data(read_id+1);
3484
                                                end if;
3485
                                        end if;
3486
                                end if;  -- if WRITE and/or READ
3487
                        end if;  -- if sclr = '1'
3488
                end if;  -- if aclr = '1'
3489
        end process;
3490
 
3491
        q <= tmp_q;
3492
        full <= full_flag;
3493
        empty <= empty_flag;
3494
        usedw <= conv_std_logic_vector(count_id, lpm_widthu);
3495
 
3496
end LPM_SYN;
3497
 
3498
 
3499
--------------------------------------------------------------------------
3500
 
3501
library IEEE;
3502
use IEEE.std_logic_1164.all;
3503
use IEEE.std_logic_arith.all;
3504
use IEEE.std_logic_unsigned.all;
3505
use work.LPM_COMPONENTS.all;
3506
 
3507
entity LPM_FIFO_DC_DFFPIPE is
3508
    generic (LPM_DELAY : natural);
3509
    port (D : in integer;
3510
          Q : out integer := 0;
3511
          CLOCK : in std_logic;
3512
          ACLR : in std_logic := '0');
3513
end LPM_FIFO_DC_DFFPIPE;
3514
 
3515
architecture LPM_SYN of LPM_FIFO_DC_DFFPIPE is
3516
type delaypipe is array (LPM_DELAY downto 0) of integer;
3517
 
3518
begin
3519
 
3520
    process (clock, aclr, d)
3521
    variable intpipe : delaypipe := (OTHERS => 0);
3522
    variable delay : integer := LPM_DELAY-1;
3523
    variable init : integer := 0;
3524
    begin
3525
        if (LPM_DELAY = 0) then
3526
            if (aclr = '1' or init = 0) then
3527
                q <= 0;
3528
                init := 1;
3529
            else
3530
                q <= d;
3531
            end if;
3532
        else
3533
            if (aclr = '1' or init = 0) then
3534
                for i in LPM_DELAY downto 0 loop
3535
                    intpipe(i) := 0;
3536
                end loop;
3537
                init := 1;
3538
                q <= 0;
3539
            end if;
3540
            if (clock'event and clock = '1' and NOW > 0 ns) then
3541
                if (delay > 0) then
3542
                    for i in delay downto 1 loop
3543
                        intpipe(i) := intpipe(i-1);
3544
                    end loop;
3545
                end if;
3546
                intpipe(0) := d;
3547
                q <= intpipe(delay);
3548
            end if;
3549
        end if;
3550
    end process;
3551
 
3552
end LPM_SYN;
3553
 
3554
--------------------------------------------------------------------------
3555
 
3556
library IEEE;
3557
use IEEE.std_logic_1164.all;
3558
use IEEE.std_logic_arith.all;
3559
use IEEE.std_logic_unsigned.all;
3560
use work.LPM_COMPONENTS.all;
3561
 
3562
entity LPM_FIFO_DC_FEFIFO is
3563
    generic (LPM_WIDTHAD : natural;
3564
             LPM_NUMWORDS : natural;
3565
             UNDERFLOW_CHECKING : string := "ON";
3566
             LPM_MODE : string );
3567
    port (USEDW_IN : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
3568
          WREQ : in std_logic := 'Z';
3569
          RREQ : in std_logic := 'Z';
3570
          EMPTY : out std_logic;
3571
          FULL : out std_logic;
3572
          CLOCK : in std_logic;
3573
          ACLR : in std_logic := '0');
3574
end LPM_FIFO_DC_FEFIFO;
3575
 
3576
architecture LPM_SYN of LPM_FIFO_DC_FEFIFO is
3577
signal usedw : std_logic_vector(LPM_WIDTHAD-1 downto 0);
3578
signal sm_empty : std_logic_vector(1 downto 0) := "00";
3579
signal lrreq : std_logic := '0'; -- DFF;
3580
signal init : natural := 0;
3581
signal i_empty : std_logic := '1';
3582
signal i_full : std_logic := '0';
3583
signal valid_rreq : std_logic;
3584
 
3585
begin
3586
 
3587
    valid_rreq <= rreq when underflow_checking = "OFF" else
3588
                  rreq and not i_empty;
3589
 
3590
    process (clock, aclr)
3591
    begin
3592
        if (aclr = '1') then
3593
            lrreq <= '0';
3594
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
3595
            lrreq <= valid_rreq;
3596
        end if;
3597
    end process;
3598
 
3599
    process (clock, aclr)
3600
    variable almost_full : integer := 0;
3601
    begin
3602
        if (aclr = '1') then
3603
            i_full <= '0';
3604
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
3605
            if (lpm_numwords >= 3) then
3606
                almost_full := lpm_numwords-3;
3607
            end if;
3608
            if (unsigned(usedw) >= almost_full) then
3609
                i_full <= '1';
3610
            else
3611
                i_full <= '0';
3612
            end if;
3613
        end if;
3614
    end process;
3615
 
3616
    process (clock, aclr)
3617
    variable local_sm_empty : std_logic_vector(1 downto 0) := "00";
3618
    variable usedw_is_1 : boolean;
3619
    begin
3620
        local_sm_empty := sm_empty;
3621
        if (aclr = '1') then
3622
            local_sm_empty := "00";
3623
        elsif (clock'event and clock = '1' and NOW > 0 ns) then
3624
            if (lpm_mode = "READ") then
3625
                case sm_empty is
3626
                    when "00" =>                    -- state_empty
3627
                        if (usedw /= 0) then
3628
                            local_sm_empty := "01";
3629
                        end if;
3630
                    when "01" =>                    -- state_non_empty
3631
                        usedw_is_1 := (usedw = 1 and lrreq = '0') or (usedw = 2 and lrreq = '1');
3632
                        if (rreq = '1' and usedw_is_1) then
3633
                            local_sm_empty := "10";
3634
                        end if;
3635
                    when "10" =>                    -- state_emptywait
3636
                        if (usedw > 1) then
3637
                            local_sm_empty := "01";
3638
                        else
3639
                            local_sm_empty := "00";
3640
                        end if;
3641
                    when others =>
3642
                        -- INTERNAL ERROR
3643
                end case;
3644
            elsif (lpm_mode = "WRITE") then
3645
                case sm_empty is
3646
                    when "00" =>                    -- state_empty
3647
                        if (wreq = '1') then
3648
                            local_sm_empty := "01";
3649
                        end if;
3650
                    when "01" =>                    -- state_one
3651
                        if (wreq = '0') then
3652
                            local_sm_empty := "11";
3653
                        end if;
3654
                    when "11" =>                    -- state_non_empty
3655
                        if (wreq = '1') then
3656
                            local_sm_empty := "01";
3657
                        elsif (usedw = 0) then
3658
                            local_sm_empty := "00";
3659
                        end if;
3660
                    when others =>
3661
                        -- INTERNAL ERROR
3662
                end case;
3663
            end if;
3664
        end if;
3665
        sm_empty <= local_sm_empty;
3666
        i_empty <= not local_sm_empty(0);
3667
    end process;
3668
 
3669
    usedw <= usedw_in;
3670
    empty <= i_empty;
3671
    full <= i_full;
3672
 
3673
end LPM_SYN;
3674
 
3675
---------------------------------------------------------------------------
3676
 
3677
library IEEE;
3678
use IEEE.std_logic_1164.all;
3679
use IEEE.std_logic_arith.all;
3680
use IEEE.std_logic_unsigned.all;
3681
use work.LPM_COMPONENTS.all;
3682
use std.textio.all;
3683
 
3684
entity LPM_FIFO_DC is
3685
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
3686
             LPM_WIDTHU : natural := 1;    -- MUST be greater than 0
3687
             LPM_NUMWORDS : natural;    -- MUST be greater than 0
3688
             LPM_SHOWAHEAD : string := "OFF";
3689
             LPM_TYPE : string := "LPM_FIFO_DC";
3690
             UNDERFLOW_CHECKING : string := "ON";
3691
             OVERFLOW_CHECKING : string := "ON";
3692
             LPM_HINT : string := "USE_EAB=ON");
3693
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
3694
                  WRCLOCK : in std_logic;
3695
                  RDCLOCK : in std_logic;
3696
                  WRREQ : in std_logic;
3697
                  RDREQ : in std_logic;
3698
                  ACLR : in std_logic := '0';
3699
                  Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
3700
                  WRUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
3701
                  RDUSEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
3702
                  WRFULL : out std_logic;
3703
                  RDFULL : out std_logic;
3704
                  WREMPTY : out std_logic;
3705
                  RDEMPTY : out std_logic);
3706
end LPM_FIFO_DC;
3707
 
3708
architecture LPM_SYN of lpm_fifo_dc is
3709
 
3710
type lpm_memory is array (2**lpm_widthu-1 downto 0) of std_logic_vector(lpm_width-1 downto 0);
3711
 
3712
signal i_q : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3713
signal i_rdptr, i_wrptr, i_rdptrrg, i_wrdelaycycle : integer := 0;
3714
signal i_ws_nbrp, i_rs_nbwp, i_ws_dbrp, i_rs_dbwp : integer := 0;
3715
signal i_wr_udwn, i_rd_udwn, i_wr_dbuw, i_rd_dbuw : integer := 0;
3716
signal i_rdempty, i_wrempty : std_logic := '1';
3717
signal i_rdfull, i_wrfull : std_logic := '0';
3718
signal i_rdusedw, i_wrusedw : integer := 0;
3719
signal i_rden, i_wren, i_rdenclock : std_logic := '0';
3720
signal slv_wr_dbuw, slv_rd_dbuw : std_logic_vector(lpm_widthu-1 downto 0);
3721
 
3722
signal i_data_tmp, i_data_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3723
signal i_q_tmp, i_q_reg : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3724
signal i_rdptr_tmp, i_wrptr_tmp, i_wrptr_reg : integer := 0;
3725
signal i_wren_tmp, i_wren_reg : std_logic := '0';
3726
 
3727
constant ZEROS : std_logic_vector(lpm_width-1 downto 0) := (OTHERS => '0');
3728
constant WRSYNC_DELAYPIPE : integer := 3;   -- from the rdclk to the wrclk subsystem
3729
constant RDSYNC_DELAYPIPE : integer := 3;   -- from the wrclk to the rdclk subsystem
3730
constant GRAY_DELAYPIPE : integer := 1;
3731
constant DELAY_WRUSEDW : integer := 1;      -- output delay to the wrusedw outputs
3732
constant DELAY_RDUSEDW : integer := 1;      -- output delay to the rdusedw outputs
3733
constant WRUSEDW_DELAYPIPE : integer := 1;  -- delayed usedw to compute empty/full
3734
constant RDUSEDW_DELAYPIPE : integer := 1;  -- delayed usedw to compute empty/full
3735
 
3736
component LPM_FIFO_DC_FEFIFO
3737
    generic (LPM_WIDTHAD : natural;
3738
             LPM_NUMWORDS : natural;
3739
             UNDERFLOW_CHECKING : STRING := "ON";
3740
             LPM_MODE : string);
3741
    port (USEDW_IN : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
3742
          WREQ : in std_logic := 'Z';
3743
          RREQ : in std_logic := 'Z';
3744
          EMPTY : out std_logic;
3745
          FULL : out std_logic;
3746
          CLOCK : in std_logic;
3747
          ACLR : in std_logic := '0');
3748
end component;
3749
 
3750
component LPM_FIFO_DC_DFFPIPE
3751
    generic (LPM_DELAY : natural);
3752
    port (D : in integer;
3753
          Q : out integer := 0;
3754
          CLOCK : in std_logic;
3755
          ACLR : in std_logic := '0');
3756
end component;
3757
 
3758
begin
3759
 
3760
    ----------
3761
    -- FIFOram
3762
    ----------
3763
 
3764
    i_rden <= rdreq when underflow_checking = "OFF" else
3765
              rdreq and not i_rdempty;
3766
    i_wren <= wrreq when overflow_checking = "OFF" else
3767
              wrreq and not i_wrfull;
3768
 
3769
    FIFOram_sync: process (i_data_reg, i_q_tmp, i_q_reg, aclr,
3770
                           i_rdptr, i_wren_reg, i_wrptr_reg)
3771
    begin
3772
        if (aclr = '1') then
3773
            i_wrptr_tmp <= 0;
3774
            i_rdptr_tmp <= 0;
3775
            i_wren_tmp <= '0';
3776
            i_data_tmp <= (OTHERS => '0');
3777
            if (LPM_SHOWAHEAD = "ON") then
3778
                i_q <= i_q_tmp;
3779
            else
3780
                i_q <= (OTHERS => '0');
3781
            end if;
3782
        else
3783
            i_wrptr_tmp <= i_wrptr_reg;
3784
            i_rdptr_tmp <= i_rdptr;
3785
            i_wren_tmp <= i_wren_reg;
3786
            i_data_tmp <= i_data_reg;
3787
            if (LPM_SHOWAHEAD = "ON") then
3788
                i_q <= i_q_tmp;
3789
            else
3790
                i_q <= i_q_reg;
3791
            end if;
3792
        end if;
3793
    end process;
3794
 
3795
    FIFOram_wrclock: process (wrclock, aclr)
3796
    begin
3797
        if (aclr = '1') then
3798
            i_data_reg <= (OTHERS => '0');
3799
            i_wrptr_reg <= 0;
3800
            i_wren_reg <= '0';
3801
        elsif (wrclock'event and wrclock = '1' and NOW > 0 ns) then
3802
            i_data_reg <= data;
3803
            i_wrptr_reg <= i_wrptr;
3804
            i_wren_reg <= i_wren;
3805
        end if;
3806
    end process;
3807
 
3808
    FIFOram_rdclock: process (rdclock, aclr)
3809
    begin
3810
        if (aclr = '1') then
3811
            i_q_reg <= (OTHERS => '0');
3812
        elsif (rdclock'event and rdclock = '1' and i_rden = '1' and NOW > 0 ns) then
3813
            i_q_reg <= i_q_tmp;
3814
        end if;
3815
    end process;
3816
 
3817
    FIFOram_memory: process (i_data_tmp, i_wren_tmp, i_wrptr_tmp, i_rdptr_tmp, wrclock)
3818
    variable mem_data : lpm_memory := (OTHERS => ZEROS);
3819
    variable init : integer := 0;
3820
    begin
3821
        if (init = 0) then
3822
            for i in lpm_numwords-1 downto 0 loop
3823
                mem_data(i) := ZEROS;
3824
            end loop;
3825
            init := 1;
3826
        end if;
3827
        if wrclock'event and i_wren_tmp = '1' and
3828
            ((wrclock = '0' and lpm_hint = "USE_EAB=ON") or
3829
             (wrclock = '1' and lpm_hint /= "USE_EAB=ON")) then
3830
                mem_data(i_wrptr_tmp) := i_data_tmp;
3831
        end if;
3832
        i_q_tmp <= mem_data(i_rdptr_tmp);
3833
    end process;
3834
 
3835
 
3836
    -----------
3837
    -- Counters
3838
    -----------
3839
 
3840
    rdptr: process (rdclock, aclr)
3841
    begin
3842
        if (aclr = '1') then
3843
            i_rdptr <= 0;
3844
        elsif (rdclock'event and rdclock = '1' and i_rden = '1' and NOW > 0 ns) then
3845
            if (i_rdptr < 2**lpm_widthu-1) then
3846
                i_rdptr <= i_rdptr + 1;
3847
            else
3848
                i_rdptr <= 0;
3849
            end if;
3850
        end if;
3851
    end process;
3852
 
3853
    wrptr: process (wrclock, aclr)
3854
    begin
3855
        if (aclr = '1') then
3856
            i_wrptr <= 0;
3857
        elsif (wrclock'event and wrclock = '1' and i_wren = '1' and NOW > 0 ns) then
3858
            if (i_wrptr < 2**lpm_widthu-1) then
3859
                i_wrptr <= i_wrptr + 1;
3860
            else
3861
                i_wrptr <= 0;
3862
            end if;
3863
        end if;
3864
    end process;
3865
 
3866
 
3867
    ---------------------
3868
    -- Delays & DFF Pipes
3869
    ---------------------
3870
 
3871
    process (rdclock)
3872
    begin
3873
        if (rdclock = '0') then
3874
            i_rdenclock <= '0';
3875
        elsif (rdclock = '1' and i_rden = '1') then
3876
            i_rdenclock <= '1';
3877
        end if;
3878
    end process;
3879
 
3880
    RDPTR_D:    LPM_FIFO_DC_DFFPIPE
3881
                    generic map (LPM_DELAY => 0)
3882
                    port map (D => i_rdptr, Q => i_rdptrrg,
3883
                              CLOCK => i_rdenclock, ACLR => aclr);
3884
 
3885
    WRPTR_D:    LPM_FIFO_DC_DFFPIPE
3886
                    generic map (LPM_DELAY => 1)
3887
                    port map (D => i_wrptr, Q => i_wrdelaycycle,
3888
                              CLOCK => wrclock, ACLR => aclr);
3889
 
3890
    WS_NBRP:    LPM_FIFO_DC_DFFPIPE
3891
                    generic map (LPM_DELAY => WRSYNC_DELAYPIPE)
3892
                    port map (D => i_rdptrrg, Q => i_ws_nbrp,
3893
                              CLOCK => wrclock, ACLR => aclr);
3894
 
3895
    RS_NBWP:    LPM_FIFO_DC_DFFPIPE
3896
                    generic map (LPM_DELAY => RDSYNC_DELAYPIPE)
3897
                    port map (D => i_wrdelaycycle, Q => i_rs_nbwp,
3898
                              CLOCK => rdclock, ACLR => aclr);
3899
 
3900
    WS_DBRP:    LPM_FIFO_DC_DFFPIPE
3901
                    generic map (LPM_DELAY => GRAY_DELAYPIPE)
3902
                    port map (D => i_ws_nbrp, Q => i_ws_dbrp,
3903
                              CLOCK => wrclock, ACLR => aclr);
3904
 
3905
    RS_DBWP:    LPM_FIFO_DC_DFFPIPE
3906
                    generic map (LPM_DELAY => GRAY_DELAYPIPE)
3907
                    port map (D => i_rs_nbwp, Q => i_rs_dbwp,
3908
                              CLOCK => rdclock, ACLR => aclr);
3909
 
3910
    process (i_wrptr, i_ws_dbrp)
3911
    begin
3912
        i_wr_udwn <= i_wrptr - i_ws_dbrp;
3913
    end process;
3914
 
3915
    process (i_rdptr, i_rs_dbwp)
3916
    begin
3917
        i_rd_udwn <= i_rs_dbwp - i_rdptr;
3918
    end process;
3919
 
3920
    WR_USEDW:   LPM_FIFO_DC_DFFPIPE
3921
                    generic map (LPM_DELAY => DELAY_WRUSEDW)
3922
                    port map (D => i_wr_udwn, Q => i_wrusedw,
3923
                              CLOCK => wrclock, ACLR => aclr);
3924
 
3925
    RD_USEDW:   LPM_FIFO_DC_DFFPIPE
3926
                    generic map (LPM_DELAY => DELAY_RDUSEDW)
3927
                    port map (D => i_rd_udwn, Q => i_rdusedw,
3928
                              CLOCK => rdclock, ACLR => aclr);
3929
 
3930
    WR_DBUW:    LPM_FIFO_DC_DFFPIPE
3931
                    generic map (LPM_DELAY => WRUSEDW_DELAYPIPE)
3932
                    port map (D => i_wr_udwn, Q => i_wr_dbuw,
3933
                              CLOCK => wrclock, ACLR => aclr);
3934
 
3935
    RD_DBUW:    LPM_FIFO_DC_DFFPIPE
3936
                    generic map (LPM_DELAY => RDUSEDW_DELAYPIPE)
3937
                    port map (D => i_rd_udwn, Q => i_rd_dbuw,
3938
                              CLOCK => rdclock, ACLR => aclr);
3939
 
3940
 
3941
    -------------
3942
    -- Full/Empty
3943
    -------------
3944
 
3945
    slv_wr_dbuw <= conv_std_logic_vector(i_wr_dbuw, LPM_WIDTHU);
3946
    slv_rd_dbuw <= conv_std_logic_vector(i_rd_dbuw, LPM_WIDTHU);
3947
 
3948
    WR_FE:  LPM_FIFO_DC_FEFIFO
3949
                generic map (LPM_WIDTHAD => LPM_WIDTHU,
3950
                             LPM_NUMWORDS => LPM_NUMWORDS,
3951
                             LPM_MODE => "WRITE",
3952
                             UNDERFLOW_CHECKING => UNDERFLOW_CHECKING)
3953
                port map (USEDW_IN => slv_wr_dbuw, WREQ => wrreq,
3954
                          CLOCK => wrclock, ACLR => aclr,
3955
                          EMPTY => i_wrempty, FULL => i_wrfull);
3956
 
3957
    RD_FE:  LPM_FIFO_DC_FEFIFO
3958
                generic map (LPM_WIDTHAD => LPM_WIDTHU,
3959
                             LPM_NUMWORDS => LPM_NUMWORDS,
3960
                             LPM_MODE => "READ",
3961
                             UNDERFLOW_CHECKING => UNDERFLOW_CHECKING)
3962
                port map (USEDW_IN => slv_rd_dbuw, RREQ => rdreq,
3963
                          CLOCK => rdclock, ACLR => aclr,
3964
                          EMPTY => i_rdempty, FULL => i_rdfull);
3965
 
3966
    ----------
3967
    -- Outputs
3968
    ----------
3969
 
3970
    q <= i_q;
3971
    wrfull <= i_wrfull;
3972
    wrempty <= i_wrempty;
3973
    rdfull <= i_rdfull;
3974
    rdempty <= i_rdempty;
3975
    wrusedw <= conv_std_logic_vector(i_wrusedw, LPM_WIDTHU);
3976
    rdusedw <= conv_std_logic_vector(i_rdusedw, LPM_WIDTHU);
3977
 
3978
end LPM_SYN;
3979
 
3980
 
3981
--------------------------------------------------------------------------
3982
 
3983
library IEEE;
3984
use IEEE.std_logic_1164.all;
3985
use work.LPM_COMPONENTS.all;
3986
 
3987
entity LPM_INPAD is
3988
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
3989
                         LPM_TYPE : string := "LPM_INPAD";
3990
                         LPM_HINT : string := "UNUSED");
3991
        port (PAD : in std_logic_vector(LPM_WIDTH-1 downto 0);
3992
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0));
3993
end LPM_INPAD;
3994
 
3995
architecture LPM_SYN of LPM_INPAD is
3996
begin
3997
 
3998
        RESULT <=  PAD;
3999
 
4000
end LPM_SYN;
4001
 
4002
 
4003
--------------------------------------------------------------------------
4004
 
4005
library IEEE;
4006
use IEEE.std_logic_1164.all;
4007
use work.LPM_COMPONENTS.all;
4008
 
4009
entity LPM_OUTPAD is
4010
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
4011
                         LPM_TYPE : string := "L_OUTPAD";
4012
                         LPM_HINT : string := "UNUSED");
4013
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
4014
                  PAD : out std_logic_vector(LPM_WIDTH-1 downto 0));
4015
end LPM_OUTPAD;
4016
 
4017
architecture LPM_SYN of LPM_OUTPAD is
4018
begin
4019
 
4020
        PAD <= DATA;
4021
 
4022
end LPM_SYN;
4023
 
4024
 
4025
--------------------------------------------------------------------------
4026
 
4027
library IEEE;
4028
use IEEE.std_logic_1164.all;
4029
use work.LPM_COMPONENTS.all;
4030
 
4031
entity LPM_BIPAD is
4032
    generic (LPM_WIDTH : natural;    -- MUST be greater than 0
4033
                         LPM_TYPE : string := "LPM_BIPAD";
4034
                         LPM_HINT : string := "UNUSED");
4035
        port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
4036
                  ENABLE : in std_logic;
4037
                  RESULT : out std_logic_vector(LPM_WIDTH-1 downto 0);
4038
                  PAD : inout std_logic_vector(LPM_WIDTH-1 downto 0));
4039
end LPM_BIPAD;
4040
 
4041
architecture LPM_SYN of LPM_BIPAD is
4042
begin
4043
 
4044
        process(DATA, PAD, ENABLE)
4045
        begin
4046
                if ENABLE = '1' then
4047
                        PAD <= DATA;
4048
                        RESULT <= (OTHERS => 'Z');
4049
                else
4050
                        RESULT <= PAD;
4051
                        PAD <= (OTHERS => 'Z');
4052
                end if;
4053
        end process;
4054
 
4055
end LPM_SYN;

powered by: WebSVN 2.1.0

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