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

Subversion Repositories common

[/] [common/] [trunk/] [LPM_gates.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 bbeaver
//------------------------------------------------------------------------
2
//   This Verilog 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
// Imported to Opencores directory.   Date Sept 10, 2001
12
// Split related modules into separate files, as the manual splits them.
13
// Added example instantiations to the beginning of each file.
14
//
15
/* EXAMPLE INSTANTIATIONS:
16
 
17
lpm_constant
18
#( 1,                         // lpm_width
19
   0,                         // lpm_cvalue
20
   "UNUSED"                   // lpm_strength, optional, {UNUSED, WEAK}
21
 ) lpm_constant_example (
22
  .result                     (const_out[lpm_width-1:0])
23
);
24
 
25
lpm_inv
26
#( 1                          // lpm_width
27
 ) lpm_inv_example (
28
  .result                     (data_out[lpm_width-1:0]),
29
  .data                       (data_in[lpm_width-1:0])
30
);
31
 
32
// NOTE: Bits data[lpm_size-1:0] are ANDed together to make result[0]
33
lpm_and
34
#( 1,                         // lpm_width (output width)
35
   1                          // lpm_size (inputs to each gate)
36
 ) lpm_and_example (
37
  .result                     (data_out[lpm_width-1:0]),
38
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
39
);
40
 
41
// NOTE: Bits data[lpm_size-1:0] are ORed together to make result[0]
42
lpm_or
43
#( 1,                         // lpm_width (output width)
44
   1                          // lpm_size (inputs to each gate)
45
 ) lpm_or_example (
46
  .result                     (data_out[lpm_width-1:0]),
47
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
48
);
49
 
50
// NOTE: Bits data_[lpm_size-1:0] are XORed together to make result[0]
51
lpm_xor
52
#( 1,                         // lpm_width (output width)
53
   1                          // lpm_size (inputs to each gate)
54
 ) lpm_xor_example (
55
  .result                     (data_out[lpm_width-1:0]),
56
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
57
);
58
 
59
lpm_bustri
60
#( 1                          // lpm_width
61
 ) lpm_bustri_example (
62
  .tridata                    (data_tristate[lpm_width-1:0]),
63
  .data                       (data_to_tristate[lpm_width-1:0]),    // CHOICE
64
  .enabledt                   (enable_data_to_tristate_bus_HIGH),   // OPTIONAL
65
  .result                     (data_from_tristate[lpm_width-1:0]),  // CHOICE
66
  .enabletr                   (enable_data_to_result_bus_HIGH),     // OPTIONAL
67
);
68
 
69
// NOTE: Bits data[lpm_size-1:0] are SELECTED to make result[0]
70
lpm_mux
71
#( 1,                         // lpm_width (output width)
72
   1,                         // lpm_size (inputs to each mux)
73
   1,                         // lpm_widths (number of bits in output select bus)
74
 
75
 ) lpm_mux_example (
76
  .result                     (data_out[lpm_width-1:0]),
77
  .data                       (data_in[(lpm_size*lpm_width)-1:0]),
78
  .sel                        (data_sel[lpm_widths-1:0]),
79
  .clock                      (clock_if_pipelined),              // OPTIONAL
80
  .clken                      (clock_enable_HIGH_if_pipelined),  // OPTIONAL
81
  .aclr                       (async_clear_if_pipelined)         // OPTIONAL
82
);
83
 
84
lpm_decode
85
#( 1,                         // lpm_width (number of bits in input to be decoded)
86
   1,                         // lpm_decodes (number of actual outputs decoded)
87
 
88
 ) lpm_decode_example (
89
  .eq                         (decodes_out[lpm_decodes-1:0]),
90
  .data                       (data_in[lpm_width:0]),
91
  .enable                     (force_all_outputs_LOW_when_LOW),  // OPTIONAL
92
  .clock                      (clock_if_pipelined),              // OPTIONAL
93
  .clken                      (clock_enable_HIGH_if_pipelined),  // OPTIONAL
94
  .aclr                       (async_clear_if_pipelined)         // OPTIONAL
95
);
96
 
97
lpm_clshift
98
#( 1,                         // lpm_width (width of input vector)
99
   1,                         // lpm_widthdist (width of shift distance port)
100
   "LOGICAL"                  // lpm_shifttype, optional, {LOGICAL, ROTATE, ARITHMETIC}
101
 ) lpm_clshift_example (
102
  .result                     (data_out[lpm_width-1:0]),
103
  .overflow                   (overflow_means_arith_bit_lost_or_result_became_0),  // OPTIONAL
104
  .underflow                  (underflow_means_result_became_0),  // OPTIONAL
105
  .data                       (data_in[lpm_width-1:0]),
106
  .direction                  (low_means_towards_LSB),  // OPTIONAL
107
  .distance                   (shift_distance[lpm_widthdist-1:0])
108
);
109
*/
110
 
111
//------------------------------------------------------------------------
112
// LPM Synthesizable Models
113
//------------------------------------------------------------------------
114
// Version 1.5 (lpm 220)      Date 12/17/99
115
//
116
// Modified LPM_ADD_SUB and LPM_MULT to accomodate LPM_WIDTH = 1.
117
//   Default values for LPM_WIDTH* are changed back to 1.
118
// Added LPM_HINT to LPM_DIVIDE.
119
// Rewritten LPM_FIFO_DC to output correctly.
120
// Modified LPM_FIFO to output 0s before first read, output correct
121
//   values after aclr and sclr, and output LPM_NUMWORDS mod
122
//   exp(2, LPM_WIDTHU) when FIFO is full.
123
//
124
//------------------------------------------------------------------------
125
// Version 1.4.1 (lpm 220)    Date 10/29/99
126
//
127
// Default values for LPM_WIDTH* of LPM_ADD_SUB and LPM_MULT are changed
128
//   from 1 to 2.
129
//
130
//------------------------------------------------------------------------
131
// Version 1.4 (lpm 220)      Date 10/18/99
132
//
133
// Default values for each optional inputs for ALL modules are added.
134
// Some LPM_PVALUE implementations were missing, and now implemented.
135
//
136
//------------------------------------------------------------------------
137
// Version 1.3 (lpm 220)      Date 06/23/99
138
//
139
// Corrected LPM_FIFO and LPM_FIFO_DC cout and empty/full flags.
140
// Implemented LPM_COUNTER cin/cout, and LPM_MODULUS is now working.
141
//
142
//------------------------------------------------------------------------
143
// Version 1.2 (lpm 220)      Date 06/16/99
144
//
145
// Added LPM_RAM_DP, LPM_RAM_DQ, LPM_IO, LPM_ROM, LPM_FIFO, LPM_FIFO_DC.
146
// Parameters and ports are added/discarded according to the spec.
147
//
148
//------------------------------------------------------------------------
149
// Version 1.1 (lpm 220)      Date 02/05/99
150
//
151
// Added LPM_DIVIDE module.
152
//
153
//------------------------------------------------------------------------
154
// Version 1.0                Date 07/09/97
155
//
156
//------------------------------------------------------------------------
157
// Excluded Functions:
158
//
159
//  LPM_FSM and LPM_TTABLE.
160
//
161
//------------------------------------------------------------------------
162
// Assumptions:
163
//
164
// 1. LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, and LPM_NUMWORDS,
165
//    LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE  default value is
166
//    string UNUSED.
167
//
168
//------------------------------------------------------------------------
169
// Verilog Language Issues:
170
//
171
// Two dimensional ports are not supported. Modules with two dimensional
172
// ports are implemented as one dimensional signal of (LPM_SIZE * LPM_WIDTH)
173
// bits wide.
174
//
175
//------------------------------------------------------------------------
176
// Synthesis Issues:
177
// 
178
// 1. LPM_COUNTER 
179
//
180
// Currently synthesis tools do not allow mixing of level and edge
181
// sensetive signals. To overcome that problem the "data" signal is
182
// removed from the clock always block of lpm_counter, however the
183
// synthesis result is accurate. For correct simulation add the "data"
184
// pin to the sensetivity list as follows:
185
//
186
//  always @(posedge clock or posedge aclr or posedge aset or 
187
//           posedge aload or data)
188
//------------------------------------------------------------------------
189
 
190
module lpm_constant ( result );
191
 
192
// NOTE: Parameters must be declared in the same order as the Properties
193
//       are specified in the Cell Specification document.
194
        parameter lpm_width = 1;
195
        parameter lpm_cvalue = 0;
196
        parameter lpm_strength = "UNUSED";
197
        parameter lpm_type = "lpm_constant";
198
        parameter lpm_hint = "UNUSED";
199
        parameter lpm_source_version = "lpm 220 version 1.6";
200
 
201
        output [lpm_width-1:0] result;
202
 
203
        assign result = lpm_cvalue;
204
 
205
// Check for previous Parameter declaration order
206
initial if ((lpm_width === "lpm_constant") || (lpm_type !== "lpm_constant"))
207
  begin
208
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
209
    $finish;
210
  end
211
endmodule // lpm_constant
212
 
213
//------------------------------------------------------------------------
214
 
215
module lpm_inv ( result, data );
216
 
217
// NOTE: Parameters must be declared in the same order as the Properties
218
//       are specified in the Cell Specification document.
219
        parameter lpm_width = 1;
220
        parameter lpm_type = "lpm_inv";
221
        parameter lpm_hint = "UNUSED";
222
        parameter lpm_source_version = "lpm 220 version 1.6";
223
 
224
        input  [lpm_width-1:0] data;
225
        output [lpm_width-1:0] result;
226
 
227
        reg    [lpm_width-1:0] result;
228
 
229
        always @(data)
230
        begin
231
                result = ~data;
232
        end
233
 
234
// Check for previous Parameter declaration order
235
initial if ((lpm_width === "lpm_inv") || (lpm_type !== "lpm_inv"))
236
  begin
237
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
238
    $finish;
239
  end
240
endmodule // lpm_inv
241
 
242
//------------------------------------------------------------------------
243
 
244
module lpm_and ( result, data );
245
 
246
// NOTE: Parameters must be declared in the same order as the Properties
247
//       are specified in the Cell Specification document.
248
        parameter lpm_width = 1;
249
        parameter lpm_size = 1;
250
        parameter lpm_type = "lpm_and";
251
        parameter lpm_hint = "UNUSED";
252
        parameter lpm_source_version = "lpm 220 version 1.6";
253
 
254
        input  [(lpm_size * lpm_width)-1:0] data;
255
        output [lpm_width-1:0] result;
256
 
257
        reg    [lpm_width-1:0] result;
258
        integer i, j, k;
259
 
260
        always @(data)
261
        begin
262
                for (i=0; i<lpm_width; i=i+1)
263
                begin
264
                        result[i] = data[i];
265
                        for (j=1; j<lpm_size; j=j+1)
266
                        begin
267
                                k = j * lpm_width + i;
268
                                result[i] = result[i] & data[k];
269
                        end
270
                end
271
        end
272
 
273
// Check for previous Parameter declaration order
274
initial if ((lpm_width === "lpm_and") || (lpm_type !== "lpm_and"))
275
  begin
276
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
277
    $finish;
278
  end
279
endmodule // lpm_and
280
 
281
//------------------------------------------------------------------------
282
 
283
module lpm_or ( result, data );
284
 
285
// NOTE: Parameters must be declared in the same order as the Properties
286
//       are specified in the Cell Specification document.
287
        parameter lpm_width = 1;
288
        parameter lpm_size = 1;
289
        parameter lpm_type = "lpm_or";
290
        parameter lpm_hint  = "UNUSED";
291
        parameter lpm_source_version = "lpm 220 version 1.6";
292
 
293
        input  [(lpm_size * lpm_width)-1:0] data;
294
        output [lpm_width-1:0] result;
295
 
296
        reg    [lpm_width-1:0] result;
297
        integer i, j, k;
298
 
299
        always @(data)
300
        begin
301
                for (i=0; i<lpm_width; i=i+1)
302
                begin
303
                        result[i] = data[i];
304
                        for (j=1; j<lpm_size; j=j+1)
305
                        begin
306
                                k = j * lpm_width + i;
307
                                result[i] = result[i] | data[k];
308
                        end
309
                end
310
        end
311
 
312
// Check for previous Parameter declaration order
313
initial if ((lpm_width === "lpm_or") || (lpm_type !== "lpm_or"))
314
  begin
315
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
316
    $finish;
317
  end
318
endmodule // lpm_or
319
 
320
//------------------------------------------------------------------------
321
 
322
module lpm_xor ( result, data );
323
 
324
// NOTE: Parameters must be declared in the same order as the Properties
325
//       are specified in the Cell Specification document.
326
        parameter lpm_width = 1;
327
        parameter lpm_size = 1;
328
        parameter lpm_type = "lpm_xor";
329
        parameter lpm_hint  = "UNUSED";
330
        parameter lpm_source_version = "lpm 220 version 1.6";
331
 
332
        input  [(lpm_size * lpm_width)-1:0] data;
333
        output [lpm_width-1:0] result;
334
 
335
        reg    [lpm_width-1:0] result;
336
        integer i, j, k;
337
 
338
        always @(data)
339
        begin
340
                for (i=0; i<lpm_width; i=i+1)
341
                begin
342
                        result[i] = data[i];
343
                        for (j=1; j<lpm_size; j=j+1)
344
                        begin
345
                                k = j * lpm_width + i;
346
                                result[i] = result[i] ^ data[k];
347
                        end
348
                end
349
        end
350
 
351
// Check for previous Parameter declaration order
352
initial if ((lpm_width === "lpm_xor") || (lpm_type !== "lpm_xor"))
353
  begin
354
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
355
    $finish;
356
  end
357
endmodule // lpm_xor
358
 
359
//------------------------------------------------------------------------
360
 
361
module lpm_bustri ( result, tridata, data, enabledt, enabletr );
362
 
363
// NOTE: Parameters must be declared in the same order as the Properties
364
//       are specified in the Cell Specification document.
365
        parameter lpm_width = 1;
366
        parameter lpm_type = "lpm_bustri";
367
        parameter lpm_hint = "UNUSED";
368
        parameter lpm_source_version = "lpm 220 version 1.6";
369
 
370
        input  [lpm_width-1:0] data;
371
        input  enabledt;
372
        input  enabletr;
373
        output [lpm_width-1:0] result;
374
        inout  [lpm_width-1:0] tridata;
375
 
376
        reg    [lpm_width-1:0] result;
377
        reg    [lpm_width-1:0] tmp_tridata;
378
 
379
        tri0  enabledt;
380
        tri0  enabletr;
381
        buf (i_enabledt, enabledt);
382
        buf (i_enabletr, enabletr);
383
 
384
        always @(data or tridata or i_enabletr or i_enabledt)
385
        begin
386
                if (i_enabledt == 0 && i_enabletr == 1)
387
                begin
388
                        result = tridata;
389
                        tmp_tridata = 'bz;
390
                end
391
                else if (i_enabledt == 1 && i_enabletr == 0)
392
                begin
393
                        result = 'bz;
394
                        tmp_tridata = data;
395
                end
396
                else if (i_enabledt == 1 && i_enabletr == 1)
397
                begin
398
                        result = data;
399
                        tmp_tridata = data;
400
                end
401
                else
402
                begin
403
                        result = 'bz;
404
                        tmp_tridata = 'bz;
405
                end
406
        end
407
 
408
        assign tridata = tmp_tridata;
409
 
410
// Check for previous Parameter declaration order
411
initial if ((lpm_width === "lpm_bustri") || (lpm_type !== "lpm_bustri"))
412
  begin
413
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
414
    $finish;
415
  end
416
endmodule // lpm_bustri
417
 
418
//------------------------------------------------------------------------
419
 
420
module lpm_mux ( result, clock, clken, data, aclr, sel );
421
 
422
// NOTE: Parameters must be declared in the same order as the Properties
423
//       are specified in the Cell Specification document.
424
        parameter lpm_width = 1;
425
        parameter lpm_size = 1;
426
        parameter lpm_widths = 1;
427
        parameter lpm_pipeline = 0;
428
        parameter lpm_type = "lpm_mux";
429
        parameter lpm_hint  = "UNUSED";
430
        parameter lpm_source_version = "lpm 220 version 1.6";
431
 
432
        input [(lpm_size * lpm_width)-1:0] data;
433
        input aclr;
434
        input clock;
435
        input clken;
436
        input [lpm_widths-1:0] sel;
437
        output [lpm_width-1:0] result;
438
 
439
        integer i, j, m, n;
440
        reg [lpm_width-1:0] tmp_result;
441
        reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0];
