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

Subversion Repositories xmatchpro

[/] [xmatchpro/] [trunk/] [xmw4-comdec/] [xmatch_sim7/] [lib/] [dzx/] [bit_arith_pkg_body.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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