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

Subversion Repositories xmatchpro

[/] [xmatchpro/] [trunk/] [xmw4-comdec/] [src/] [bit_arith.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 eejlny
--D  sccsid @(#)bit_arith.vhdl  1.3 daisy(C) 2/13/95 /files1/SCCS.model/bvhdl/vhdl_packages/dzx/src/s.bit_arith.vhdl
2
-------------------------------------------------------------------------------
3
--    File: Bit_Arith
4
-------------------------------------------------------------------------------
5
 
6
package Bit_Arith is
7
 
8
    --=============================
9
    -- Bit_Vector arithemetics   --
10
    --=============================
11
 
12
    ----------------------------
13
    -- Bit_Vector Basic Types --
14
    ----------------------------
15
 
16
    subtype nibble is Bit_Vector ( 3 downto 0 ) ;
17
    subtype byte   is Bit_Vector ( 7 downto 0 ) ;
18
    subtype word   is Bit_Vector (15 downto 0 ) ;
19
    subtype long   is Bit_Vector (31 downto 0 ) ;
20
 
21
    -------------------------
22
    -- Conversion routines --
23
    -------------------------
24
 
25
    function To_Integer    (v : Bit_Vector) return Integer;
26
    function To_BitVector (i : Integer) return Long;
27
    function To_BitVector (i, size : Integer) return Bit_Vector;
28
 
29
    ------------------------------
30
    -- Bit_Vector OP Bit_Vector --
31
    ------------------------------
32
 
33
    function "+" ( left , right : Bit_Vector ) return Bit_Vector ;
34
    function "-" ( left , right : Bit_Vector ) return Bit_Vector ;
35
    function "*" ( left , right : Bit_Vector ) return Bit_Vector ;
36
    function "/" ( left , right : Bit_Vector ) return Bit_Vector ;
37
 
38
    function "mod" ( left , right : Bit_Vector ) return Bit_Vector ;
39
    function "rem" ( left , right : Bit_Vector ) return Bit_Vector ;
40
 
41
 
42
    ---------------------------
43
    -- Bit_Vector OP Integer --
44
    ---------------------------
45
 
46
    function "+" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
47
    function "-" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
48
    function "*" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
49
    function "/" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
50
 
51
    function "mod" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
52
    function "rem" ( left : Bit_Vector ; right : Integer ) return Bit_Vector ;
53
 
54
 
55
    ----------------------------
56
    -- Integer OP Bit_Vector  --
57
    ----------------------------
58
 
59
    function "+" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
60
    function "-" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
61
    function "*" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
62
    function "/" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
63
 
64
    function "mod" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
65
    function "rem" ( left : Integer ; right : Bit_Vector ) return Bit_Vector ;
66
 
67
    -------------------------------------------------
68
    -- Bit_Vector Extension & Truncation functions --
69
    -------------------------------------------------
70
    function ext      ( b : Bit_Vector ; size : Integer ) return Bit_Vector ;
71
    function trunc    ( b : Bit_Vector ; size : Integer ) return Bit_Vector ;
72
 
73
    --==================================
74
    -- SIGNED & UNSIGNED arithemetics --
75
    --==================================
76
 
77
    ------------------
78
    -- Basic types: --
79
    ------------------
80
    type Unsigned is array (Natural range <>) of Bit;
81
    type Signed is array (Natural range <>) of Bit;
82
 
83
    subtype UNnibble is Unsigned ( 3 downto 0 ) ;
84
    subtype UNbyte   is Unsigned ( 7 downto 0 ) ;
85
    subtype UNword   is Unsigned (15 downto 0 ) ;
86
    subtype UNlong   is Unsigned (31 downto 0 ) ;
87
 
88
    subtype SInibble is Signed ( 3 downto 0 ) ;
89
    subtype SIbyte   is Signed ( 7 downto 0 ) ;
90
    subtype SIword   is Signed (15 downto 0 ) ;
91
    subtype SIlong   is Signed (31 downto 0 ) ;
92
 
93
    ---------------------------
94
    -- Conversion functions: --
95
    ---------------------------
96
 
97
    function To_Integer (u : Unsigned) return Integer;
98
    function To_Integer (s: Signed) return Integer;
99
 
100
    function To_BitVector (u: Unsigned; size : Integer) return Bit_Vector;
101
 
102
    function To_Unsigned (i, size : Integer) return Unsigned;
103
    function To_Unsigned (s: Signed; size: Integer)  return Unsigned;
104
    function To_Unsigned (u: Unsigned; size: Integer)  return Unsigned;
105
 
106
    function To_Signed (i, size : Integer)  return Signed;
107
    function To_Signed (u : Unsigned; size : Integer) return Signed;
108
    function To_Signed (s: Signed; size: Integer) return Signed;
109
 
110
    ----------------------------------
111
    -- Binary arithmetic functions: --
112
    ----------------------------------
113
 
114
    function "+" (L: Unsigned; R: Unsigned) return Unsigned;
115
    function "+" (L: Signed;   R: Signed)   return Signed;
116
-- ADDED following 4 lines: BHASKER:
117
    function "+" (L: Signed;   R: INTEGER)   return Signed;
118
    function "+" (L: INTEGER;   R: Signed)   return Signed;
119
    function "+" (L: Unsigned;   R: INTEGER)   return Unsigned;
120
    function "+" (L: INTEGER;   R: Unsigned)   return Unsigned;
121
 
122
    function "-" (L: Unsigned; R: Unsigned) return Unsigned;
123
    function "-" (L: Signed;   R: Signed)   return Signed;
124
-- ADDED following 4 lines: BHASKER:
125
    function "-" (L: Signed;   R: INTEGER)   return Signed;
126
    function "-" (L: INTEGER;   R: Signed)   return Signed;
127
    function "-" (L: Unsigned;   R: INTEGER)   return Unsigned;
128
    function "-" (L: INTEGER;   R: Unsigned)   return Unsigned;
129
 
130
    function "*" (L: Unsigned; R: Unsigned) return Unsigned;
131
    function "*" (L: Signed; R: Signed) return Signed;
132
 
133
    function "/" (L: Unsigned; R: Unsigned) return Unsigned;
134
    function "/" (L: Signed; R: Signed) return Signed;
135
 
136
    function "mod" (L: Unsigned; R: Unsigned) return Unsigned;
137
    function "mod" (L: Signed; R: Signed) return Signed;
138
 
139
    function "rem" (L: Unsigned; R: Unsigned) return Unsigned;
140
    function "rem" (L: Signed; R: Signed) return Signed;
141
 
142
    ---------------------------------
143
    -- Unary arithmetic functions: --
144
    ---------------------------------
145
 
146
    function "-" (L: Signed) return Signed;
147
    function "abs" (L: Signed) return Signed;
148
 
149
    ---------------------------
150
    -- Comparison functions: --
151
    ---------------------------
152
    function "<" (L: Unsigned; R: Unsigned) return Boolean;
153
    function "<" (L: Signed;   R: Signed)   return Boolean;
154
 
155
    function "<=" (L: Unsigned; R: Unsigned) return Boolean;
156
    function "<=" (L: Signed;   R: Signed)   return Boolean;
157
 
158
    function ">=" (L: Unsigned; R: Unsigned) return Boolean;
159
    function ">=" (L: Signed;   R: Signed)   return Boolean;
160
 
161
    function ">" (L: Unsigned; R: Unsigned) return Boolean;
162
    function ">" (L: Signed;   R: Signed)   return Boolean;
163
 
164
    function "=" (L: Unsigned; R: Integer)  return Boolean;
165
    function "=" (L: Unsigned; R: Unsigned) return Boolean;
166
    function "=" (L: Signed;   R: Signed)   return Boolean;
167
 
168
    function "/=" (L: Unsigned; R: Unsigned) return Boolean;
169
    function "/=" (L: Signed;   R: Signed)   return Boolean;
170
 
171
    ------------------------
172
    -- Shift   functions: --
173
    ------------------------
174
 
175
    function Shift_Left  (u : Unsigned; size : Natural) return Unsigned;
176
    function Shift_Left  (s: Signed;    size : Natural) return Signed;
177
    function Shift_Right (u: Unsigned;  size : Natural)  return Unsigned;
178
    function Shift_Right (s: Signed;    size : Natural)  return Signed;
179
 
180
    -------------------------------
181
    -- preset / clear procedure: --
182
    -------------------------------
183
    procedure Preset_Clear (signal FF: out Unsigned; Pc_Value: Unsigned);
184
    procedure Preset_Clear (signal FF: out Signed; Pc_Value: Signed);
185
 
186
  -------------------------
187
  -- types for MacroSyn: --
188
  -------------------------
189
 
190
  type Bcd_Bit_Vector is array (Natural range <>) of Bit;
191
  type Johnson_Bit_Vector is array (Natural range <>) of Bit;
192
  type Xs_3_Bit_Vector is array (Natural range <>) of Bit;
193
  type Xs_3_Gray_Bit_Vector is array (Natural range <>) of Bit;
194
 
195
  ----------------------------------------
196
  -- conversion functions for MacroSyn: --
197
  ----------------------------------------
198
  function To_Integer (opd: Bcd_Bit_Vector) return Integer;
199
  function To_Integer (opd: Xs_3_Bit_Vector) return Integer;
200
  function To_Integer (opd: Xs_3_Gray_Bit_Vector) return Integer;
201
  function To_Integer (opd: Johnson_Bit_Vector) return Integer;
202
 
203
 
204
    attribute BUILT_IN: Boolean;                           --D
205
    attribute BUILT_IN of EXT: function is TRUE;           --D
206
    attribute BUILT_IN of TRUNC: function is TRUE;         --D
207
    attribute BUILT_IN of Shift_Left: function is TRUE;    --D
208
    attribute BUILT_IN of Shift_Right: function is TRUE;   --D
209
    attribute BUILT_IN of Preset_Clear: procedure is TRUE; --D
210
 
211
   attribute Built_In of To_Integer   : function is TRUE;   --D
212
   attribute Built_In of To_BitVector : function is TRUE;   --D
213
   attribute Built_In of To_Unsigned  : function is TRUE;   --D
214
   attribute Built_In of To_Signed    : function is TRUE;   --D
215
 
216
--****** 4 NEW LINES Added: BHASKER:
217
  function MAX (L, R: INTEGER) return INTEGER;
218
  function MIN (L, R: INTEGER) return INTEGER;
219
 
220
  attribute BUILT_IN of MAX: function is TRUE;
221
  attribute BUILT_IN of MIN: function is TRUE;
222
 
223
end Bit_Arith;
224
 
225
package body Bit_Arith is
226
 
227
    ----------------
228
    -- Utilities: --
229
    ----------------
230
  function Max (L, R: Integer) return Integer is
231
  begin
232
    if (L > R) then
233
      return L;
234
    else
235
      return R;
236
    end if;
237
  end Max;
238
 
239
  function Min (L, R: Integer) return Integer is
240
  begin
241
    if (L < R) then
242
      return L;
243
    else
244
      return R;
245
    end if;
246
  end Min;
247
 
248
    ----------------------------------
249
    -- Error Messages and Procedure --
250
    ----------------------------------
251
 
252
    constant LongVec   : string := "Vector is longer then 32" ;
253
    constant TruncSize : string := "Truncate to a bigger size" ;
254
    constant TruncErr  : string := "Overflow" ;
255
    constant ExtSize   : string := "Extension to a smaller size" ;
256
    constant I2bSize   : string := "Size is bigger then 32" ;
257
    constant OpLen     : string := "Operands are not in the same length" ;
258
    constant Undef     : string := "Undef bit in Dbit vector arithmetic" ;
259
    constant OvrflPlus : string := "Overflow occurred during a + operation; Carry ignored.";
260
    constant OvrflMinus: string := "Overflow occurred during a - operation; Borrow ignored.";
261
    constant ToBVSize  : string := "Number of bits specified is less than that of input operand: extra bits truncated.";
262
    constant ToUNeg    : string := "Input operand cannot be negative.";
263
    constant ToUBitNo  : string := "Number of bits specified is less than that of input operand: extra bits truncated.";
264
    constant ToUPos    : string := "Input operand must be non-negative.";
265
    constant ToSBitNo  : string := "Number of bits specified is less than that of input operand: extra bits truncated.";
266
    constant LongSize  : string := "Size of operand cannot be more than 32.";
267
    constant ShiftBitNo: string := "Shift: No of bits greater than or equal to operand bit width";
268
    constant size_9    : string := "A BCD digit cannot be more than 9.";
269
    constant Axcess_3_Gray : string := "An invalid Excess-3 GRAY digit.";
270
 
271
    procedure Message ( s : String ; v : Severity_Level) is
272
    begin
273
            assert false report s severity v;
274
    end Message;
275
 
276
 
277
 
278
    ----------------------------------------
279
    -- Bit_Vector <=> Integer Conversions --
280
    ----------------------------------------
281
 
282
    function To_Integer ( v : Bit_Vector ) return Integer is
283
    begin
284
        return To_integer (Unsigned(v));
285
    end To_Integer ;
286
 
287
    function To_BitVector ( i : Integer ) return long is
288
    begin
289
        return Long(To_Unsigned(i, 32));
290
    end To_BitVector;
291
 
292
 
293
    -------------------------------------------------
294
    -- Bit_Vector Extension & Truncation functions --
295
    -------------------------------------------------
296
 
297
    function ext ( b : Bit_Vector ; size : Integer ) return Bit_Vector is
298
    variable ret : Bit_Vector ( size - 1 downto 0 ) ;
299
    begin
300
        if b'length > size then
301
            Message (ExtSize, Error) ;
302
            return (b) ;
303
        end if ;
304
 
305
        ret(b'length-1 downto 0) := b ;
306
 
307
        return(ret) ;
308
    end ext ;
309
 
310
 
311
    function trunc ( b : Bit_Vector ; size : Integer ) return Bit_Vector is
312
    variable ret : Bit_Vector ( size - 1 downto 0 ) ;
313
    variable inx: natural := 0;
314
    begin
315
        if b'length < size then
316
            Message (TruncSize, Error) ;
317
            return (b) ;
318
        end if ;
319
 
320
        -- ret := b(size-1 downto 0) ;
321
 
322
        for I in b'reverse_range loop
323
           ret(inx) := b(I);
324
           inx := inx + 1;
325
           exit when inx >= size;
326
        end loop;
327
 
328
        return ret;
329
    end trunc ;
330
 
331
 
332
    function To_BitVector ( i , size : Integer ) return Bit_Vector is
333
    begin
334
        return Bit_Vector(To_Unsigned(i, size));
335
    end  To_BitVector;
336
 
337
 
338
    ------------------------------
339
    -- Bit_Vector OP Bit_Vector --
340
    ------------------------------
341
 
342
    function "+" ( left , right : Bit_Vector ) return Bit_Vector is
343
    begin
344
      return Bit_Vector((Unsigned(left) + Unsigned(right)));
345
    end "+" ;
346
 
347
    function "-" ( left , right : Bit_Vector ) return Bit_Vector is
348
    begin
349
      return Bit_Vector((Unsigned(left) - Unsigned(right)));
350
    end "-" ;
351
 
352
    function "*" ( left , right : Bit_Vector ) return Bit_Vector is
353
    begin
354
      return Bit_Vector((Unsigned(left) * Unsigned(right)));
355
    end "*" ;
356
 
357
    function "/" ( left , right : Bit_Vector ) return Bit_Vector is
358
    begin
359
      return Bit_Vector((Unsigned(left) / Unsigned(right)));
360
    end "/" ;
361
 
362
    function "mod" ( left , right : Bit_Vector ) return Bit_Vector is
363
    begin
364
      return Bit_Vector((Unsigned(left) mod Unsigned(right)));
365
    end "mod" ;
366
 
367
    function "rem" ( left , right : Bit_Vector ) return Bit_Vector is
368
    begin
369
      return Bit_Vector((Unsigned(left) rem Unsigned(right)));
370
    end "rem" ;
371
 
372
    ---------------------------
373
    -- Integer OP Bit_Vector --
374
    ---------------------------
375
 
376
    function "+" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
377
    begin
378
        return Bit_Vector(To_Unsigned (left, right'length) + Unsigned(right));
379
    end "+" ;
380
 
381
    function "-" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
382
    begin
383
        return Bit_Vector(To_Unsigned(left, right'length) - Unsigned(right));
384
    end "-" ;
385
 
386
    function "*" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
387
    begin
388
        return Bit_Vector(To_Unsigned(left, right'length) * Unsigned(right));
389
    end "*" ;
390
 
391
    function "/" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
392
    begin
393
        return Bit_Vector(To_Unsigned (left, right'length) / Unsigned(right));
394
    end "/" ;
395
 
396
    function "mod" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
397
    begin
398
        return Bit_Vector(To_Unsigned (left, right'length) mod Unsigned(right));
399
    end "mod" ;
400
 
401
    function "rem" ( left : Integer ; right : Bit_Vector ) return Bit_Vector is
402
    begin
403
        return Bit_Vector(To_Unsigned (left, right'length) rem Unsigned(right));
404
    end "rem" ;
405
 
406
 
407
    ---------------------------
408
    -- Bit_Vector OP Integer --
409
    ---------------------------
410
 
411
    function "+"  ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
412
    begin
413
        return Bit_Vector(Unsigned(left) + To_Unsigned(right, left'length));
414
    end "+" ;
415
 
416
    function "-" ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
417
    begin
418
        return Bit_Vector(Unsigned(left) - To_Unsigned(right, left'length));
419
    end "-" ;
420
 
421
    function "*" ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
422
    begin
423
        return Bit_Vector(Unsigned(left) * To_Unsigned(right, left'length));
424
    end "*" ;
425
 
426
    function "/" ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
427
    begin
428
        return Bit_Vector(Unsigned(left) / To_Unsigned(right, left'length));
429
    end "/" ;
430
 
431
    function "mod" ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
432
    begin
433
        return Bit_Vector(Unsigned(left) mod To_Unsigned(right, left'length));
434
    end "mod" ;
435
 
436
    function "rem" ( left : Bit_Vector ; right : Integer ) return Bit_Vector is
437
    begin
438
        return Bit_Vector(Unsigned(left) rem To_Unsigned(right, left'length));
439
    end "rem" ;
440
 
441
    --============================
442
    -- Signed/Unsigned routines --
443
    --============================
444
 
445
  function Downto_Dir (OPD: Unsigned) return Unsigned is
446
    variable ret: Unsigned (OPD'length-1 downto 0);
447
  begin
448
    if (OPD'left > OPD'right) then -- if already downto 
449
      ret := OPD;
450
    else
451
      for J in OPD'RANGE loop
452
        ret(OPD'right-J) := OPD(J);
453
      end loop;
454
    end if;
455
 
456
    return ret;
457
  end;
458
 
459
  function Downto_Dir (OPD: Signed) return Signed is
460
    variable ret: Signed (OPD'length-1 downto 0);
461
  begin
462
    if (OPD'left > OPD'right) then -- if already downto  
463
      ret := OPD;
464
    else
465
      for J in OPD'RANGE loop
466
        ret(OPD'right-J) := OPD(J);
467
      end loop;
468
    end if;
469
 
470
    return ret;
471
  end;
472
 
473
  function Get_Magnitude (OPD: Signed) return Unsigned is
474
    -- returns the magnitude of the input Signed operand.
475
    -- Input is a negative number.
476
    variable RET: Unsigned (OPD'length-1 downto 0);
477
    variable FOUND_1: BOOLEAN := FALSE;
478
  begin
479
    RET := UNSIGNED(OPD);
480
 
481
    -- Search for first 1 from right, after that complement every bit:
482
    for J in RET'REVERSE_RANGE loop
483
      if FOUND_1 then
484
        RET(J) := not RET(J);
485
      elsif RET(J) = '1' then
486
          FOUND_1 := TRUE;
487
      end if;
488
    end loop;
489
 
490
    return RET;
491
  end Get_Magnitude;
492
 
493
  function Unsigned_Plus (L: Unsigned; R: Unsigned) return Unsigned is
494
    -- Special Plus function: input sizes must be same and also must be
495
    -- downto dir, with 'right = 0, i.e. 15 downto 0 for example.
496
    variable CARRY: BIT := '0';
497
    variable SUM: Unsigned (L'left downto 0);
498
  begin
499
    for K in L'REVERSE_RANGE loop -- from 0th bit which is LSB.
500
      SUM(K) := L(K) xor R(K) xor CARRY;
501
      CARRY := (L(K) or R(K)) and (L(K) or CARRY) and (CARRY or R(K));
502
    end loop;
503
 
504
    if (CARRY = '1') then
505
        Message (OvrflPlus, Note);
506
    end if;
507
 
508
    return SUM;
509
  end;
510
 
511
  function Signed_Plus (L: Signed; R: Signed) return Signed is
512
    -- Identical functionality to Unsigned_Plus function.
513
    -- Special Plus function: input sizes must be same and also must be
514
    -- downto dir, with 'right = 0, i.e. 15 downto 0 for example.
515
    variable CARRY: BIT := '0';
516
    variable LAST_CARRY: BIT := '0';
517
    variable SUM: Signed (L'left downto 0);
518
  begin
519
    for K in L'REVERSE_RANGE loop -- from 0th bit which is LSB.
520
      SUM(K) := L(K) xor R(K) xor CARRY;
521
      LAST_CARRY := CARRY;
522
      CARRY := (L(K) or R(K)) and (L(K) or CARRY) and (CARRY or R(K));
523
    end loop;
524
 
525
    if (CARRY /= LAST_CARRY) then
526
        Message (OvrflPlus, Note);
527
    end if;
528
 
529
    return SUM;
530
  end;
531
 
532
  function Unsigned_Minus (L: Unsigned; R: Unsigned) return Unsigned is
533
    -- Special Minus function: input sizes must be same and also must be
534
    -- downto dir, with 'right = 0, i.e. 15 downto 0 for example.
535
    variable BORROW: BIT := '0';
536
    variable DIFF: Unsigned (L'left downto 0);
537
  begin
538
    for K in L'REVERSE_RANGE loop -- from 0th bit which is LSB.
539
      DIFF(K) := L(K) xor R(K) xor BORROW;
540
      BORROW := (not L(K) and (BORROW or (R(K) and not BORROW))) or
541
                  (L(K) and R(K) and BORROW);
542
    end loop;
543
 
544
    if (BORROW  = '1') then
545
        Message (OvrflMinus, Note);
546
    end if;
547
 
548
    return DIFF;
549
  end;
550
 
551
 
552
  function Signed_Minus (L: Signed; R: Signed) return Signed is
553
    -- Identical functionality to Unsigned_Minus.
554
    -- Special Minus function: input sizes must be same and also must be
555
    -- downto dir, with 'right = 0, i.e. 15 downto 0 for example. 
556
    variable BORROW: BIT := '0';
557
    variable LAST_BORROW: BIT := '0';
558
    variable DIFF: Signed (L'left downto 0);
559
  begin
560
    for K in L'REVERSE_RANGE loop -- from 0th bit which is LSB.
561
      DIFF(K) := L(K) xor R(K) xor BORROW;
562
      LAST_BORROW := BORROW;
563
      BORROW := (not L(K) and (BORROW or (R(K) and not BORROW))) or
564
                  (L(K) and R(K) and BORROW);
565
    end loop;
566
 
567
    if (BORROW  /= LAST_BORROW) then
568
        Message (OvrflMinus, Note);
569
    end if;
570
 
571
    return DIFF;
572
  end;
573
 
574
  function Less_Than (L: Signed; R: Signed) return Boolean is
575
    -- Special function: inputs of same size and decr range and 'right is 0.
576
  begin
577
    if (L(L'left) /= R(R'left)) then -- compare signs.
578
      return (L(L'left) = '1');
579
    end if;
580
 
581
    for J in L'left-1 downto 0 loop -- compae from MSB.
582
      if L(J) /= R(J) then
583
        return (R(J) = '1');
584
      end if;
585
    end loop;
586
 
587
    return FALSE;
588
  end Less_Than;
589
 
590
  function Less_Than_Or_Equal_To (L: Signed; R: Signed) return Boolean is
591
    -- Special function: inputs of same size and decr range and 'right is 0.
592
  begin
593
    if (L(L'left) /= R(R'left)) then -- compare signs. 
594
      return (L(L'left) = '1');
595
    end if;
596
 
597
    for J in L'left-1 downto 0 loop -- compae from MSB. 
598
      if L(J) /= R(J) then
599
        return (R(J) = '1');
600
      end if;
601
    end loop;
602
 
603
    return TRUE;
604
  end Less_Than_Or_Equal_To;
605
 
606
  function EQUAL_TO (L: Signed; R: Signed) return Boolean is
607
    -- Special function: inputs of same size and decr range and 'right is 0.
608
  begin
609
    for J in L'RANGE loop -- start from MSB.
610
      if L(J) /= R(J) then
611
        return FALSE;
612
      end if;
613
    end loop;
614
 
615
    return TRUE;
616
  end EQUAL_TO;
617
 
618
    ---------------------------
619
    -- Conversion functions: --
620
    ---------------------------
621
 
622
    function To_Integer (u: Unsigned) return Integer is
623
      variable ret: Integer;
624
    begin
625
      -- First check if size of input is less than 32 bits, the Max int value.
626
        if (u'length >= 32) then
627
            Message (LongVec, Error);
628
        end if;
629
 
630
      ret := 0;
631
      -- Remember: leftmost is MSB; DO NOT go by index value of u, i.e u(0)
632
      -- may also be the MSB.
633
 
634
      for M3 in u'RANGE loop -- Start from MSB first.
635
        ret := ret * 2;
636
 
637
        if u(M3) = '1' then
638
          ret := ret + 1;
639
        end if;
640
      end loop;
641
 
642
      return ret;
643
    end To_Integer;
644
 
645
 
646
    function To_Integer (s: Signed) return Integer is
647
      variable ret: Integer;
648
    begin
649
      -- First check if size of input is less than 32 bits, the Max int value.
650
      if (s'length >= 32) then
651
          Message (LongVec , Error);
652
      end if;
653
 
654
      ret := 0;
655
 
656
      for M3 in s'RANGE loop
657
        ret := ret * 2;
658
 
659
        if s(M3) = '1' then
660
          ret := ret + 1;
661
        end if;
662
      end loop;
663
 
664
      -- now check if it was a Positive or a negative number.
665
      if (s(s'left) = '1') then -- Negative number: take 2's complement.
666
        ret := ret - 2 ** s'length;
667
      end if; -- If Positive, ret already contains the correct result.
668
 
669
      return ret;
670
    end;
671
 
672
    function To_BitVector (u: Unsigned; size: Integer)
673
        return Bit_Vector is
674
    variable ret: Bit_Vector (size-1 downto 0) := (others => '0');
675
    constant Min_BITS: Integer := Min (u'length, size) - 1;
676
    variable TEMP: Unsigned (u'length-1 downto 0);
677
  begin
678
      if (u'length > size) then
679
          Message (ToBVSize, Note);
680
      end if;
681
 
682
    TEMP := Unsigned (Downto_Dir (u));
683
 
684
    for I in 0 to Min_BITS loop
685
      ret(I) := TEMP(I);
686
    end loop;
687
 
688
    return ret;
689
  end;
690
 
691
  function To_Unsigned (i, size : Integer)
692
      return Unsigned is
693
 
694
    variable M1: Integer;
695
    variable ret : Unsigned(size-1 downto 0) := (others => '0');
696
  begin
697
    -- Input must be Positive.
698
      if (i < 0) then
699
          Message (ToUNeg, Error);
700
      end if;
701
 
702
    M1 := i;
703
 
704
    for J in ret'REVERSE_RANGE loop -- LSB first.
705
      if (M1 mod 2) = 1 then
706
        ret(J) := '1';
707
      else
708
        ret(J) := '0';
709
      end if;
710
 
711
      -- exit when (J = ret'left);
712
      M1 := M1 / 2;
713
    end loop;
714
 
715
    if (M1 /= 0) then
716
        Message (ToUBitNo, Note);
717
    end if;
718
 
719
    return ret;
720
  end;
721
 
722
  function To_Unsigned (s: Signed; size : Integer)
723
      return Unsigned is
724
    variable ret : Unsigned(size-1 downto 0) := (others => '0');
725
    constant Min_BITS: Integer := Min (s'length, size) - 1;
726
    variable TEMP: Unsigned (s'length-1 downto 0);
727
  begin
728
    -- Input cannot be a negative value.
729
    if (s(s'left) = '1') then
730
      Message (ToUPos, Error);
731
    end if;
732
 
733
    -- Truncated if no of bits are less.
734
    if (s'length > size) then
735
       Message (ToUBitNo, Note);
736
    end if;
737
 
738
    TEMP := Unsigned (Downto_Dir (s));
739
    ret (Min_BITS downto 0) := TEMP (Min_BITS downto 0);
740
 
741
    return ret;
742
  end;
743
 
744
  function To_Unsigned (u: Unsigned; size: Integer)
745
      return Unsigned is
746
    variable ret : Unsigned(size-1 downto 0) := (others => '0');
747
    constant Min_BITS: Integer := Min (u'length, size) - 1;
748
    variable TEMP: Unsigned (u'length-1 downto 0);
749
  begin
750
      if (u'length > size) then
751
         Message (ToUBitNo, Note);
752
      end if;
753
 
754
    TEMP := Unsigned (Downto_Dir (u));
755
    ret (Min_BITS downto 0) := TEMP (Min_BITS downto 0);
756
 
757
    return ret;
758
  end;
759
 
760
  function To_Signed (i, size: Integer)  return Signed is
761
    variable M1: Integer;
762
    variable ret : Signed(size-1 downto 0) := (others => '0');
763
 
764
  begin
765
    -- If input is negative, get its 2's complement int value which
766
    -- is 2 ** size - ABS(i).
767
 
768
    M1 := abs (i);
769
 
770
    for J in ret'REVERSE_RANGE loop -- from LSB.
771
      if (M1 mod 2) = 1 then
772
        ret(J) := '1';
773
      else
774
        ret(J) := '0';
775
      end if;
776
 
777
      -- exit when (J = ret'left);
778
      M1 := M1 / 2;
779
    end loop;
780
 
781
    if (M1 /= 0) then
782
      Message (ToSBitNo, Note);
783
    end if;
784
 
785
    -- if -ve value, complement and add 1.
786
    if (i < 0) then
787
--      ret := Get_Twos_Complement (ret);
788
      ret := -ret;
789
    else -- make sure the leftmost bit is a zero; since +ve number; number
790
         -- that is same size as no-of-bits will therefore get truncated.
791
      if (ret(ret'left) = '1') then
792
        Message (ToSBitNo, Note);
793
      end if;
794
 
795
      ret(ret'left) := '0';
796
    end if;
797
 
798
    return ret;
799
  end;
800
 
801
  function To_Signed (u: Unsigned; size: Integer) return Signed is
802
    variable ret : Signed(size-1 downto 0) := (others => '0');
803
    constant Min_BITS: Integer := Min (u'length, size) - 1;
804
    variable TEMP: Signed(u'length-1 downto 0);
805
  begin
806
    if (u'length > size) then
807
      Message(ToSBitNo, Note);
808
    end if;
809
 
810
 
811
    TEMP := Signed (Downto_Dir(u));
812
    ret(Min_BITS downto 0) := TEMP (Min_BITS downto 0);
813
    -- Make sure left most bit is zero, since orig was an Unsigned number.
814
    ret(ret'left) := '0';
815
 
816
    return ret;
817
  end;
818
 
819
  function To_Signed (s: Signed; size: Integer) return Signed is
820
    variable ret : Signed(size-1 downto 0) := (others => s(s'left));
821
    constant Min_BITS: Integer := Min (s'length, size) - 1;
822
    variable TEMP: Signed(s'length-1 downto 0);
823
  begin
824
    if (s'length > size) then
825
      Message (ToSBitNo, Note);
826
    end if;
827
 
828
    TEMP := Downto_Dir(s);
829
    ret(Min_BITS downto 0) := TEMP (Min_BITS downto 0);
830
 
831
    return ret;
832
  end;
833
 
834
    ----------------------------------
835
    -- Binary arithmetic functions: --
836
    ----------------------------------
837
 
838
  function "+" (L: Unsigned; R: Integer)  return Unsigned is
839
    constant size: Integer := L'length;
840
    variable new_r: Unsigned (size-1 downto 0);
841
    variable new_l: Unsigned (size-1 downto 0);
842
  begin
843
    new_l := To_Unsigned (L, size);
844
    new_r := To_Unsigned (R, size);
845
 
846
    return (Unsigned_Plus (new_l, new_r));
847
  end;
848
 
849
  function "+" (L: Unsigned; R: Unsigned) return Unsigned is
850
    constant size: Integer := Max(L'length, R'length);
851
    variable new_r: Unsigned (size-1 downto 0);
852
    variable new_l: Unsigned (size-1 downto 0);
853
  begin
854
    new_l := To_Unsigned (L, size);
855
    new_r := To_Unsigned (R, size);
856
 
857
    return (Unsigned_Plus (new_l, new_r));
858
  end;
859
 
860
  function "+" (L: Signed;   R: Signed)   return Signed is
861
    constant size: Integer := Max(L'length, R'length);
862
    variable new_r: Signed (size-1 downto 0);
863
    variable new_l: Signed (size-1 downto 0);
864
  begin
865
    new_l := To_Signed (L, size);
866
    new_r := To_Signed (R, size);
867
 
868
    return (Signed_Plus (new_l, new_r));
869
  end;
870
 
871
-- Next 3 functions added: BHASKER:
872
  function "+" (L: Integer; R: Unsigned)  return Unsigned is
873
  begin
874
    return ("+"(R, L));
875
  end;
876
 
877
  function "+" (L: Signed;   R: Integer)   return Signed is
878
    constant size: Integer := L'length;
879
    variable new_r: Signed (size-1 downto 0);
880
    variable new_l: Signed (size-1 downto 0);
881
  begin
882
    new_l := To_Signed (L, size);
883
    new_r := To_Signed (R, size);
884
 
885
    return (Signed_Plus (new_l, new_r));
886
  end;
887
 
888
  function "+" (L: Integer; R: Signed)  return Signed is
889
  begin
890
    return ("+"(R, L));
891
  end;
892
 
893
  function "-" (L: Unsigned; R: Unsigned) return Unsigned is
894
    constant size: Integer := Max (L'length, R'length);
895
    variable new_r: Unsigned (size-1 downto 0);
896
    variable new_l: Unsigned (size-1 downto 0);
897
  begin
898
    new_l := To_Unsigned (L, size);
899
    new_r := To_Unsigned (R, size);
900
 
901
    return (Unsigned_Minus(new_l, new_r));
902
  end;
903
 
904
  function "-" (L: Signed;   R: Signed)   return Signed is
905
    constant size: Integer := Max (L'length, R'length);
906
    variable new_r: Signed (size-1 downto 0);
907
    variable new_l: Signed (size-1 downto 0);
908
  begin
909
    new_l := To_Signed (L, size);
910
    new_r := To_Signed (R, size);
911
 
912
    return (Signed_Minus(new_l, new_r));
913
  end;
914
 
915
-- Next 4 functions added: BHASKER:
916
  function "-" (L: Unsigned; R: Integer) return Unsigned is
917
    constant size: Integer := L'length;
918
    variable new_r: Unsigned (size-1 downto 0);
919
    variable new_l: Unsigned (size-1 downto 0);
920
  begin
921
    new_l := To_Unsigned (L, size);
922
    new_r := To_Unsigned (R, size);
923
 
924
    return (Unsigned_Minus(new_l, new_r));
925
  end;
926
 
927
  function "-" (L: Integer; R: Unsigned) return Unsigned is
928
    constant size: Integer := R'length;
929
    variable new_r: Unsigned (size-1 downto 0);
930
    variable new_l: Unsigned (size-1 downto 0);
931
  begin
932
    new_l := To_Unsigned (L, size);
933
    new_r := To_Unsigned (R, size);
934
 
935
    return (Unsigned_Minus(new_l, new_r));
936
  end;
937
 
938
  function "-" (L: Signed;   R: Integer)   return Signed is
939
    constant size: Integer := L'length;
940
    variable new_r: Signed (size-1 downto 0);
941
    variable new_l: Signed (size-1 downto 0);
942
  begin
943
    new_l := To_Signed (L, size);
944
    new_r := To_Signed (R, size);
945
 
946
    return (Signed_Minus(new_l, new_r));
947
  end;
948
 
949
  function "-" (L: Integer; R: Signed) return Signed is
950
    constant size: Integer := R'length;
951
    variable new_r: Signed (size-1 downto 0);
952
    variable new_l: Signed (size-1 downto 0);
953
  begin
954
    new_l := To_Signed (L, size);
955
    new_r := To_Signed (R, size);
956
 
957
    return (Signed_Minus(new_l, new_r));
958
  end;
959
 
960
  function "*" (L: Unsigned; R: Unsigned) return Unsigned is
961
    variable res, tmp_L: Unsigned (L'length+R'length-1 downto 0)
962
                         := (others => '0');
963
  begin
964
    tmp_L(L'length-1 downto 0) := L;
965
 
966
    for J in R'REVERSE_RANGE loop -- Start from LSB.
967
      if R(J) = '1' then -- add tmp_L to res.
968
        res := res + tmp_L;
969
      end if;
970
 
971
    -- tmp_L := tmp_L(tmp_L'length-2 downto 0) & '0'; -- left shift tmp_L.
972
      tmp_L(tmp_L'length-1 downto 1) := tmp_L(tmp_L'length-2 downto 0);
973
      tmp_L(0) := '0'; -- left shift tmp_L.
974
    end loop;
975
 
976
    return res;
977
  end;
978
 
979
  function "*" (L: Signed;   R: Signed)   return Signed is
980
    variable ret: Signed (L'length+R'length-1 downto 0) := (others => '0');
981
    variable TR: Unsigned (R'length-1 downto 0) := (others => '0');
982
    variable TL: Unsigned (L'length-1 downto 0) := (others => '0');
983
    variable UL: Unsigned (L'length-1 downto 0);
984
    variable UR: Unsigned (R'length-1 downto 0);
985
 
986
  begin
987
    if (L(L'left) = '1') then
988
      TL := Get_Magnitude (L);
989
    else
990
--      if (L'left > L'right) then
991
 --       TL := L (L`left-1 downto L'right);
992
  --    else
993
   --     TL := L (L'left+1 to L'right);
994
    --  end if;
995
      UL := To_Unsigned(L, L'length);
996
      TL := UL (TL'RANGE);
997
    end if;
998
 
999
    if (R(R'left) = '1') then
1000
      TR := Get_Magnitude (R);
1001
    else
1002
      UR := To_Unsigned (R, R'length);
1003
      TR := UR (TR'RANGE);
1004
    end if;
1005
 
1006
    ret := To_Signed (TL * TR, ret'length);
1007
 
1008
    -- add sign now.
1009
    if ((L(L'left) = '0') and (R(R'left) = '1')) or
1010
       ((L(L'left) = '1') and (R(R'left) = '0')) then
1011
--      ret := Get_Twos_Complement (ret);
1012
      ret := -ret;
1013
    end if;
1014
 
1015
    return ret;
1016
  end;
1017
 
1018
  function "/" (L: Unsigned; R: Unsigned) return Unsigned is
1019
    variable res: Unsigned (L'length-1 downto 0) := (others => '0');
1020
    variable TL, TR: Integer;
1021
  begin
1022
    if (not (L'length < 32 and R'length < 32)) then
1023
      Message (LongSize, Error);
1024
    end if;
1025
 
1026
  -- assert L'length < 32 and R'length < 32
1027
      --report "Unsigned / Unsigned: Number of bits in operand cannot be more than 32."
1028
      --severity ERROR;
1029
 
1030
    TL := To_Integer (L);
1031
    TR := To_Integer (R);
1032
    res := To_Unsigned ((TL / TR), res'length);
1033
 
1034
    return res;
1035
  end;
1036
 
1037
  function "/" (L: Signed;   R: Signed)   return Signed is
1038
    variable res: Signed (L'length-1 downto 0) := (others => '0');
1039
    variable TL, TR: Integer;
1040
  begin
1041
    if (not (L'length < 32 and R'length < 32)) then
1042
      Message (LongSize, Error);
1043
    end if;
1044
 
1045
    TL := To_Integer (L);
1046
    TR := To_Integer (R);
1047
    res := To_Signed ((TL / TR), res'length);
1048
 
1049
    return res;
1050
  end;
1051
 
1052
  function "mod" (L: Unsigned; R: Unsigned) return Unsigned is
1053
    variable res: Unsigned (R'length-1 downto 0) := (others => '0');
1054
    variable TL, TR: Integer;
1055
  begin
1056
    if (not (L'length < 32 and R'length < 32)) then
1057
      Message (LongSize, Error);
1058
    end if;
1059
 
1060
    TL := To_Integer (L);
1061
    TR := To_Integer (R);
1062
    res := To_Unsigned ((TL mod TR), res'length);
1063
 
1064
    return res;
1065
  end;
1066
 
1067
  function "mod" (L: Signed;   R: Signed)   return Signed is
1068
    variable res: Signed (R'length-1 downto 0) := (others => '0');
1069
    variable TL, TR: Integer;
1070
  begin
1071
    if (not (L'length < 32 and R'length < 32)) then
1072
      Message (LongSize, Error);
1073
    end if;
1074
 
1075
    TL := To_Integer (L);
1076
    TR := To_Integer (R);
1077
    res := To_Signed ((TL mod TR), res'length);
1078
 
1079
    return res;
1080
  end;
1081
 
1082
  function "rem" (L: Unsigned; R: Unsigned) return Unsigned is
1083
    variable res: Unsigned (R'length-1 downto 0) := (others => '0');
1084
    variable TL, TR: Integer;
1085
  begin
1086
    if (not (L'length < 32 and R'length < 32)) then
1087
      Message (LongSize, Error);
1088
    end if;
1089
 
1090
    TL := To_Integer (L);
1091
    TR := To_Integer (R);
1092
    res := To_Unsigned ((TL rem TR), res'length);
1093
 
1094
    return res;
1095
  end;
1096
 
1097
  function "rem" (L: Signed;   R: Signed)   return Signed is
1098
    variable res: Signed (R'length-1 downto 0) := (others => '0');
1099
    variable TL, TR: Integer;
1100
  begin
1101
    if (not (L'length < 32 and R'length < 32)) then
1102
      Message (LongSize, Error);
1103
    end if;
1104
 
1105
    TL := To_Integer (L);
1106
    TR := To_Integer (R);
1107
    res := To_Signed ((TL rem TR), res'length);
1108
 
1109
    return res;
1110
  end;
1111
 
1112
  function "-" (L: Signed) return Signed is
1113
    variable ret, ZERO: Signed (L'length-1 downto 0) := (others => '0');
1114
  begin
1115
    ret := ZERO - L;
1116
    return ret;
1117
  end;
1118
 
1119
 
1120
  function "abs" (L: Signed) return Signed is
1121
    variable ret: Signed (L'length-1 downto 0) := (others => '0');
1122
  begin
1123
    if (L(L'left) = '1') then -- if negative number.
1124
      ret := To_Signed(Get_Magnitude(L), ret'length);
1125
    else -- Positive number;
1126
      ret := L;
1127
    end if;
1128
 
1129
    return ret;
1130
  end;
1131
 
1132
 
1133
  function "<" (L: Unsigned; R: Unsigned) return Boolean is
1134
    constant size: Integer := Max (L'length, R'length);
1135
    variable new_l: Signed (size downto 0);
1136
    variable new_r: Signed (size downto 0);
1137
  begin
1138
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1139
    new_r := To_Signed (R, size+1);
1140
 
1141
    return (Less_Than (new_l, new_r));
1142
  end;
1143
 
1144
 
1145
  function "<" (L: Signed;   R: Signed)   return Boolean is
1146
    constant size: Integer := Max (L'length, R'length);
1147
    variable new_l: Signed (size-1 downto 0);
1148
    variable new_r: Signed (size-1 downto 0);
1149
  begin
1150
    new_l := To_Signed (L, size);
1151
    new_r := To_Signed (R, size);
1152
 
1153
    return (Less_Than (new_l, new_r));
1154
  end;
1155
 
1156
  function "<=" (L: Unsigned; R: Unsigned) return Boolean is
1157
    constant size: Integer := Max (L'length, R'length);
1158
    variable new_l: Signed (size downto 0);
1159
    variable new_r: Signed (size downto 0);
1160
  begin
1161
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1162
    new_r := To_Signed (R, size+1);
1163
 
1164
    return (Less_Than_Or_Equal_To (new_l, new_r));
1165
  end;
1166
 
1167
  function "<=" (L: Signed;   R: Signed)   return Boolean is
1168
    constant size: Integer := Max (L'length, R'length);
1169
    variable new_l: Signed (size-1 downto 0);
1170
    variable new_r: Signed (size-1 downto 0);
1171
  begin
1172
    new_l := To_Signed (L, size);
1173
    new_r := To_Signed (R, size);
1174
 
1175
    return (Less_Than_Or_Equal_To (new_l, new_r));
1176
  end;
1177
 
1178
  function ">=" (L: Unsigned; R: Unsigned) return Boolean is
1179
    constant size: Integer := Max (L'length, R'length);
1180
    variable new_l: Signed (size downto 0);
1181
    variable new_r: Signed (size downto 0);
1182
  begin
1183
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1184
    new_r := To_Signed (R, size+1);
1185
 
1186
    return (Less_Than_Or_Equal_To (new_r, new_l));
1187
  end;
1188
 
1189
  function ">=" (L: Signed;   R: Signed)   return Boolean is
1190
    constant size: Integer := Max (L'length, R'length);
1191
    variable new_l: Signed (size-1 downto 0);
1192
    variable new_r: Signed (size-1 downto 0);
1193
  begin
1194
    new_l := To_Signed (L, size);
1195
    new_r := To_Signed (R, size);
1196
 
1197
    return (Less_Than_Or_Equal_To (new_r, new_l));
1198
  end;
1199
 
1200
  function ">" (L: Unsigned; R: Unsigned) return Boolean is
1201
    constant size: Integer := Max (L'length, R'length);
1202
    variable new_l: Signed (size downto 0);
1203
    variable new_r: Signed (size downto 0);
1204
  begin
1205
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1206
    new_r := To_Signed (R, size+1);
1207
 
1208
    return (Less_Than (new_r, new_l));
1209
  end;
1210
 
1211
  function ">" (L: Signed;   R: Signed)   return Boolean is
1212
    constant size: Integer := Max (L'length, R'length);
1213
    variable new_l: Signed (size-1 downto 0);
1214
    variable new_r: Signed (size-1 downto 0);
1215
  begin
1216
    new_l := To_Signed (L, size);
1217
    new_r := To_Signed (R, size);
1218
 
1219
    return (Less_Than (new_r, new_l));
1220
  end;
1221
 
1222
  function "=" (L: Unsigned; R: Integer)  return Boolean is
1223
    constant size: Integer := L'length;
1224
    variable new_l: Signed (size downto 0);
1225
    variable new_r: Signed (size downto 0);
1226
  begin
1227
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1228
    new_r := To_Signed (R, size+1);
1229
 
1230
    return (EQUAL_TO (new_l, new_r));
1231
  end;
1232
 
1233
  function "=" (L: Unsigned; R: Unsigned) return Boolean is
1234
    constant size: Integer := Max (L'length, R'length);
1235
    variable new_l: Signed (size downto 0);
1236
    variable new_r: Signed (size downto 0);
1237
  begin
1238
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1239
    new_r := To_Signed (R, size+1);
1240
 
1241
    return (EQUAL_TO (new_l, new_r));
1242
  end;
1243
 
1244
  function "=" (L: Signed;   R: Signed)   return Boolean is
1245
    constant size: Integer := Max (L'length, R'length);
1246
    variable new_l: Signed (size-1 downto 0);
1247
    variable new_r: Signed (size-1 downto 0);
1248
  begin
1249
    new_l := To_Signed (L, size);
1250
    new_r := To_Signed (R, size);
1251
 
1252
    return (EQUAL_TO (new_l, new_r));
1253
  end;
1254
 
1255
  function "/=" (L: Unsigned; R: Unsigned) return Boolean is
1256
    constant size: Integer := Max (L'length, R'length);
1257
    variable new_l: Signed (size downto 0);
1258
    variable new_r: Signed (size downto 0);
1259
  begin
1260
    new_l := To_Signed (L, size+1); -- pad 1 zero.
1261
    new_r := To_Signed (R, size+1);
1262
 
1263
    return (not EQUAL_TO (new_l, new_r));
1264
  end;
1265
 
1266
  function "/=" (L: Signed;   R: Signed)   return Boolean is
1267
    constant size: Integer := Max (L'length, R'length);
1268
    variable new_l: Signed (size-1 downto 0);
1269
    variable new_r: Signed (size-1 downto 0);
1270
  begin
1271
    new_l := To_Signed (L, size);
1272
    new_r := To_Signed (R, size);
1273
 
1274
    return (not EQUAL_TO (new_l, new_r));
1275
  end;
1276
 
1277
  ----------------------
1278
  -- Shift functions: --
1279
  ----------------------
1280
 
1281
  function Shift_Left  (u: Unsigned; size: Natural)  return Unsigned is
1282
    variable tmp, ret: Unsigned (u'length-1 downto 0) := (others => '0');
1283
  begin
1284
    if (size >= u'length) then
1285
      Message (ShiftBitNo, Error);
1286
    end if;
1287
 
1288
    tmp := Downto_Dir (u);
1289
    ret(tmp'left downto size) := tmp ((tmp'left-size) downto 0);
1290
    return ret;
1291
  end;
1292
 
1293
  function Shift_Left  (s: Signed;   size: Natural)  return Signed is
1294
    variable tmp, ret: Signed (s'length-1 downto 0) := (others => '0');
1295
  begin
1296
    if (size >= s'length-1) then
1297
      Message (ShiftBitNo, Error);
1298
    end if;
1299
 
1300
    tmp := Downto_Dir (s);
1301
    ret((tmp'left-1) downto size) := tmp ((tmp'left-1-size) downto 0);
1302
    --Jb Sign bit no longer being retained: Aug 18 '93:
1303
    -- ret(tmp'left) := s(s'left); -- copy sign bit.
1304
    return ret;
1305
  end;
1306
 
1307
  function Shift_Right (u: Unsigned; size: Natural)  return Unsigned is
1308
    variable tmp, ret: Unsigned (u'length-1 downto 0) := (others => '0');
1309
  begin
1310
    if (size >= u'length) then
1311
      Message (ShiftBitNo, Error);
1312
    end if;
1313
 
1314
    tmp := Downto_Dir (u);
1315
    ret((tmp'left-size) downto 0) := tmp (tmp'left downto size);
1316
    return ret;
1317
  end;
1318
 
1319
  function Shift_Right (s: Signed; size : Natural)  return Signed is
1320
    variable tmp, ret: Signed (s'length-1 downto 0) := (others => s(s'left));
1321
  begin
1322
    if (size >= s'length-1) then
1323
      Message (ShiftBitNo, Error);
1324
    end if;
1325
 
1326
    tmp := Downto_Dir (s);
1327
    ret((tmp'left-1-size) downto 0) := tmp ((tmp'left-1) downto size);
1328
    ret(tmp'left) := s(s'left); -- copy sign bit.
1329
    return ret;
1330
  end;
1331
 
1332
   -------------------------------
1333
   -- preset / clear procedure: --
1334
   -------------------------------
1335
    procedure Preset_Clear (signal FF: out Unsigned; Pc_Value: Unsigned) is
1336
    begin
1337
      FF <= Pc_Value;
1338
    end;
1339
 
1340
    procedure Preset_Clear (signal FF: out Signed; Pc_Value: Signed) is
1341
    begin
1342
      FF <= Pc_Value;
1343
    end;
1344
 
1345
  --------------------------------------------------
1346
  -- Conversion functions for FDS2 (provided by IG):
1347
  --------------------------------------------------
1348
  function To_Integer (OPD: BCD_BIT_VECTOR) return INTEGER is
1349
    variable TEMP: INTEGER;               -- returning integer
1350
    variable BCD_INDEX_COUNTER: INTEGER;  -- for BCD 4-bit counting(0 - 3)
1351
    variable BCD_DIGIT: INTEGER;          -- BCD digit (0 - 9)
1352
    variable BCD_WEIGHT: INTEGER;         -- weight for decimal digit(1, 10, ..)
1353
  begin
1354
    -- First check if size of input is less than 32 bits, the max int value.
1355
    if (OPD'LENGTH >= 32) then
1356
      Message(LongSize, Error);
1357
    end if;
1358
 
1359
    TEMP := 0;
1360
    BCD_INDEX_COUNTER := 0;
1361
    BCD_DIGIT := 0;
1362
    BCD_WEIGHT := 1;                          -- weight initial value 
1363
 
1364
    -- Remember: leftmost is MSB; DO NOT go by index value of OPD, i.e OPD(0)
1365
    -- may also be the MSB.
1366
    for M3 in OPD'REVERSE_RANGE loop          -- scanning from the index 0 to n
1367
      if OPD(M3) = '1' then
1368
        -- BCD digit calculation
1369
        BCD_DIGIT := BCD_DIGIT + (2 ** BCD_INDEX_COUNTER);
1370
      end if;
1371
 
1372
      BCD_INDEX_COUNTER := BCD_INDEX_COUNTER + 1;
1373
 
1374
      if BCD_INDEX_COUNTER = 4   then             -- four bits are scanned?
1375
        if (BCD_DIGIT >= 10) then                  -- invalid BCD digit?
1376
          Message (Size_9, Error);
1377
        end if;
1378
 
1379
        TEMP := TEMP + (BCD_DIGIT * BCD_WEIGHT);  -- add integer to TEMP
1380
        BCD_INDEX_COUNTER := 0;           -- reinitialize the BCD 4-bit counter
1381
        BCD_DIGIT := 0;                   -- reinitialize the BCD digit
1382
        BCD_WEIGHT := BCD_WEIGHT * 10;    -- weight is adjusted for next digit
1383
      end if;
1384
    end loop;
1385
 
1386
    return TEMP;
1387
  end To_Integer;
1388
 
1389
  function To_Integer (OPD: XS_3_BIT_VECTOR) return INTEGER is
1390
    variable TEMP: INTEGER;               -- returning integer
1391
    variable XS_3_INDEX_COUNTER: INTEGER; -- for XS_3 4-bit counting(0 - 3)
1392
    variable XS_3_DIGIT: INTEGER;         -- XS_3 digit (0 - 9)
1393
    variable XS_3_WEIGHT: INTEGER;        -- weight for decimal digit(1, 10, ..)
1394
  begin
1395
    -- First check if size of input is less than 32 bits, the max int value.
1396
    if (OPD'LENGTH > 32) then
1397
      Message (LongSize, Error);
1398
    end if;
1399
 
1400
    TEMP := 0;
1401
    XS_3_INDEX_COUNTER := 0;
1402
    XS_3_DIGIT := 0;
1403
    XS_3_WEIGHT := 1;                          -- weight initial value 
1404
 
1405
    -- Remember: leftmost is MSB; DO NOT go by index value of OPD, i.e OPD(0)
1406
    -- may also be the MSB.
1407
    for M3 in OPD'REVERSE_RANGE loop          -- scanning from the index 0 to n
1408
      -- XS_3 digit (3 - 12, due to the excesse 3) calculation
1409
      if OPD(M3) = '1' then
1410
        XS_3_DIGIT := XS_3_DIGIT + (2 ** XS_3_INDEX_COUNTER);
1411
      end if;
1412
 
1413
      XS_3_INDEX_COUNTER := XS_3_INDEX_COUNTER + 1;
1414
 
1415
      if XS_3_INDEX_COUNTER = 4   then             -- four bits are scanned?
1416
        XS_3_DIGIT := XS_3_DIGIT -3;               -- correction the excess-3
1417
 
1418
        if (XS_3_DIGIT >= 10) then                  -- invalid XS_3 digit?
1419
          Message (Size_9, Error);
1420
        end if;
1421
 
1422
        TEMP := TEMP + (XS_3_DIGIT * XS_3_WEIGHT); -- add integer to TEMP
1423
        XS_3_INDEX_COUNTER := 0;        -- reinitialize the XS_3 4-bit counter
1424
        XS_3_DIGIT := 0;                -- reinitialize the XS_3 digit
1425
        XS_3_WEIGHT := XS_3_WEIGHT * 10; -- weight is adjusted for next digit
1426
      end if;
1427
    end loop;
1428
 
1429
    return TEMP;
1430
  end To_Integer;
1431
 
1432
  function To_Integer (OPD: XS_3_GRAY_BIT_VECTOR) return INTEGER is
1433
    variable TEMP: INTEGER;               -- returning integer
1434
    variable XS_3_GRAY_INDEX_COUNTER: INTEGER; -- for XS_3_GRAY 4-bit counting(0 - 3)
1435
    variable XS_3_GRAY_DIGIT: INTEGER;    -- XS_3_GRAY digit (0 - 9)
1436
    variable XS_3_GRAY_WEIGHT: INTEGER;   -- weight for decimal digit(1, 10, ..)
1437
 --   variable XS_3_GRAY_INPUTS: BIT_VECTOR(3 downto 0);  -- 4-bit input segment
1438
  begin
1439
    -- First check if size of input is less than 32 bits, the max int value.
1440
    if (OPD'LENGTH > 32) then
1441
      Message (LongSize, Error);
1442
    end if;
1443
 
1444
    TEMP := 0;
1445
    XS_3_GRAY_INDEX_COUNTER := 0;
1446
    XS_3_GRAY_DIGIT := 0;
1447
    XS_3_GRAY_WEIGHT := 1;                          -- weight initial value 
1448
 
1449
    -- Remember: leftmost is MSB; DO NOT go by index value of OPD, i.e OPD(0)
1450
     -- may also be the MSB.
1451
    for M3 in OPD'REVERSE_RANGE loop          -- scanning from the index 0 to n
1452
      XS_3_GRAY_INDEX_COUNTER := XS_3_GRAY_INDEX_COUNTER + 1;
1453
 
1454
      if XS_3_GRAY_INDEX_COUNTER = 4   then        -- four bits are scanned?
1455
 
1456
----------------------------------------------------------------------------
1457
       if OPD(M3)='0' and OPD(M3-1)='0' and OPD(M3-2)='1' and OPD(M3-3)='0' then
1458
          XS_3_GRAY_DIGIT := 0;
1459
       elsif OPD(M3)='0' and OPD(M3-1)='1' and OPD(M3-2)='1' and OPD(M3-3)='0' then
1460
          XS_3_GRAY_DIGIT := 1;
1461
       elsif OPD(M3)='0' and OPD(M3-1)='1' and OPD(M3-2)='1' and OPD(M3-3)='1' then
1462
          XS_3_GRAY_DIGIT := 2;
1463
       elsif OPD(M3)='0' and OPD(M3-1)='1' and OPD(M3-2)='0' and OPD(M3-3)='1' then
1464
          XS_3_GRAY_DIGIT := 3;
1465
       elsif OPD(M3)='0' and OPD(M3-1)='1' and OPD(M3-2)='0' and OPD(M3-3)='0' then
1466
          XS_3_GRAY_DIGIT := 4;
1467
       elsif OPD(M3)='1' and OPD(M3-1)='1' and OPD(M3-2)='0' and OPD(M3-3)='0' then
1468
          XS_3_GRAY_DIGIT := 5;
1469
       elsif OPD(M3)='1' and OPD(M3-1)='1' and OPD(M3-2)='0' and OPD(M3-3)='1' then
1470
          XS_3_GRAY_DIGIT := 6;
1471
       elsif OPD(M3)='1' and OPD(M3-1)='1' and OPD(M3-2)='1' and OPD(M3-3)='1' then
1472
          XS_3_GRAY_DIGIT := 7;
1473
       elsif OPD(M3)='1' and OPD(M3-1)='1' and OPD(M3-2)='1' and OPD(M3-3)='0' then
1474
          XS_3_GRAY_DIGIT := 8;
1475
       elsif OPD(M3)='1' and OPD(M3-1)='0' and OPD(M3-2)='1' and OPD(M3-3)='0' then
1476
          XS_3_GRAY_DIGIT := 9;
1477
       else               -- invalid XS_3_GRAY digit!
1478
            Message (Axcess_3_Gray, Error);
1479
       end if;
1480
----------------------------------------------------------------------------
1481
----------------------------------------------------------------------------
1482
--   This routine was replaced with above code because
1483
--    DAZIX dvhdl does not support '&' operator
1484
--
1485
--        XS_3_GRAY_INPUTS := OPD(M3)&OPD(M3-1)&OPD(M3-2)&OPD(M3-3);
1486
--
1487
--        case XS_3_GRAY_INPUTS is
1488
--          when "0010" => XS_3_GRAY_DIGIT := 0;
1489
--          when "0110" => XS_3_GRAY_DIGIT := 1;
1490
--          when "0111" => XS_3_GRAY_DIGIT := 2;
1491
--          when "0101" => XS_3_GRAY_DIGIT := 3;
1492
--          when "0100" => XS_3_GRAY_DIGIT := 4;
1493
--          when "1100" => XS_3_GRAY_DIGIT := 5;
1494
--          when "1101" => XS_3_GRAY_DIGIT := 6;
1495
--          when "1111" => XS_3_GRAY_DIGIT := 7;
1496
--          when "1110" => XS_3_GRAY_DIGIT := 8;
1497
--          when "1010" => XS_3_GRAY_DIGIT := 9;
1498
--          when others => assert FALSE     -- invalid XS_3_GRAY digit!
1499
--                           report "CONV_TO_INT: An invalid Excess-3 GRAY digit."
1500
--                           severity ERROR;
1501
--        end case;
1502
----------------------------------------------------------------------------
1503
 
1504
 
1505
        TEMP := TEMP + (XS_3_GRAY_DIGIT * XS_3_GRAY_WEIGHT); -- add integer to TEMP
1506
        XS_3_GRAY_INDEX_COUNTER := 0; -- reinitialize the XS_3_GRAY 4-bit counter
1507
        XS_3_GRAY_DIGIT := 0;             -- reinitialize the XS_3_GRAY digit
1508
        XS_3_GRAY_WEIGHT := XS_3_GRAY_WEIGHT * 10;  -- weight is adjusted for next digit
1509
      end if;
1510
    end loop;
1511
 
1512
    return TEMP;
1513
  end To_Integer;
1514
 
1515
  function To_Integer (OPD: JOHNSON_BIT_VECTOR) return INTEGER is
1516
    variable TEMP: INTEGER;                      -- returning integer
1517
    variable JOHNSON_ONE_COUNTER: INTEGER;       -- for counting ones
1518
    variable JOHNSON_ZERO_COUNTER: INTEGER;      -- for counting zeros
1519
  begin
1520
    -- First check if size of input is less than 32 bits, the max int value.
1521
    assert (OPD'LENGTH < 32)
1522
      report "CONV_TO_INT: Number of bits in input operand cannot be more than 32."
1523
      severity ERROR;
1524
 
1525
    TEMP := 0;
1526
    JOHNSON_ONE_COUNTER := 0;
1527
    JOHNSON_ZERO_COUNTER := 0;
1528
 
1529
    -- Remember: leftmost is MSB; DO NOT go by index value of OPD, i.e OPD(0)
1530
    -- may also be the MSB.
1531
    for M3 in OPD'REVERSE_RANGE loop          -- scanning from the index 0 to n
1532
      if OPD(M3) = '1' then
1533
        JOHNSON_ONE_COUNTER := JOHNSON_ONE_COUNTER +1;
1534
      else
1535
        JOHNSON_ZERO_COUNTER := JOHNSON_ZERO_COUNTER +1;
1536
      end if;
1537
    end loop;
1538
 
1539
    if JOHNSON_ONE_COUNTER = 0  then
1540
      TEMP := 0;
1541
    elsif OPD(OPD'LOW) = '1'    then
1542
      TEMP := JOHNSON_ONE_COUNTER;
1543
    else
1544
      TEMP := OPD'LENGTH + JOHNSON_ZERO_COUNTER;
1545
    end if;
1546
 
1547
    return TEMP;
1548
  end To_Integer;
1549
 
1550
end Bit_Arith;
1551
 
1552
 

powered by: WebSVN 2.1.0

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