442
 
443
        tri0 aclr;
444
        tri0 clock;
445
        tri1 clken;
446
 
447
        buf (i_aclr, aclr);
448
        buf (i_clock, clock);
449
        buf (i_clken, clken);
450
 
451
        always @(data or sel)
452
        begin
453
                tmp_result = 0;
454
                for (m=0; m<lpm_width; m=m+1)
455
                begin
456
                        n = sel * lpm_width + m;
457
                        tmp_result[m] = data[n];
458
                end
459
        end
460
 
461
        always @(posedge i_clock or posedge i_aclr)
462
        begin
463
                if (i_aclr)
464
                begin
465
                        for (i = 0; i <= lpm_pipeline; i = i + 1)
466
                                tmp_result2[i] = 'b0;
467
                end
468
                else if (i_clken == 1)
469
                begin
470
                        tmp_result2[lpm_pipeline] = tmp_result;
471
                        for (j = 0; j < lpm_pipeline; j = j +1)
472
                                tmp_result2[j] = tmp_result2[j+1];
473
                end
474
        end
475
 
476
        assign result = (lpm_pipeline > 0) ? tmp_result2[0] : tmp_result;
477
 
478
// Check for previous Parameter declaration order
479
initial if ((lpm_width === "lpm_mux") || (lpm_type !== "lpm_mux"))
480
  begin
481
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
482
    $finish;
483
  end
484
endmodule // lpm_mux
485
 
486
//------------------------------------------------------------------------
487
 
488
module lpm_decode ( eq, data, enable, clock, clken, aclr );
489
 
490
// NOTE: Parameters must be declared in the same order as the Properties
491
//       are specified in the Cell Specification document.
492
        parameter lpm_width = 1;
493
        parameter lpm_decodes = 1 << lpm_width;
494
        parameter lpm_pipeline = 0;
495
        parameter lpm_type = "lpm_decode";
496
        parameter lpm_hint = "UNUSED";
497
        parameter lpm_source_version = "lpm 220 version 1.6";
498
 
499
        input  [lpm_width-1:0] data;
500
        input  enable;
501
        input  clock;
502
        input  clken;
503
        input  aclr;
504
        output [lpm_decodes-1:0] eq;
505
 
506
        reg    [lpm_decodes-1:0] tmp_eq2 [lpm_pipeline:0];
507
        reg    [lpm_decodes-1:0] tmp_eq;
508
        integer i, j;
509
 
510
        tri0   clock;
511
        tri1   clken;
512
        tri0   aclr;
513
        tri1   enable;
514
 
515
        buf (i_clock, clock);
516
        buf (i_clken, clken);
517
        buf (i_aclr, aclr);
518
        buf (i_enable, enable);
519
 
520
 
521
        always @(data or i_enable)
522
        begin
523
                tmp_eq = 0;
524
                if (i_enable)
525
                begin
526
                        if ((data < lpm_decodes))
527
                        begin
528
                                tmp_eq[data] = 1'b1;
529
                        end
530
                else
531
                        tmp_eq = 0;
532
                end
533
        end
534
 
535
        always @(posedge i_clock or posedge i_aclr)
536
        begin
537
                if (i_aclr)
538
                begin
539
                        for (i = 0; i <= lpm_pipeline; i = i + 1)
540
                                tmp_eq2[i] = 'b0;
541
                end
542
                else if (clken == 1)
543
                begin
544
                        tmp_eq2[lpm_pipeline] = tmp_eq;
545
                        for (j = 0; j < lpm_pipeline; j = j +1)
546
                                tmp_eq2[j] = tmp_eq2[j+1];
547
                end
548
        end
549
 
550
        assign eq = (lpm_pipeline > 0) ? tmp_eq2[0] : tmp_eq;
551
 
552
// Check for previous Parameter declaration order
553
initial if ((lpm_width === "lpm_decode") || (lpm_type !== "lpm_decode"))
554
  begin
555
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
556
    $finish;
557
  end
558
endmodule // lpm_decode
559
 
560
//------------------------------------------------------------------------
561
 
562
module lpm_clshift ( result, overflow, underflow, data, direction, distance );
563
 
564
// NOTE: Parameters must be declared in the same order as the Properties
565
//       are specified in the Cell Specification document.
566
        parameter lpm_width = 1;
567
        parameter lpm_widthdist = 1;
568
        parameter lpm_shifttype = "LOGICAL";
569
        parameter lpm_type = "lpm_clshift";
570
        parameter lpm_hint = "UNUSED";
571
        parameter lpm_source_version = "lpm 220 version 1.6";
572
 
573
        input  [lpm_width-1:0] data;
574
        input  [lpm_widthdist-1:0] distance;
575
        input  direction;
576
        output [lpm_width-1:0] result;
577
        output overflow;
578
        output underflow;
579
 
580
        reg    [lpm_width-1:0] ONES;
581
        reg    [lpm_width-1:0] result;
582
        reg    overflow, underflow;
583
        integer i;
584
 
585
        tri0  direction;
586
 
587
        buf (i_direction, direction);
588
 
589
//---------------------------------------------------------------//
590
        function [lpm_width+1:0] LogicShift;
591
                input [lpm_width-1:0] data;
592
                input [lpm_widthdist-1:0] dist;
593
                input direction;
594
                reg   [lpm_width-1:0] tmp_buf;
595
                reg   overflow, underflow;
596
 
597
                begin
598
                        tmp_buf = data;
599
                        overflow = 1'b0;
600
                        underflow = 1'b0;
601
                        if ((direction) && (dist > 0)) // shift right
602
                        begin
603
                                tmp_buf = data >> dist;
604
                                if ((data != 0) && ((dist >= lpm_width) || (tmp_buf == 0)))
605
                                        underflow = 1'b1;
606
                        end
607
                        else if (dist > 0) // shift left
608
                        begin
609
                                tmp_buf = data << dist;
610
                                if ((data != 0) && ((dist >= lpm_width)
611
                                        || ((data >> (lpm_width-dist)) != 0)))
612
                                        overflow = 1'b1;
613
                        end
614
                        LogicShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
615
                end
616
        endfunction
617
 
618
//---------------------------------------------------------------//
619
        function [lpm_width+1:0] ArithShift;
620
                input [lpm_width-1:0] data;
621
                input [lpm_widthdist-1:0] dist;
622
                input direction;
623
                reg   [lpm_width-1:0] tmp_buf;
624
                reg   overflow, underflow;
625
 
626
                begin
627
                        tmp_buf = data;
628
                        overflow = 1'b0;
629
                        underflow = 1'b0;
630
 
631
                        if (direction && (dist > 0))   // shift right
632
                        begin
633
                                if (data[lpm_width-1] == 0) // positive number
634
                                begin
635
                                        tmp_buf = data >> dist;
636
                                        if ((data != 0) && ((dist >= lpm_width) || (tmp_buf == 0)))
637
                                                underflow = 1'b1;
638
                                end
639
                                else // negative number
640
                                begin
641
                                        tmp_buf = (data >> dist) | (ONES << (lpm_width - dist));
642
                                        if ((data != ONES) && ((dist >= lpm_width-1) || (tmp_buf == ONES)))
643
                                                underflow = 1'b1;
644
                                end
645
                        end
646
                        else if (dist > 0) // shift left
647
                        begin
648
                                tmp_buf = data << dist;
649
                                if (data[lpm_width-1] == 0) // positive number
650
                                begin
651
                                        if ((data != 0) && ((dist >= lpm_width-1)
652
                                        || ((data >> (lpm_width-dist-1)) != 0)))
653
                                                overflow = 1'b1;
654
                                end
655
                                else // negative number
656
                                begin
657
                                        if ((data != ONES) && ((dist >= lpm_width)
658
                                        || (((data >> (lpm_width-dist-1))|(ONES << (dist+1))) != ONES)))
659
                                                overflow = 1'b1;
660
                                end
661
                        end
662
                        ArithShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
663
                end
664
        endfunction
665
 
666
//---------------------------------------------------------------//
667
        function [lpm_width-1:0] RotateShift;
668
                input [lpm_width-1:0] data;
669
                input [lpm_widthdist-1:0] dist;
670
                input direction;
671
                reg   [lpm_width-1:0] tmp_buf;
672
 
673
                begin
674
                        tmp_buf = data;
675
                        if ((direction) && (dist > 0)) // shift right
676
                        begin
677
                                tmp_buf = (data >> dist) | (data << (lpm_width - dist));
678
                        end
679
                        else if (dist > 0) // shift left
680
                        begin
681
                                tmp_buf = (data << dist) | (data >> (lpm_width - dist));
682
                        end
683
                        RotateShift = tmp_buf[lpm_width-1:0];
684
                end
685
        endfunction
686
//---------------------------------------------------------------//
687
 
688
        initial
689
        begin
690
                for (i=0; i < lpm_width; i=i+1)
691
                        ONES[i] = 1'b1;
692
        end
693
 
694
        always @(data or i_direction or distance)
695
        begin
696
                // lpm_shifttype is optional and default to LOGICAL
697
                if ((lpm_shifttype == "LOGICAL"))
698
                begin
699
                        {overflow,underflow,result} = LogicShift(data,distance,i_direction);
700
                end
701
                else if (lpm_shifttype == "ARITHMETIC")
702
                begin
703
                        {overflow,underflow,result} = ArithShift(data,distance,i_direction);
704
                end
705
                else if (lpm_shifttype == "ROTATE")
706
                begin
707
                        result = RotateShift(data, distance, i_direction);
708
                        overflow = 1'b0;
709
                        underflow = 1'b0;
710
                end
711
                else
712
                begin
713
                        result = 'bx;
714
                        overflow = 1'b0;
715
                        underflow = 1'b0;
716
                end
717
        end
718
 
719
// Check for previous Parameter declaration order
720
initial if ((lpm_width === "lpm_clshift") || (lpm_type !== "lpm_clshift"))
721
  begin
722
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
723
    $finish;
724
  end
725
endmodule // lpm_clshift

powered by: WebSVN 2.1.0

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