OpenCores
URL https://opencores.org/ocsvn/single-14-segment-display-driver-w-decoder/single-14-segment-display-driver-w-decoder/trunk

Subversion Repositories single-14-segment-display-driver-w-decoder

[/] [single-14-segment-display-driver-w-decoder/] [trunk/] [Project/] [Sources/] [Decoding_Table/] [ROM_ASCII_Decoder/] [decoder_table_dist_rom_impl/] [decoder_table_dist_rom/] [._Real_._Math_.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 liubenoff
 
2
 
3
------------------------------------------------------------------------
4
--
5
-- Copyright 1996 by IEEE. All rights reserved.
6
--
7
-- This source file is an essential part of IEEE Std 1076.2-1996, IEEE Standard 
8
-- VHDL Mathematical Packages. This source file may not be copied, sold, or 
9
-- included with software that is sold without written permission from the IEEE
10
-- Standards Department. This source file may be used to implement this standard 
11
-- and may be distributed in compiled form in any manner so long as the 
12
-- compiled form does not allow direct decompilation of the original source file.
13
-- This source file may be copied for individual use between licensed users. 
14
-- This source file is provided on an AS IS basis. The IEEE disclaims ANY 
15
-- WARRANTY EXPRESS OR IMPLIED INCLUDING ANY WARRANTY OF MERCHANTABILITY 
16
-- AND FITNESS FOR USE FOR A PARTICULAR PURPOSE. The user of the source 
17
-- file shall indemnify and hold IEEE harmless from any damages or liability 
18
-- arising out of the use thereof.
19
--
20
-- Title:       Standard VHDL Mathematical Packages (IEEE Std 1076.2-1996, 
21
--              MATH_REAL)
22
--
23
-- Library:     This package shall be compiled into a library
24
--              symbolically named IEEE.
25
--
26
-- Developers:  IEEE DASC VHDL Mathematical Packages Working Group
27
--
28
-- Purpose:     This package defines a standard for designers to use in
29
--              describing VHDL models that make use of common REAL constants
30
--              and common REAL elementary mathematical functions.
31
--
32
-- Limitation:  The values generated by the functions in this package may
33
--              vary from platform to platform, and the precision of results
34
--              is only guaranteed to be the minimum required by IEEE Std 1076-
35
--              1993.
36
--
37
-- Notes:
38
--              No declarations or definitions shall be included in, or
39
--              excluded from, this package.
40
--              The "package declaration" defines the types, subtypes, and
41
--              declarations of MATH_REAL.
42
--              The standard mathematical definition and conventional meaning
43
--              of the mathematical functions that are part of this standard
44
--              represent the formal semantics of the implementation of the
45
--              MATH_REAL package declaration.  The purpose of the MATH_REAL
46
--              package body is to provide a guideline for implementations to
47
--              verify their implementation of MATH_REAL.  Tool developers may
48
--              choose to implement the package body in the most efficient
49
--              manner available to them.
50
--
51
-- -----------------------------------------------------------------------------
52
-- Version    : 1.5
53
-- Date       : 24 July 1996
54
-- -----------------------------------------------------------------------------
55
 
56
package MATH_REAL is
57
    constant CopyRightNotice: STRING
58
      := "Copyright 1996 IEEE. All rights reserved.";
59
 
60
    --
61
    -- Constant Definitions
62
    --
63
    constant  MATH_E : REAL := 2.71828_18284_59045_23536;
64
                                                      -- Value of e
65
    constant  MATH_1_OVER_E : REAL := 0.36787_94411_71442_32160;
66
                                                      -- Value of 1/e
67
    constant  MATH_PI : REAL := 3.14159_26535_89793_23846;
68
                                                      -- Value of pi
69
    constant  MATH_2_PI : REAL := 6.28318_53071_79586_47693;
70
                                                      -- Value of 2*pi
71
    constant  MATH_1_OVER_PI : REAL := 0.31830_98861_83790_67154;
72
                                                      -- Value of 1/pi
73
    constant  MATH_PI_OVER_2 : REAL := 1.57079_63267_94896_61923;
74
                                                      -- Value of pi/2
75
    constant  MATH_PI_OVER_3 : REAL := 1.04719_75511_96597_74615;
76
                                                      -- Value of pi/3
77
    constant  MATH_PI_OVER_4 : REAL := 0.78539_81633_97448_30962;
78
                                                      -- Value of pi/4
79
    constant  MATH_3_PI_OVER_2 : REAL := 4.71238_89803_84689_85769;
80
                                                      -- Value 3*pi/2
81
    constant  MATH_LOG_OF_2 : REAL := 0.69314_71805_59945_30942;
82
                                                      -- Natural log of 2
83
    constant  MATH_LOG_OF_10 : REAL := 2.30258_50929_94045_68402;
84
                                                      -- Natural log of 10
85
    constant  MATH_LOG2_OF_E : REAL := 1.44269_50408_88963_4074;
86
                                                      -- Log base 2 of e
87
    constant  MATH_LOG10_OF_E: REAL := 0.43429_44819_03251_82765;
88
                                                      -- Log base 10 of e
89
    constant  MATH_SQRT_2: REAL := 1.41421_35623_73095_04880;
90
                                                      -- square root of 2
91
    constant  MATH_1_OVER_SQRT_2: REAL := 0.70710_67811_86547_52440;
92
                                                      -- square root of 1/2
93
    constant  MATH_SQRT_PI: REAL := 1.77245_38509_05516_02730;
94
                                                      -- square root of pi
95
    constant  MATH_DEG_TO_RAD: REAL := 0.01745_32925_19943_29577;
96
                                     -- Conversion factor from degree to radian
97
    constant  MATH_RAD_TO_DEG: REAL := 57.29577_95130_82320_87680;
98
                                     -- Conversion factor from radian to degree
99
 
100
    --
101
    -- Function Declarations
102
    --
103
    function SIGN (X: in REAL ) return REAL;
104
        -- Purpose:
105
        --         Returns 1.0 if X > 0.0; 0.0 if X = 0.0; -1.0 if X < 0.0
106
        -- Special values:
107
        --         None
108
        -- Domain:
109
        --         X in REAL
110
        -- Error conditions:
111
        --         None
112
        -- Range:
113
        --         ABS(SIGN(X)) <= 1.0
114
        -- Notes:
115
        --         None
116
 
117
    function CEIL (X : in REAL ) return REAL;
118
        -- Purpose:
119
        --         Returns smallest INTEGER value (as REAL) not less than X
120
        -- Special values:
121
        --         None
122
        -- Domain:
123
        --         X in REAL
124
        -- Error conditions:
125
        --         None
126
        -- Range:
127
        --         CEIL(X) is mathematically unbounded
128
        -- Notes:
129
        --         a) Implementations have to support at least the domain
130
        --                ABS(X) < REAL(INTEGER'HIGH)
131
 
132
    function FLOOR (X : in REAL ) return REAL;
133
        -- Purpose:
134
        --         Returns largest INTEGER value (as REAL) not greater than X
135
        -- Special values:
136
        --         FLOOR(0.0) = 0.0
137
        -- Domain:
138
        --         X in REAL
139
        -- Error conditions:
140
        --         None
141
        -- Range:
142
        --         FLOOR(X) is mathematically unbounded
143
        -- Notes:
144
        --         a) Implementations have to support at least the domain
145
        --                ABS(X) < REAL(INTEGER'HIGH)
146
 
147
    function ROUND (X : in REAL ) return REAL;
148
        -- Purpose:
149
        --         Rounds X to the nearest integer value (as real). If X is
150
        --         halfway between two integers, rounding is away from 0.0
151
        -- Special values:
152
        --         ROUND(0.0) = 0.0
153
        -- Domain:
154
        --         X in REAL
155
        -- Error conditions:
156
        --         None
157
        -- Range:
158
        --         ROUND(X) is mathematically unbounded
159
        -- Notes:
160
        --         a) Implementations have to support at least the domain
161
        --                ABS(X) < REAL(INTEGER'HIGH)
162
 
163
    function TRUNC (X : in REAL ) return REAL;
164
        -- Purpose:
165
        --         Truncates X towards 0.0 and returns truncated value
166
        -- Special values:
167
        --         TRUNC(0.0) = 0.0
168
        -- Domain:
169
        --         X in REAL
170
        -- Error conditions:
171
        --         None
172
        -- Range:
173
        --         TRUNC(X) is mathematically unbounded
174
        -- Notes:
175
        --         a) Implementations have to support at least the domain
176
        --                ABS(X) < REAL(INTEGER'HIGH)
177
 
178
    function "MOD" (X, Y: in REAL ) return REAL;
179
        -- Purpose:
180
        --         Returns floating point modulus of X/Y, with the same sign as
181
        --         Y, and absolute value less than the absolute value of Y, and
182
        --         for some INTEGER value N the result satisfies the relation
183
        --         X = Y*N + MOD(X,Y)
184
        -- Special values:
185
        --         None
186
        -- Domain:
187
        --         X in REAL; Y in REAL and Y /= 0.0
188
        -- Error conditions:
189
        --         Error if Y = 0.0
190
        -- Range:
191
        --         ABS(MOD(X,Y)) < ABS(Y)
192
        -- Notes:
193
        --         None
194
 
195
    function REALMAX (X, Y : in REAL ) return REAL;
196
        -- Purpose:
197
        --         Returns the algebraically larger of X and Y
198
        -- Special values:
199
        --         REALMAX(X,Y) = X when X = Y
200
        -- Domain:
201
        --         X in REAL; Y in REAL
202
        -- Error conditions:
203
        --         None
204
        -- Range:
205
        --         REALMAX(X,Y) is mathematically unbounded
206
        -- Notes:
207
        --         None
208
 
209
    function REALMIN (X, Y : in REAL ) return REAL;
210
        -- Purpose:
211
        --         Returns the algebraically smaller of X and Y
212
        -- Special values:
213
        --         REALMIN(X,Y) = X when X = Y
214
        -- Domain:
215
        --         X in REAL; Y in REAL
216
        -- Error conditions:
217
        --         None
218
        -- Range:
219
        --         REALMIN(X,Y) is mathematically unbounded
220
        -- Notes:
221
        --         None
222
 
223
    procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE; variable X:out REAL);
224
        -- Purpose:
225
        --         Returns, in X, a pseudo-random number with uniform
226
        --         distribution in the open interval (0.0, 1.0).
227
        -- Special values:
228
        --         None
229
        -- Domain:
230
        --         1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
231
        -- Error conditions:
232
        --         Error if SEED1 or SEED2 outside of valid domain
233
        -- Range:
234
        --         0.0 < X < 1.0
235
        -- Notes:
236
        --         a) The semantics for this function are described by the
237
        --            algorithm published by Pierre L'Ecuyer in "Communications
238
        --            of the ACM," vol. 31, no. 6, June 1988, pp. 742-774.
239
        --            The algorithm is based on the combination of two
240
        --            multiplicative linear congruential generators for 32-bit
241
        --            platforms.
242
        --
243
        --         b) Before the first call to UNIFORM, the seed values
244
        --            (SEED1, SEED2) have to be initialized to values in the range
245
        --            [1, 2147483562] and [1, 2147483398] respectively.  The
246
        --            seed values are modified after each call to UNIFORM.
247
        --
248
        --         c) This random number generator is portable for 32-bit
249
        --            computers, and it has a period of ~2.30584*(10**18) for each
250
        --            set of seed values.
251
        --
252
        --         d) For information on spectral tests for the algorithm, refer
253
        --            to the L'Ecuyer article.
254
 
255
    function SQRT (X : in REAL ) return REAL;
256
        -- Purpose:
257
        --         Returns square root of X
258
        -- Special values:
259
        --         SQRT(0.0) = 0.0
260
        --         SQRT(1.0) = 1.0
261
        -- Domain:
262
        --         X >= 0.0
263
        -- Error conditions:
264
        --         Error if X < 0.0
265
        -- Range:
266
        --         SQRT(X) >= 0.0
267
        -- Notes:
268
        --         a) The upper bound of the reachable range of SQRT is
269
        --            approximately given by:
270
        --                SQRT(X) <= SQRT(REAL'HIGH)
271
 
272
    function CBRT (X : in REAL ) return REAL;
273
        -- Purpose:
274
        --         Returns cube root of X
275
        -- Special values:
276
        --         CBRT(0.0) = 0.0
277
        --         CBRT(1.0) = 1.0
278
        --         CBRT(-1.0) = -1.0
279
        -- Domain:
280
        --         X in REAL
281
        -- Error conditions:
282
        --         None
283
        -- Range:
284
        --         CBRT(X) is mathematically unbounded
285
        -- Notes:
286
        --         a) The reachable range of CBRT is approximately given by:
287
        --                ABS(CBRT(X)) <= CBRT(REAL'HIGH)
288
 
289
    function "**" (X : in INTEGER; Y : in REAL) return REAL;
290
        -- Purpose:
291
        --         Returns Y power of X ==>  X**Y
292
        -- Special values:
293
        --         X**0.0 = 1.0; X /= 0
294
        --         0**Y = 0.0; Y > 0.0
295
        --         X**1.0 = REAL(X); X >= 0
296
        --         1**Y = 1.0
297
        -- Domain:
298
        --         X > 0
299
        --         X = 0 for Y > 0.0
300
        --         X < 0 for Y = 0.0
301
        -- Error conditions:
302
        --         Error if X < 0 and Y /= 0.0
303
        --         Error if X = 0 and Y <= 0.0
304
        -- Range:
305
        --         X**Y >= 0.0
306
        -- Notes:
307
        --         a) The upper bound of the reachable range for "**" is
308
        --            approximately given by:
309
        --                X**Y <= REAL'HIGH
310
 
311
    function "**" (X : in REAL; Y : in REAL) return REAL;
312
        -- Purpose:
313
        --         Returns Y power of X ==>  X**Y
314
        -- Special values:
315
        --         X**0.0 = 1.0; X /= 0.0
316
        --         0.0**Y = 0.0; Y > 0.0
317
        --         X**1.0 = X; X >= 0.0
318
        --         1.0**Y = 1.0
319
        -- Domain:
320
        --         X > 0.0
321
        --         X = 0.0 for Y > 0.0
322
        --         X < 0.0 for Y = 0.0
323
        -- Error conditions:
324
        --         Error if X < 0.0 and Y /= 0.0
325
        --         Error if X = 0.0 and Y <= 0.0
326
        -- Range:
327
        --         X**Y >= 0.0
328
        -- Notes:
329
        --         a) The upper bound of the reachable range for "**" is
330
        --            approximately given by:
331
        --                X**Y <= REAL'HIGH
332
 
333
    function EXP (X : in REAL ) return REAL;
334
        -- Purpose:
335
        --         Returns e**X; where e = MATH_E
336
        -- Special values:
337
        --         EXP(0.0) = 1.0
338
        --         EXP(1.0) = MATH_E
339
        --         EXP(-1.0) = MATH_1_OVER_E
340
        --         EXP(X) = 0.0 for X <= -LOG(REAL'HIGH)
341
        -- Domain:
342
        --         X in REAL such that EXP(X) <= REAL'HIGH
343
        -- Error conditions:
344
        --         Error if X > LOG(REAL'HIGH)
345
        -- Range:
346
        --         EXP(X) >= 0.0
347
        -- Notes:
348
        --         a) The usable domain of EXP is approximately given by:
349
        --                X <= LOG(REAL'HIGH)
350
 
351
    function LOG (X : in REAL ) return REAL;
352
        -- Purpose:
353
        --         Returns natural logarithm of X
354
        -- Special values:
355
        --         LOG(1.0) = 0.0
356
        --         LOG(MATH_E) = 1.0
357
        -- Domain:
358
        --         X > 0.0
359
        -- Error conditions:
360
        --         Error if X <= 0.0
361
        -- Range:
362
        --         LOG(X) is mathematically unbounded
363
        -- Notes:
364
        --         a) The reachable range of LOG is approximately given by:
365
        --                LOG(0+) <= LOG(X) <= LOG(REAL'HIGH)
366
 
367
    function LOG2 (X : in REAL ) return REAL;
368
        -- Purpose:
369
        --         Returns logarithm base 2 of X
370
        -- Special values:
371
        --         LOG2(1.0) = 0.0
372
        --         LOG2(2.0) = 1.0
373
        -- Domain:
374
        --         X > 0.0
375
        -- Error conditions:
376
        --         Error if X <= 0.0
377
        -- Range:
378
        --         LOG2(X) is mathematically unbounded
379
        -- Notes:
380
        --         a) The reachable range of LOG2 is approximately given by:
381
        --                LOG2(0+) <= LOG2(X) <= LOG2(REAL'HIGH)
382
 
383
    function LOG10 (X : in REAL ) return REAL;
384
        -- Purpose:
385
        --         Returns logarithm base 10 of X
386
        -- Special values:
387
        --         LOG10(1.0) = 0.0
388
        --         LOG10(10.0) = 1.0
389
        -- Domain:
390
        --         X > 0.0
391
        -- Error conditions:
392
        --         Error if X <= 0.0
393
        -- Range:
394
        --         LOG10(X) is mathematically unbounded
395
        -- Notes:
396
        --         a) The reachable range of LOG10 is approximately given by:
397
        --                LOG10(0+) <= LOG10(X) <= LOG10(REAL'HIGH)
398
 
399
    function LOG (X: in REAL; BASE: in REAL) return REAL;
400
        -- Purpose:
401
        --         Returns logarithm base BASE of X
402
        -- Special values:
403
        --         LOG(1.0, BASE) = 0.0
404
        --         LOG(BASE, BASE) = 1.0
405
        -- Domain:
406
        --         X > 0.0
407
        --         BASE > 0.0
408
        --         BASE /= 1.0
409
        -- Error conditions:
410
        --         Error if X <= 0.0
411
        --         Error if BASE <= 0.0
412
        --         Error if BASE = 1.0
413
        -- Range:
414
        --         LOG(X, BASE) is mathematically unbounded
415
        -- Notes:
416
        --         a) When BASE > 1.0, the reachable range of LOG is
417
        --            approximately given by:
418
        --                LOG(0+, BASE) <= LOG(X, BASE) <= LOG(REAL'HIGH, BASE)
419
        --         b) When 0.0 < BASE < 1.0, the reachable range of LOG is
420
        --            approximately given by:
421
        --                LOG(REAL'HIGH, BASE) <= LOG(X, BASE) <= LOG(0+, BASE)
422
 
423
    function  SIN (X : in REAL ) return REAL;
424
        -- Purpose:
425
        --         Returns sine of X; X in radians
426
        -- Special values:
427
        --         SIN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER
428
        --         SIN(X) = 1.0 for X = (4*k+1)*MATH_PI_OVER_2, where k is an
429
        --                                                           INTEGER
430
        --         SIN(X) = -1.0 for X = (4*k+3)*MATH_PI_OVER_2, where k is an
431
        --                                                           INTEGER
432
        -- Domain:
433
        --         X in REAL
434
        -- Error conditions:
435
        --         None
436
        -- Range:
437
        --         ABS(SIN(X)) <= 1.0
438
        -- Notes:
439
        --         a) For larger values of ABS(X), degraded accuracy is allowed.
440
 
441
    function  COS ( X : in REAL ) return REAL;
442
        -- Purpose:
443
        --         Returns cosine of X; X in radians
444
        -- Special values:
445
        --         COS(X) = 0.0 for X = (2*k+1)*MATH_PI_OVER_2, where k is an
446
        --                                                            INTEGER
447
        --         COS(X) = 1.0 for X = (2*k)*MATH_PI, where k is an INTEGER
448
        --         COS(X) = -1.0 for X = (2*k+1)*MATH_PI, where k is an INTEGER
449
        -- Domain:
450
        --         X in REAL
451
        -- Error conditions:
452
        --         None
453
        -- Range:
454
        --         ABS(COS(X)) <= 1.0
455
        -- Notes:
456
        --         a) For larger values of ABS(X), degraded accuracy is allowed.
457
 
458
    function  TAN (X : in REAL ) return REAL;
459
        -- Purpose:
460
        --         Returns tangent of X; X in radians
461
        -- Special values:
462
        --         TAN(X) = 0.0 for X = k*MATH_PI, where k is an INTEGER
463
        -- Domain:
464
        --         X in REAL and
465
        --         X /= (2*k+1)*MATH_PI_OVER_2, where k is an INTEGER
466
        -- Error conditions:
467
        --         Error if X = ((2*k+1) * MATH_PI_OVER_2), where k is an
468
        --                                                           INTEGER
469
        -- Range:
470
        --         TAN(X) is mathematically unbounded
471
        -- Notes:
472
        --         a) For larger values of ABS(X), degraded accuracy is allowed.
473
 
474
    function  ARCSIN (X : in REAL ) return REAL;
475
        -- Purpose:
476
        --         Returns inverse sine of X
477
        -- Special values:
478
        --         ARCSIN(0.0) = 0.0
479
        --         ARCSIN(1.0) = MATH_PI_OVER_2
480
        --         ARCSIN(-1.0) = -MATH_PI_OVER_2
481
        -- Domain:
482
        --         ABS(X) <= 1.0
483
        -- Error conditions:
484
        --         Error if ABS(X) > 1.0
485
        -- Range:
486
        --         ABS(ARCSIN(X) <= MATH_PI_OVER_2
487
        -- Notes:
488
        --         None
489
 
490
    function  ARCCOS (X : in REAL ) return REAL;
491
        -- Purpose:
492
        --         Returns inverse cosine of X
493
        -- Special values:
494
        --         ARCCOS(1.0) = 0.0
495
        --         ARCCOS(0.0) = MATH_PI_OVER_2
496
        --         ARCCOS(-1.0) = MATH_PI
497
        -- Domain:
498
        --         ABS(X) <= 1.0
499
        -- Error conditions:
500
        --         Error if ABS(X) > 1.0
501
        -- Range:
502
        --         0.0 <= ARCCOS(X) <= MATH_PI
503
        -- Notes:
504
        --         None
505
 
506
    function  ARCTAN (Y : in REAL) return REAL;
507
        -- Purpose:
508
        --         Returns the value of the angle in radians of the point
509
        --        (1.0, Y), which is in rectangular coordinates
510
        -- Special values:
511
        --         ARCTAN(0.0) = 0.0
512
        -- Domain:
513
        --         Y in REAL
514
        -- Error conditions:
515
        --         None
516
        -- Range:
517
        --         ABS(ARCTAN(Y)) <= MATH_PI_OVER_2
518
        -- Notes:
519
        --         None
520
 
521
    function  ARCTAN (Y : in REAL; X : in REAL) return REAL;
522
        -- Purpose:
523
        --         Returns the principal value of the angle in radians of
524
        --         the point (X, Y), which is in rectangular coordinates
525
        -- Special values:
526
        --         ARCTAN(0.0, X) = 0.0 if X > 0.0
527
        --         ARCTAN(0.0, X) = MATH_PI if X < 0.0
528
        --         ARCTAN(Y, 0.0) = MATH_PI_OVER_2 if Y > 0.0
529
        --         ARCTAN(Y, 0.0) = -MATH_PI_OVER_2 if Y < 0.0
530
        -- Domain:
531
        --         Y in REAL
532
        --         X in REAL, X /= 0.0 when Y = 0.0
533
        -- Error conditions:
534
        --         Error if X = 0.0 and Y = 0.0
535
        -- Range:
536
        --         -MATH_PI < ARCTAN(Y,X) <= MATH_PI
537
        -- Notes:
538
        --         None
539
 
540
    function SINH (X : in REAL) return REAL;
541
        -- Purpose:
542
        --         Returns hyperbolic sine of X
543
        -- Special values:
544
        --         SINH(0.0) = 0.0
545
        -- Domain:
546
        --         X in REAL
547
        -- Error conditions:
548
        --         None
549
        -- Range:
550
        --         SINH(X) is mathematically unbounded
551
        -- Notes:
552
        --         a) The usable domain of SINH is approximately given by:
553
        --                ABS(X) <= LOG(REAL'HIGH)
554
 
555
 
556
    function COSH (X : in REAL) return REAL;
557
        -- Purpose:
558
        --         Returns hyperbolic cosine of X
559
        -- Special values:
560
        --         COSH(0.0) = 1.0
561
        -- Domain:
562
        --         X in REAL
563
        -- Error conditions:
564
        --         None
565
        -- Range:
566
        --         COSH(X) >= 1.0
567
        -- Notes:
568
        --         a) The usable domain of COSH is approximately given by:
569
        --                ABS(X) <= LOG(REAL'HIGH)
570
 
571
    function TANH (X : in REAL) return REAL;
572
        -- Purpose:
573
        --         Returns hyperbolic tangent of X
574
        -- Special values:
575
        --         TANH(0.0) = 0.0
576
        -- Domain:
577
        --         X in REAL
578
        -- Error conditions:
579
        --         None
580
        -- Range:
581
        --         ABS(TANH(X)) <= 1.0
582
        -- Notes:
583
        --         None
584
 
585
    function ARCSINH (X : in REAL) return REAL;
586
        -- Purpose:
587
        --         Returns inverse hyperbolic sine of X
588
        -- Special values:
589
        --         ARCSINH(0.0) = 0.0
590
        -- Domain:
591
        --         X in REAL
592
        -- Error conditions:
593
        --         None
594
        -- Range:
595
        --         ARCSINH(X) is mathematically unbounded
596
        -- Notes:
597
        --         a) The reachable range of ARCSINH is approximately given by:
598
        --                ABS(ARCSINH(X)) <= LOG(REAL'HIGH)
599
 
600
    function ARCCOSH (X : in REAL) return REAL;
601
        -- Purpose:
602
        --         Returns inverse hyperbolic cosine of X
603
        -- Special values:
604
        --         ARCCOSH(1.0) = 0.0
605
        -- Domain:
606
        --         X >= 1.0
607
        -- Error conditions:
608
        --         Error if X < 1.0
609
        -- Range:
610
        --         ARCCOSH(X) >= 0.0
611
        -- Notes:
612
        --         a) The upper bound of the reachable range of ARCCOSH is
613
        --            approximately given by:   ARCCOSH(X) <= LOG(REAL'HIGH)
614
 
615
    function ARCTANH (X : in REAL) return REAL;
616
        -- Purpose:
617
        --         Returns inverse hyperbolic tangent of X
618
        -- Special values:
619
        --         ARCTANH(0.0) = 0.0
620
        -- Domain:
621
        --         ABS(X) < 1.0
622
        -- Error conditions:
623
        --         Error if ABS(X) >= 1.0
624
        -- Range:
625
        --         ARCTANH(X) is mathematically unbounded
626
        -- Notes:
627
        --         a) The reachable range of ARCTANH is approximately given by:
628
        --                ABS(ARCTANH(X)) < LOG(REAL'HIGH)
629
 
630
end  MATH_REAL;
631
 
632
 
633
 
634
------------------------------------------------------------------------
635
--
636
-- Copyright 1996 by IEEE. All rights reserved.
637
 
638
-- This source file is an informative part of IEEE Std 1076.2-1996, IEEE Standard 
639
-- VHDL Mathematical Packages. This source file may not be copied, sold, or 
640
-- included with software that is sold without written permission from the IEEE
641
-- Standards Department. This source file may be used to implement this standard 
642
-- and may be distributed in compiled form in any manner so long as the 
643
-- compiled form does not allow direct decompilation of the original source file.
644
-- This source file may be copied for individual use between licensed users. 
645
-- This source file is provided on an AS IS basis. The IEEE disclaims ANY 
646
-- WARRANTY EXPRESS OR IMPLIED INCLUDING ANY WARRANTY OF MERCHANTABILITY 
647
-- AND FITNESS FOR USE FOR A PARTICULAR PURPOSE. The user of the source 
648
-- file shall indemnify and hold IEEE harmless from any damages or liability 
649
-- arising out of the use thereof.
650
 
651
--
652
-- Title:       Standard VHDL Mathematical Packages (IEEE Std 1076.2-1996,
653
--              MATH_REAL)
654
--
655
-- Library:     This package shall be compiled into a library
656
--              symbolically named IEEE.
657
--
658
-- Developers:  IEEE DASC VHDL Mathematical Packages Working Group
659
--
660
-- Purpose:     This package body is a nonnormative implementation of the 
661
--              functionality defined in the MATH_REAL package declaration.
662
--
663
-- Limitation:  The values generated by the functions in this package may
664
--              vary from platform to platform, and the precision of results
665
--              is only guaranteed to be the minimum required by IEEE Std 1076
666
--              -1993.
667
--
668
-- Notes:
669
--              The "package declaration" defines the types, subtypes, and
670
--              declarations of MATH_REAL.
671
--              The standard mathematical definition and conventional meaning
672
--              of the mathematical functions that are part of this standard
673
--              represent the formal semantics of the implementation of the
674
--              MATH_REAL package declaration.  The purpose of the MATH_REAL
675
--              package body is to clarify such semantics and provide a
676
--              guideline for implementations to verify their implementation
677
--              of MATH_REAL.  Tool developers may choose to implement
678
--              the package body in the most efficient manner available to them.
679
--
680
-- -----------------------------------------------------------------------------
681
-- Version    : 1.5
682
-- Date       : 24 July 1996
683
-- -----------------------------------------------------------------------------
684
 
685
package body MATH_REAL is
686
 
687
    --
688
    -- Local Constants for Use in the Package Body Only
689
    --
690
    constant  MATH_E_P2 :  REAL := 7.38905_60989_30650;   -- e**2
691
    constant  MATH_E_P10 :  REAL := 22026.46579_48067_17; -- e**10
692
    constant  MATH_EIGHT_PI : REAL := 25.13274_12287_18345_90770_115; --8*pi
693
    constant  MAX_ITER:  INTEGER := 27;  -- Maximum precision factor for cordic
694
    constant  MAX_COUNT: INTEGER := 150; -- Maximum count for number of tries
695
    constant  BASE_EPS: REAL := 0.00001;  -- Factor for convergence criteria
696
    constant  KC : REAL := 6.0725293500888142e-01; -- Constant for cordic
697
 
698
    --
699
    -- Local Type Declarations for Cordic Operations
700
    --
701
    type REAL_VECTOR is array (NATURAL range <>) of REAL;
702
    type NATURAL_VECTOR is array (NATURAL range <>) of NATURAL;
703
    subtype REAL_VECTOR_N is REAL_VECTOR (0 to MAX_ITER);
704
    subtype REAL_ARR_2 is REAL_VECTOR (0 to 1);
705
    subtype REAL_ARR_3 is REAL_VECTOR (0 to 2);
706
    subtype QUADRANT is INTEGER range 0 to 3;
707
    type CORDIC_MODE_TYPE is (ROTATION, VECTORING);
708
 
709
    --
710
    -- Auxiliary Functions for Cordic Algorithms
711
    --
712
    function POWER_OF_2_SERIES (D : in NATURAL_VECTOR; INITIAL_VALUE : in REAL;
713
                NUMBER_OF_VALUES : in NATURAL) return REAL_VECTOR is
714
        -- Description:
715
        --        Returns power of two for a vector of values
716
        -- Notes:
717
        --        None
718
        --
719
        variable V : REAL_VECTOR (0 to NUMBER_OF_VALUES);
720
        variable TEMP : REAL := INITIAL_VALUE;
721
        variable FLAG : BOOLEAN := TRUE;
722
    begin
723
              for I in 0 to NUMBER_OF_VALUES loop
724
                 V(I) := TEMP;
725
                 for P in D'RANGE loop
726
                            if I = D(P) then
727
                                FLAG := FALSE;
728
                                exit;
729
                            end if;
730
                 end loop;
731
                 if FLAG then
732
                            TEMP := TEMP/2.0;
733
                 end if;
734
                 FLAG := TRUE;
735
              end loop;
736
              return V;
737
    end POWER_OF_2_SERIES;
738
 
739
 
740
    constant TWO_AT_MINUS : REAL_VECTOR := POWER_OF_2_SERIES(
741
                                               NATURAL_VECTOR'(100, 90),1.0,
742
                                                                  MAX_ITER);
743
 
744
    constant EPSILON : REAL_VECTOR_N := (
745
                                        7.8539816339744827e-01,
746
                                        4.6364760900080606e-01,
747
                                        2.4497866312686413e-01,
748
                                        1.2435499454676144e-01,
749
                                        6.2418809995957351e-02,
750
                                        3.1239833430268277e-02,
751
                                        1.5623728620476830e-02,
752
                                        7.8123410601011116e-03,
753
                                        3.9062301319669717e-03,
754
                                        1.9531225164788189e-03,
755
                                        9.7656218955931937e-04,
756
                                        4.8828121119489829e-04,
757
                                        2.4414062014936175e-04,
758
                                        1.2207031189367021e-04,
759
                                        6.1035156174208768e-05,
760
                                        3.0517578115526093e-05,
761
                                        1.5258789061315760e-05,
762
                                        7.6293945311019699e-06,
763
                                        3.8146972656064960e-06,
764
                                        1.9073486328101870e-06,
765
                                        9.5367431640596080e-07,
766
                                        4.7683715820308876e-07,
767
                                        2.3841857910155801e-07,
768
                                        1.1920928955078067e-07,
769
                                        5.9604644775390553e-08,
770
                                        2.9802322387695303e-08,
771
                                        1.4901161193847654e-08,
772
                                        7.4505805969238281e-09
773
                                       );
774
 
775
    function CORDIC ( X0 : in REAL;
776
                      Y0 : in REAL;
777
                      Z0 : in REAL;
778
                      N : in NATURAL;                 --  Precision factor
779
            CORDIC_MODE : in CORDIC_MODE_TYPE         --  Rotation (Z -> 0)
780
                                                      --  or vectoring (Y -> 0)
781
                    ) return REAL_ARR_3 is
782
        -- Description:
783
        --        Compute cordic values
784
        -- Notes:
785
        --         None
786
             variable X : REAL := X0;
787
             variable Y : REAL := Y0;
788
             variable Z : REAL := Z0;
789
             variable X_TEMP : REAL;
790
    begin
791
       if CORDIC_MODE = ROTATION then
792
           for K in 0 to N loop
793
                      X_TEMP := X;
794
                      if ( Z >= 0.0) then
795
                               X := X - Y * TWO_AT_MINUS(K);
796
                               Y := Y + X_TEMP * TWO_AT_MINUS(K);
797
                               Z := Z - EPSILON(K);
798
                      else
799
                               X := X + Y * TWO_AT_MINUS(K);
800
                               Y := Y - X_TEMP * TWO_AT_MINUS(K);
801
                               Z := Z + EPSILON(K);
802
                      end if;
803
            end loop;
804
        else
805
            for K in 0 to N loop
806
                    X_TEMP := X;
807
                    if ( Y < 0.0) then
808
                               X := X - Y * TWO_AT_MINUS(K);
809
                               Y := Y + X_TEMP * TWO_AT_MINUS(K);
810
                               Z := Z - EPSILON(K);
811
                    else
812
                               X := X + Y * TWO_AT_MINUS(K);
813
                               Y := Y - X_TEMP * TWO_AT_MINUS(K);
814
                               Z := Z + EPSILON(K);
815
                    end if;
816
            end loop;
817
        end if;
818
        return REAL_ARR_3'(X, Y, Z);
819
    end CORDIC;
820
 
821
    --
822
    -- Bodies for Global Mathematical Functions Start Here
823
    --
824
    function SIGN (X: in REAL ) return REAL is
825
        -- Description:
826
        --        See function declaration in IEEE Std 1076.2-1996
827
        -- Notes:
828
        --        None
829
    begin
830
           if  ( X > 0.0 )  then
831
                return 1.0;
832
           elsif ( X < 0.0 )  then
833
                return -1.0;
834
           else
835
                return 0.0;
836
           end if;
837
    end SIGN;
838
 
839
    function CEIL (X : in REAL ) return REAL is
840
        -- Description:
841
        --        See function declaration in IEEE Std 1076.2-1996
842
        -- Notes:
843
        --        a) No conversion to an INTEGER type is expected, so truncate
844
        --           cannot overflow for large arguments
845
        --        b) The domain supported by this function is X <= LARGE
846
        --        c) Returns X if ABS(X) >= LARGE
847
 
848
        constant LARGE: REAL  := REAL(INTEGER'HIGH);
849
        variable RD: REAL;
850
 
851
    begin
852
         if ABS(X) >= LARGE then
853
               return X;
854
         end if;
855
 
856
         RD := REAL ( INTEGER(X));
857
         if RD = X then
858
            return X;
859
         end if;
860
 
861
            if X > 0.0 then
862
                       if RD >= X then
863
                                  return RD;
864
                       else
865
                                  return RD + 1.0;
866
                       end if;
867
            elsif  X = 0.0  then
868
                return 0.0;
869
            else
870
                       if RD <= X then
871
                                  return RD + 1.0;
872
                       else
873
                                  return RD;
874
                       end if;
875
            end if;
876
    end CEIL;
877
 
878
    function FLOOR (X : in REAL ) return REAL is
879
        -- Description:
880
        --        See function declaration in IEEE Std 1076.2-1996
881
        -- Notes:
882
        --        a) No conversion to an INTEGER type is expected, so truncate
883
        --           cannot overflow for large arguments
884
        --        b) The domain supported by this function is ABS(X) <= LARGE
885
        --        c) Returns X if ABS(X) >= LARGE
886
 
887
        constant LARGE: REAL  := REAL(INTEGER'HIGH);
888
        variable RD: REAL;
889
 
890
    begin
891
        if ABS( X ) >= LARGE then
892
                    return X;
893
        end if;
894
 
895
        RD := REAL ( INTEGER(X));
896
        if RD = X then
897
                return X;
898
        end if;
899
 
900
        if X > 0.0 then
901
                      if RD <= X then
902
                                  return RD;
903
                       else
904
                                  return RD - 1.0;
905
                       end if;
906
        elsif  X = 0.0  then
907
                return 0.0;
908
        else
909
                   if RD >= X then
910
                                  return RD - 1.0;
911
                   else
912
                                  return RD;
913
                   end if;
914
        end if;
915
    end FLOOR;
916
 
917
    function ROUND (X : in REAL ) return REAL is
918
        -- Description:
919
        --        See function declaration in IEEE Std 1076.2-1996
920
        -- Notes:
921
        --         a) Returns 0.0 if X = 0.0
922
        --         b) Returns FLOOR(X + 0.5) if X > 0
923
        --         c) Returns CEIL(X - 0.5) if X < 0
924
 
925
    begin
926
           if  X > 0.0  then
927
                return FLOOR(X + 0.5);
928
           elsif  X < 0.0  then
929
                return CEIL( X - 0.5);
930
           else
931
                return 0.0;
932
           end if;
933
    end ROUND;
934
 
935
    function TRUNC (X : in REAL ) return REAL is
936
        -- Description:
937
        --        See function declaration in IEEE Std 1076.2-1996
938
        -- Notes:
939
        --         a) Returns 0.0 if X = 0.0
940
        --         b) Returns FLOOR(X) if X > 0
941
        --         c) Returns CEIL(X) if X < 0
942
 
943
    begin
944
           if  X > 0.0  then
945
                return FLOOR(X);
946
           elsif  X < 0.0  then
947
                return CEIL( X);
948
           else
949
                return 0.0;
950
           end if;
951
    end TRUNC;
952
 
953
 
954
 
955
 
956
    function "MOD" (X, Y: in REAL ) return REAL is
957
        -- Description:
958
        --        See function declaration in IEEE Std 1076.2-1996
959
        -- Notes:
960
        --        a) Returns 0.0 on error
961
 
962
        variable XNEGATIVE : BOOLEAN := X < 0.0;
963
        variable YNEGATIVE : BOOLEAN := Y < 0.0;
964
        variable VALUE : REAL;
965
    begin
966
        -- Check validity of input arguments
967
            if (Y = 0.0) then
968
                 assert FALSE
969
                        report "MOD(X, 0.0) is undefined"
970
                        severity ERROR;
971
                 return 0.0;
972
              end if;
973
 
974
        -- Compute value
975
        if ( XNEGATIVE ) then
976
                if ( YNEGATIVE ) then
977
                        VALUE := X + (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
978
                else
979
                        VALUE := X + (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
980
                end if;
981
        else
982
                if ( YNEGATIVE ) then
983
                        VALUE := X - (CEIL(ABS(X)/ABS(Y)))*ABS(Y);
984
                else
985
                        VALUE := X - (FLOOR(ABS(X)/ABS(Y)))*ABS(Y);
986
                end if;
987
        end if;
988
 
989
        return VALUE;
990
    end "MOD";
991
 
992
 
993
    function REALMAX (X, Y : in REAL ) return REAL is
994
        -- Description:
995
        --        See function declaration in IEEE Std 1076.2-1996
996
        -- Notes:
997
        --        a) REALMAX(X,Y) = X when X = Y
998
        --
999
    begin
1000
        if X >= Y then
1001
           return X;
1002
        else
1003
           return Y;
1004
        end if;
1005
    end REALMAX;
1006
 
1007
    function REALMIN (X, Y : in REAL ) return REAL is
1008
        -- Description:
1009
        --        See function declaration in IEEE Std 1076.2-1996
1010
        -- Notes:
1011
        --        a) REALMIN(X,Y) = X when X = Y
1012
        --
1013
    begin
1014
        if X <= Y then
1015
           return X;
1016
        else
1017
           return Y;
1018
        end if;
1019
    end REALMIN;
1020
 
1021
 
1022
    procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE;variable X:out REAL)
1023
                                                                         is
1024
        -- Description:
1025
        --        See function declaration in IEEE Std 1076.2-1996
1026
        -- Notes:
1027
        --        a) Returns 0.0 on error
1028
        --
1029
        variable Z, K: INTEGER;
1030
        variable TSEED1 : INTEGER := INTEGER'(SEED1);
1031
        variable TSEED2 : INTEGER := INTEGER'(SEED2);
1032
    begin
1033
        -- Check validity of arguments
1034
        if SEED1 > 2147483562 then
1035
                assert FALSE
1036
                        report "SEED1 > 2147483562 in UNIFORM"
1037
                        severity ERROR;
1038
                X := 0.0;
1039
                return;
1040
        end if;
1041
 
1042
        if SEED2 > 2147483398 then
1043
                assert FALSE
1044
                        report "SEED2 > 2147483398 in UNIFORM"
1045
                        severity ERROR;
1046
                X := 0.0;
1047
                return;
1048
        end if;
1049
 
1050
        -- Compute new seed values and pseudo-random number
1051
        K := TSEED1/53668;
1052
        TSEED1 := 40014 * (TSEED1 - K * 53668) - K * 12211;
1053
 
1054
        if TSEED1 < 0  then
1055
                TSEED1 := TSEED1 + 2147483563;
1056
        end if;
1057
 
1058
        K := TSEED2/52774;
1059
        TSEED2 := 40692 * (TSEED2 - K * 52774) - K * 3791;
1060
 
1061
        if TSEED2 < 0  then
1062
                TSEED2 := TSEED2 + 2147483399;
1063
        end if;
1064
 
1065
        Z := TSEED1 - TSEED2;
1066
        if Z < 1 then
1067
                Z := Z + 2147483562;
1068
        end if;
1069
 
1070
        -- Get output values
1071
        SEED1 := POSITIVE'(TSEED1);
1072
        SEED2 := POSITIVE'(TSEED2);
1073
        X :=  REAL(Z)*4.656613e-10;
1074
    end UNIFORM;
1075
 
1076
 
1077
 
1078
    function SQRT (X : in REAL ) return REAL is
1079
        -- Description:
1080
        --        See function declaration in IEEE Std 1076.2-1996
1081
        -- Notes:
1082
        --        a) Uses the Newton-Raphson approximation:
1083
        --            F(n+1) = 0.5*[F(n) + x/F(n)]
1084
        --        b) Returns 0.0 on error
1085
        --
1086
 
1087
        constant EPS : REAL := BASE_EPS*BASE_EPS; -- Convergence factor
1088
 
1089
        variable INIVAL: REAL;
1090
        variable OLDVAL : REAL ;
1091
        variable NEWVAL : REAL ;
1092
        variable COUNT : INTEGER := 1;
1093
 
1094
    begin
1095
        -- Check validity of argument
1096
        if ( X < 0.0 ) then
1097
                assert FALSE
1098
                        report "X < 0.0 in SQRT(X)"
1099
                        severity ERROR;
1100
                return 0.0;
1101
        end if;
1102
 
1103
        -- Get the square root for special cases
1104
        if X = 0.0 then
1105
                  return 0.0;
1106
        else
1107
                if ( X = 1.0 ) then
1108
                        return 1.0;
1109
                end if;
1110
        end if;
1111
 
1112
        -- Get the square root for general cases
1113
        INIVAL := EXP(LOG(X)*(0.5)); -- Mathematically correct but imprecise
1114
        OLDVAL := INIVAL;
1115
        NEWVAL := (X/OLDVAL + OLDVAL)*0.5;
1116
 
1117
        -- Check for  relative and absolute error and max count
1118
        while  ( ( (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS) OR
1119
                   (ABS(NEWVAL - OLDVAL) > EPS) ) AND
1120
                   (COUNT < MAX_COUNT) )  loop
1121
                OLDVAL := NEWVAL;
1122
                NEWVAL := (X/OLDVAL + OLDVAL)*0.5;
1123
                COUNT := COUNT + 1;
1124
        end loop;
1125
        return NEWVAL;
1126
    end SQRT;
1127
 
1128
    function CBRT (X : in REAL ) return REAL is
1129
        -- Description:
1130
        --        See function declaration in IEEE Std 1076.2-1996
1131
        -- Notes:
1132
        --        a) Uses the Newton-Raphson approximation:
1133
        --            F(n+1) = (1/3)*[2*F(n) + x/F(n)**2];
1134
        --
1135
        constant EPS : REAL := BASE_EPS*BASE_EPS;
1136
 
1137
        variable INIVAL: REAL;
1138
        variable XLOCAL : REAL := X;
1139
        variable NEGATIVE : BOOLEAN := X < 0.0;
1140
        variable OLDVAL : REAL ;
1141
        variable NEWVAL : REAL ;
1142
        variable COUNT : INTEGER := 1;
1143
 
1144
    begin
1145
 
1146
        -- Compute root for special cases
1147
        if X = 0.0 then
1148
                return 0.0;
1149
        elsif ( X = 1.0 ) then
1150
                return 1.0;
1151
        else
1152
                if X = -1.0 then
1153
                        return -1.0;
1154
                end if;
1155
        end if;
1156
 
1157
        -- Compute root for general cases
1158
        if NEGATIVE then
1159
                XLOCAL := -X;
1160
        end if;
1161
 
1162
        INIVAL := EXP(LOG(XLOCAL)/(3.0)); -- Mathematically correct but
1163
                                          -- imprecise
1164
        OLDVAL := INIVAL;
1165
        NEWVAL := (XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0;
1166
 
1167
        -- Check for relative and absolute errors and max count
1168
        while ( (  (ABS((NEWVAL -OLDVAL)/NEWVAL) > EPS ) OR
1169
                   (ABS(NEWVAL - OLDVAL) > EPS ) )  AND
1170
                   ( COUNT < MAX_COUNT ) ) loop
1171
                OLDVAL := NEWVAL;
1172
                NEWVAL :=(XLOCAL/(OLDVAL*OLDVAL) + 2.0*OLDVAL)/3.0;
1173
                COUNT := COUNT + 1;
1174
        end loop;
1175
 
1176
        if NEGATIVE then
1177
                NEWVAL := -NEWVAL;
1178
        end if;
1179
 
1180
        return NEWVAL;
1181
    end CBRT;
1182
 
1183
    function "**" (X : in INTEGER; Y : in REAL) return REAL is
1184
        -- Description:
1185
        --        See function declaration in IEEE Std 1076.2-1996
1186
        -- Notes:
1187
        --        a) Returns 0.0 on error condition
1188
 
1189
    begin
1190
        -- Check validity of argument
1191
        if ( ( X < 0  ) and ( Y /= 0.0 ) ) then
1192
                assert FALSE
1193
                        report "X < 0 and Y /= 0.0 in X**Y"
1194
                        severity ERROR;
1195
                return 0.0;
1196
        end if;
1197
 
1198
        if ( ( X = 0  ) and ( Y <= 0.0 ) ) then
1199
                assert FALSE
1200
                        report "X = 0 and Y <= 0.0 in X**Y"
1201
                        severity ERROR;
1202
                return 0.0;
1203
        end if;
1204
 
1205
        -- Get value for special cases
1206
        if ( X = 0  and  Y > 0.0 ) then
1207
                return 0.0;
1208
        end if;
1209
 
1210
        if ( X = 1 ) then
1211
                return 1.0;
1212
        end if;
1213
 
1214
        if ( Y = 0.0 and X /= 0 ) then
1215
                return 1.0;
1216
        end if;
1217
 
1218
        if ( Y = 1.0) then
1219
                return (REAL(X));
1220
        end if;
1221
 
1222
        -- Get value for general case
1223
        return EXP (Y * LOG (REAL(X)));
1224
    end "**";
1225
 
1226
    function "**" (X : in REAL; Y : in REAL) return REAL is
1227
        -- Description:
1228
        --        See function declaration in IEEE Std 1076.2-1996
1229
        -- Notes:
1230
        --        a) Returns 0.0 on error condition
1231
 
1232
    begin
1233
        -- Check validity of argument
1234
        if ( ( X < 0.0  ) and ( Y /= 0.0 ) ) then
1235
                assert FALSE
1236
                        report "X < 0.0 and Y /= 0.0 in X**Y"
1237
                        severity ERROR;
1238
                return 0.0;
1239
        end if;
1240
 
1241
        if ( ( X = 0.0  ) and ( Y <= 0.0 ) ) then
1242
                assert FALSE
1243
                        report "X = 0.0 and Y <= 0.0 in X**Y"
1244
                        severity ERROR;
1245
                return 0.0;
1246
        end if;
1247
 
1248
        -- Get value for special cases
1249
        if ( X = 0.0  and  Y > 0.0 ) then
1250
                return 0.0;
1251
        end if;
1252
 
1253
        if ( X = 1.0 ) then
1254
                return 1.0;
1255
        end if;
1256
 
1257
        if ( Y = 0.0 and X /= 0.0 ) then
1258
                return 1.0;
1259
        end if;
1260
 
1261
        if ( Y = 1.0) then
1262
                return (X);
1263
        end if;
1264
 
1265
        -- Get value for general case
1266
        return EXP (Y * LOG (X));
1267
    end "**";
1268
 
1269
    function EXP  (X : in REAL ) return REAL is
1270
        -- Description:
1271
        --        See function declaration in IEEE Std 1076.2-1996
1272
        -- Notes:
1273
        --        a) This function computes the exponential using the following
1274
        --           series:
1275
        --                exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; |x| < 1.0
1276
        --           and reduces argument X to take advantage of exp(x+y) =
1277
        --           exp(x)*exp(y)
1278
        --
1279
        --        b) This implementation limits X to be less than LOG(REAL'HIGH)
1280
        --           to avoid overflow.  Returns REAL'HIGH when X reaches that
1281
        --           limit
1282
        --
1283
        constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS;-- Precision criteria
1284
 
1285
            variable RECIPROCAL: BOOLEAN := X < 0.0;-- Check sign of argument
1286
            variable XLOCAL : REAL := ABS(X);       -- Use positive value
1287
            variable OLDVAL: REAL ;
1288
            variable COUNT: INTEGER ;
1289
            variable NEWVAL: REAL ;
1290
            variable LAST_TERM: REAL ;
1291
        variable FACTOR : REAL := 1.0;
1292
 
1293
     begin
1294
            -- Compute value for special cases
1295
        if X = 0.0 then
1296
                return 1.0;
1297
        end if;
1298
 
1299
        if  XLOCAL = 1.0  then
1300
                if RECIPROCAL then
1301
                        return MATH_1_OVER_E;
1302
                else
1303
                        return MATH_E;
1304
                end if;
1305
        end if;
1306
 
1307
        if  XLOCAL = 2.0  then
1308
                if RECIPROCAL then
1309
                        return 1.0/MATH_E_P2;
1310
                else
1311
                        return MATH_E_P2;
1312
                end if;
1313
        end if;
1314
 
1315
        if  XLOCAL = 10.0  then
1316
                if RECIPROCAL then
1317
                        return 1.0/MATH_E_P10;
1318
                else
1319
                        return MATH_E_P10;
1320
                end if;
1321
        end if;
1322
 
1323
        if XLOCAL > LOG(REAL'HIGH) then
1324
                if RECIPROCAL then
1325
                        return 0.0;
1326
                else
1327
                        assert FALSE
1328
                                report "X > LOG(REAL'HIGH) in EXP(X)"
1329
                                severity NOTE;
1330
                        return REAL'HIGH;
1331
                end if;
1332
        end if;
1333
 
1334
        -- Reduce argument to ABS(X) < 1.0
1335
        while XLOCAL > 10.0 loop
1336
                XLOCAL := XLOCAL - 10.0;
1337
                FACTOR := FACTOR*MATH_E_P10;
1338
        end loop;
1339
 
1340
        while XLOCAL > 1.0 loop
1341
                XLOCAL := XLOCAL - 1.0;
1342
                FACTOR := FACTOR*MATH_E;
1343
        end loop;
1344
 
1345
        -- Compute value for case 0 < XLOCAL < 1
1346
        OLDVAL := 1.0;
1347
        LAST_TERM := XLOCAL;
1348
        NEWVAL:= OLDVAL + LAST_TERM;
1349
        COUNT := 2;
1350
 
1351
        -- Check for relative and absolute errors and max count
1352
        while ( ( (ABS((NEWVAL - OLDVAL)/NEWVAL) > EPS) OR
1353
                  (ABS(NEWVAL - OLDVAL) > EPS) ) AND
1354
                  (COUNT < MAX_COUNT ) ) loop
1355
                OLDVAL := NEWVAL;
1356
                LAST_TERM := LAST_TERM*(XLOCAL / (REAL(COUNT)));
1357
                NEWVAL := OLDVAL + LAST_TERM;
1358
                COUNT := COUNT + 1;
1359
        end loop;
1360
 
1361
        -- Compute final value using exp(x+y) = exp(x)*exp(y)
1362
        NEWVAL := NEWVAL*FACTOR;
1363
 
1364
        if RECIPROCAL then
1365
                NEWVAL := 1.0/NEWVAL;
1366
        end if;
1367
 
1368
        return NEWVAL;
1369
     end EXP;
1370
 
1371
 
1372
    --
1373
    -- Auxiliary Functions to Compute LOG
1374
    --
1375
    function ILOGB(X: in REAL) return INTEGER IS
1376
        -- Description:
1377
        --        Returns n such that -1 <= ABS(X)/2^n < 2
1378
        -- Notes:
1379
        --        None
1380
 
1381
        variable N: INTEGER := 0;
1382
        variable Y: REAL := ABS(X);
1383
 
1384
    begin
1385
        if(Y = 1.0 or Y = 0.0) then
1386
                return 0;
1387
        end if;
1388
 
1389
        if( Y > 1.0) then
1390
                while Y >= 2.0 loop
1391
                        Y := Y/2.0;
1392
                        N := N+1;
1393
                end loop;
1394
                return N;
1395
        end if;
1396
 
1397
        -- O < Y < 1
1398
        while Y < 1.0 loop
1399
                Y := Y*2.0;
1400
                N := N -1;
1401
        end loop;
1402
        return N;
1403
    end ILOGB;
1404
 
1405
    function LDEXP(X: in REAL; N: in INTEGER) RETURN REAL IS
1406
        -- Description:
1407
        --        Returns X*2^n
1408
        -- Notes:
1409
        --         None
1410
    begin
1411
        return X*(2.0 ** N);
1412
    end LDEXP;
1413
 
1414
    function LOG (X : in REAL ) return REAL IS
1415
        -- Description:
1416
        --        See function declaration in IEEE Std 1076.2-1996
1417
        --
1418
        -- Notes:
1419
        --        a) Returns REAL'LOW on error
1420
        --
1421
        -- Copyright (c) 1992 Regents of the University of California.
1422
        -- All rights reserved.
1423
        --
1424
        -- Redistribution and use in source and binary forms, with or without
1425
        -- modification, are permitted provided that the following conditions
1426
        -- are met:
1427
        -- 1. Redistributions of source code must retain the above copyright
1428
        -- notice, this list of conditions and the following disclaimer.
1429
        -- 2. Redistributions in binary form must reproduce the above copyright
1430
        -- notice, this list of conditions and the following disclaimer in the
1431
        -- documentation and/or other materials provided with the distribution.
1432
        -- 3. All advertising materials mentioning features or use of this
1433
        -- software must display the following acknowledgement:
1434
        -- This product includes software developed by the University of
1435
        -- California, Berkeley and its contributors.
1436
        -- 4. Neither the name of the University nor the names of its
1437
        -- contributors may be used to endorse or promote products derived
1438
        -- from this software without specific prior written permission.
1439
        --
1440
        -- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
1441
        -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1442
        -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
1443
        -- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
1444
        -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1445
        -- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1446
        -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1447
        -- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1448
        -- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1449
        -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1450
        -- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1451
        -- DAMAGE.
1452
        --
1453
        -- NOTE: This VHDL version was generated using the C version of the
1454
        --         original function by the IEEE VHDL Mathematical Package
1455
        --         Working Group (CS/JT)
1456
 
1457
        constant N: INTEGER := 128;
1458
 
1459
        -- Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
1460
        -- Used for generation of extend precision logarithms.
1461
        -- The constant 35184372088832 is 2^45, so the divide is exact.
1462
        -- It ensures correct reading of logF_head, even for inaccurate
1463
        -- decimal-to-binary conversion routines. (Everybody gets the
1464
        -- right answer for INTEGERs less than 2^53.)
1465
        -- Values for LOG(F) were generated using error < 10^-57 absolute
1466
        -- with the bc -l package.
1467
 
1468
        type REAL_VECTOR is array (NATURAL range <>) of REAL;
1469
 
1470
        constant A1:REAL := 0.08333333333333178827;
1471
        constant A2:REAL := 0.01250000000377174923;
1472
        constant A3:REAL := 0.002232139987919447809;
1473
        constant A4:REAL := 0.0004348877777076145742;
1474
 
1475
        constant LOGF_HEAD: REAL_VECTOR(0 TO N) := (
1476
                0.0,
1477
                0.007782140442060381246,
1478
                0.015504186535963526694,
1479
                0.023167059281547608406,
1480
                0.030771658666765233647,
1481
                0.038318864302141264488,
1482
                0.045809536031242714670,
1483
                0.053244514518837604555,
1484
                0.060624621816486978786,
1485
                0.067950661908525944454,
1486
                0.075223421237524235039,
1487
                0.082443669210988446138,
1488
                0.089612158689760690322,
1489
                0.096729626458454731618,
1490
                0.103796793681567578460,
1491
                0.110814366340264314203,
1492
                0.117783035656430001836,
1493
                0.124703478501032805070,
1494
                0.131576357788617315236,
1495
                0.138402322859292326029,
1496
                0.145182009844575077295,
1497
                0.151916042025732167530,
1498
                0.158605030176659056451,
1499
                0.165249572895390883786,
1500
                0.171850256926518341060,
1501
                0.178407657472689606947,
1502
                0.184922338493834104156,
1503
                0.191394852999565046047,
1504
                0.197825743329758552135,
1505
                0.204215541428766300668,
1506
                0.210564769107350002741,
1507
                0.216873938300523150246,
1508
                0.223143551314024080056,
1509
                0.229374101064877322642,
1510
                0.235566071312860003672,
1511
                0.241719936886966024758,
1512
                0.247836163904594286577,
1513
                0.253915209980732470285,
1514
                0.259957524436686071567,
1515
                0.265963548496984003577,
1516
                0.271933715484010463114,
1517
                0.277868451003087102435,
1518
                0.283768173130738432519,
1519
                0.289633292582948342896,
1520
                0.295464212893421063199,
1521
                0.301261330578199704177,
1522
                0.307025035294827830512,
1523
                0.312755710004239517729,
1524
                0.318453731118097493890,
1525
                0.324119468654316733591,
1526
                0.329753286372579168528,
1527
                0.335355541920762334484,
1528
                0.340926586970454081892,
1529
                0.346466767346100823488,
1530
                0.351976423156884266063,
1531
                0.357455888922231679316,
1532
                0.362905493689140712376,
1533
                0.368325561158599157352,
1534
                0.373716409793814818840,
1535
                0.379078352934811846353,
1536
                0.384411698910298582632,
1537
                0.389716751140440464951,
1538
                0.394993808240542421117,
1539
                0.400243164127459749579,
1540
                0.405465108107819105498,
1541
                0.410659924985338875558,
1542
                0.415827895143593195825,
1543
                0.420969294644237379543,
1544
                0.426084395310681429691,
1545
                0.431173464818130014464,
1546
                0.436236766774527495726,
1547
                0.441274560805140936281,
1548
                0.446287102628048160113,
1549
                0.451274644139630254358,
1550
                0.456237433481874177232,
1551
                0.461175715122408291790,
1552
                0.466089729924533457960,
1553
                0.470979715219073113985,
1554
                0.475845904869856894947,
1555
                0.480688529345570714212,
1556
                0.485507815781602403149,
1557
                0.490303988045525329653,
1558
                0.495077266798034543171,
1559
                0.499827869556611403822,
1560
                0.504556010751912253908,
1561
                0.509261901790523552335,
1562
                0.513945751101346104405,
1563
                0.518607764208354637958,
1564
                0.523248143765158602036,
1565
                0.527867089620485785417,
1566
                0.532464798869114019908,
1567
                0.537041465897345915436,
1568
                0.541597282432121573947,
1569
                0.546132437597407260909,
1570
                0.550647117952394182793,
1571
                0.555141507540611200965,
1572
                0.559615787935399566777,
1573
                0.564070138285387656651,
1574
                0.568504735352689749561,
1575
                0.572919753562018740922,
1576
                0.577315365035246941260,
1577
                0.581691739635061821900,
1578
                0.586049045003164792433,
1579
                0.590387446602107957005,
1580
                0.594707107746216934174,
1581
                0.599008189645246602594,
1582
                0.603290851438941899687,
1583
                0.607555250224322662688,
1584
                0.611801541106615331955,
1585
                0.616029877215623855590,
1586
                0.620240409751204424537,
1587
                0.624433288012369303032,
1588
                0.628608659422752680256,
1589
                0.632766669570628437213,
1590
                0.636907462236194987781,
1591
                0.641031179420679109171,
1592
                0.645137961373620782978,
1593
                0.649227946625615004450,
1594
                0.653301272011958644725,
1595
                0.657358072709030238911,
1596
                0.661398482245203922502,
1597
                0.665422632544505177065,
1598
                0.669430653942981734871,
1599
                0.673422675212350441142,
1600
                0.677398823590920073911,
1601
                0.681359224807238206267,
1602
                0.685304003098281100392,
1603
                0.689233281238557538017,
1604
                0.693147180560117703862);
1605
 
1606
        constant LOGF_TAIL: REAL_VECTOR(0 TO N) := (
1607
                0.0,
1608
                -0.00000000000000543229938420049,
1609
                0.00000000000000172745674997061,
1610
                -0.00000000000001323017818229233,
1611
                -0.00000000000001154527628289872,
1612
                -0.00000000000000466529469958300,
1613
                0.00000000000005148849572685810,
1614
                -0.00000000000002532168943117445,
1615
                -0.00000000000005213620639136504,
1616
                -0.00000000000001819506003016881,
1617
                0.00000000000006329065958724544,
1618
                0.00000000000008614512936087814,
1619
                -0.00000000000007355770219435028,
1620
                0.00000000000009638067658552277,
1621
                0.00000000000007598636597194141,
1622
                0.00000000000002579999128306990,
1623
                -0.00000000000004654729747598444,
1624
                -0.00000000000007556920687451336,
1625
                0.00000000000010195735223708472,
1626
                -0.00000000000017319034406422306,
1627
                -0.00000000000007718001336828098,
1628
                0.00000000000010980754099855238,
1629
                -0.00000000000002047235780046195,
1630
                -0.00000000000008372091099235912,
1631
                0.00000000000014088127937111135,
1632
                0.00000000000012869017157588257,
1633
                0.00000000000017788850778198106,
1634
                0.00000000000006440856150696891,
1635
                0.00000000000016132822667240822,
1636
                -0.00000000000007540916511956188,
1637
                -0.00000000000000036507188831790,
1638
                0.00000000000009120937249914984,
1639
                0.00000000000018567570959796010,
1640
                -0.00000000000003149265065191483,
1641
                -0.00000000000009309459495196889,
1642
                0.00000000000017914338601329117,
1643
                -0.00000000000001302979717330866,
1644
                0.00000000000023097385217586939,
1645
                0.00000000000023999540484211737,
1646
                0.00000000000015393776174455408,
1647
                -0.00000000000036870428315837678,
1648
                0.00000000000036920375082080089,
1649
                -0.00000000000009383417223663699,
1650
                0.00000000000009433398189512690,
1651
                0.00000000000041481318704258568,
1652
                -0.00000000000003792316480209314,
1653
                0.00000000000008403156304792424,
1654
                -0.00000000000034262934348285429,
1655
                0.00000000000043712191957429145,
1656
                -0.00000000000010475750058776541,
1657
                -0.00000000000011118671389559323,
1658
                0.00000000000037549577257259853,
1659
                0.00000000000013912841212197565,
1660
                0.00000000000010775743037572640,
1661
                0.00000000000029391859187648000,
1662
                -0.00000000000042790509060060774,
1663
                0.00000000000022774076114039555,
1664
                0.00000000000010849569622967912,
1665
                -0.00000000000023073801945705758,
1666
                0.00000000000015761203773969435,
1667
                0.00000000000003345710269544082,
1668
                -0.00000000000041525158063436123,
1669
                0.00000000000032655698896907146,
1670
                -0.00000000000044704265010452446,
1671
                0.00000000000034527647952039772,
1672
                -0.00000000000007048962392109746,
1673
                0.00000000000011776978751369214,
1674
                -0.00000000000010774341461609578,
1675
                0.00000000000021863343293215910,
1676
                0.00000000000024132639491333131,
1677
                0.00000000000039057462209830700,
1678
                -0.00000000000026570679203560751,
1679
                0.00000000000037135141919592021,
1680
                -0.00000000000017166921336082431,
1681
                -0.00000000000028658285157914353,
1682
                -0.00000000000023812542263446809,
1683
                0.00000000000006576659768580062,
1684
                -0.00000000000028210143846181267,
1685
                0.00000000000010701931762114254,
1686
                0.00000000000018119346366441110,
1687
                0.00000000000009840465278232627,
1688
                -0.00000000000033149150282752542,
1689
                -0.00000000000018302857356041668,
1690
                -0.00000000000016207400156744949,
1691
                0.00000000000048303314949553201,
1692
                -0.00000000000071560553172382115,
1693
                0.00000000000088821239518571855,
1694
                -0.00000000000030900580513238244,
1695
                -0.00000000000061076551972851496,
1696
                0.00000000000035659969663347830,
1697
                0.00000000000035782396591276383,
1698
                -0.00000000000046226087001544578,
1699
                0.00000000000062279762917225156,
1700
                0.00000000000072838947272065741,
1701
                0.00000000000026809646615211673,
1702
                -0.00000000000010960825046059278,
1703
                0.00000000000002311949383800537,
1704
                -0.00000000000058469058005299247,
1705
                -0.00000000000002103748251144494,
1706
                -0.00000000000023323182945587408,
1707
                -0.00000000000042333694288141916,
1708
                -0.00000000000043933937969737844,
1709
                0.00000000000041341647073835565,
1710
                0.00000000000006841763641591466,
1711
                0.00000000000047585534004430641,
1712
                0.00000000000083679678674757695,
1713
                -0.00000000000085763734646658640,
1714
                0.00000000000021913281229340092,
1715
                -0.00000000000062242842536431148,
1716
                -0.00000000000010983594325438430,
1717
                0.00000000000065310431377633651,
1718
                -0.00000000000047580199021710769,
1719
                -0.00000000000037854251265457040,
1720
                0.00000000000040939233218678664,
1721
                0.00000000000087424383914858291,
1722
                0.00000000000025218188456842882,
1723
                -0.00000000000003608131360422557,
1724
                -0.00000000000050518555924280902,
1725
                0.00000000000078699403323355317,
1726
                -0.00000000000067020876961949060,
1727
                0.00000000000016108575753932458,
1728
                0.00000000000058527188436251509,
1729
                -0.00000000000035246757297904791,
1730
                -0.00000000000018372084495629058,
1731
                0.00000000000088606689813494916,
1732
                0.00000000000066486268071468700,
1733
                0.00000000000063831615170646519,
1734
                0.00000000000025144230728376072,
1735
                -0.00000000000017239444525614834);
1736
 
1737
        variable M, J:INTEGER;
1738
        variable F1, F2, G, Q, U, U2, V: REAL;
1739
        variable ZERO: REAL := 0.0;--Made variable so no constant folding occurs
1740
        variable ONE: REAL := 1.0; --Made variable so no constant folding occurs
1741
 
1742
        -- double logb(), ldexp();
1743
 
1744
        variable U1:REAL;
1745
 
1746
     begin
1747
 
1748
        -- Check validity of argument
1749
        if ( X <= 0.0 ) then
1750
                assert FALSE
1751
                        report "X <= 0.0 in LOG(X)"
1752
                        severity ERROR;
1753
                return(REAL'LOW);
1754
        end if;
1755
 
1756
        -- Compute value for special cases
1757
        if ( X = 1.0 ) then
1758
                return 0.0;
1759
        end if;
1760
 
1761
        if ( X = MATH_E ) then
1762
                return 1.0;
1763
        end if;
1764
 
1765
        -- Argument reduction: 1 <= g < 2; x/2^m = g;
1766
        -- y = F*(1 + f/F) for |f| <= 2^-8
1767
 
1768
        M := ILOGB(X);
1769
        G := LDEXP(X, -M);
1770
        J := INTEGER(REAL(N)*(G-1.0)); -- C code adds 0.5 for rounding
1771
        F1 := (1.0/REAL(N)) * REAL(J) + 1.0; --F1*128 is an INTEGER in [128,512]
1772
        F2 := G - F1;
1773
 
1774
        -- Approximate expansion for log(1+f2/F1) ~= u + q
1775
        G := 1.0/(2.0*F1+F2);
1776
        U := 2.0*F2*G;
1777
        V := U*U;
1778
        Q := U*V*(A1 + V*(A2 + V*(A3 + V*A4)));
1779
 
1780
        -- Case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8,
1781
        --       u1 has at most 35 bits, and F1*u1 is exact, as F1 has < 8 bits.
1782
        --       It also adds exactly to |m*log2_hi + log_F_head[j] | < 750.
1783
        --
1784
        if ( J /= 0 or M /= 0) then
1785
                U1 := U + 513.0;
1786
                U1 := U1 - 513.0;
1787
 
1788
                -- Case 2: |1-x| < 1/256. The m- and j- dependent terms are zero
1789
                --        u1 = u to 24 bits.
1790
                --
1791
        else
1792
                U1 := U;
1793
                --TRUNC(U1); --In c this is u1 = (double) (float) (u1)
1794
        end if;
1795
 
1796
        U2 := (2.0*(F2 - F1*U1) - U1*F2) * G;
1797
        -- u1 + u2 = 2f/(2F+f) to extra precision.
1798
 
1799
        -- log(x) = log(2^m*F1*(1+f2/F1)) =
1800
        -- (m*log2_hi+LOGF_HEAD(j)+u1) + (m*log2_lo+LOGF_TAIL(j)+q);
1801
        -- (exact) + (tiny)
1802
 
1803
        U1 := U1 + REAL(M)*LOGF_HEAD(N) + LOGF_HEAD(J);        -- Exact
1804
        U2 := (U2 + LOGF_TAIL(J)) + Q;        -- Tiny
1805
        U2 := U2 + LOGF_TAIL(N)*REAL(M);
1806
        return (U1 + U2);
1807
    end LOG;
1808
 
1809
 
1810
    function LOG2 (X: in REAL) return REAL is
1811
        -- Description:
1812
        --        See function declaration in IEEE Std 1076.2-1996
1813
        -- Notes:
1814
        --        a) Returns REAL'LOW on error
1815
    begin
1816
        -- Check validity of arguments
1817
        if ( X <= 0.0 )  then
1818
                assert FALSE
1819
                        report "X <= 0.0 in LOG2(X)"
1820
                        severity ERROR;
1821
                return(REAL'LOW);
1822
        end if;
1823
 
1824
        -- Compute value for special cases
1825
        if ( X = 1.0 ) then
1826
                return 0.0;
1827
        end if;
1828
 
1829
        if ( X = 2.0 ) then
1830
                return 1.0;
1831
        end if;
1832
 
1833
        -- Compute value for general case
1834
        return ( MATH_LOG2_OF_E*LOG(X) );
1835
    end LOG2;
1836
 
1837
 
1838
    function LOG10 (X: in REAL) return REAL is
1839
        -- Description:
1840
        --        See function declaration in IEEE Std 1076.2-1996
1841
        -- Notes:
1842
        --        a) Returns REAL'LOW on error
1843
    begin
1844
        -- Check validity of arguments
1845
        if ( X <= 0.0 )  then
1846
                   assert FALSE
1847
                        report "X <= 0.0 in LOG10(X)"
1848
                        severity ERROR;
1849
                   return(REAL'LOW);
1850
        end if;
1851
 
1852
        -- Compute value for special cases
1853
        if ( X = 1.0 ) then
1854
                return 0.0;
1855
        end if;
1856
 
1857
        if ( X = 10.0 ) then
1858
                return 1.0;
1859
        end if;
1860
 
1861
        -- Compute value for general case
1862
        return ( MATH_LOG10_OF_E*LOG(X) );
1863
    end LOG10;
1864
 
1865
 
1866
    function LOG (X: in REAL; BASE: in REAL) return REAL is
1867
        -- Description:
1868
        --        See function declaration in IEEE Std 1076.2-1996
1869
        -- Notes:
1870
        --        a) Returns REAL'LOW on error
1871
    begin
1872
        -- Check validity of arguments
1873
        if ( X <= 0.0 )  then
1874
                 assert FALSE
1875
                        report "X <= 0.0 in LOG(X, BASE)"
1876
                        severity ERROR;
1877
                 return(REAL'LOW);
1878
        end if;
1879
 
1880
        if ( BASE <= 0.0 or BASE = 1.0 )  then
1881
                 assert FALSE
1882
                        report "BASE <= 0.0 or BASE = 1.0 in LOG(X, BASE)"
1883
                        severity ERROR;
1884
                 return(REAL'LOW);
1885
        end if;
1886
 
1887
        -- Compute value for special cases
1888
        if ( X = 1.0 ) then
1889
                return 0.0;
1890
        end if;
1891
 
1892
        if ( X = BASE ) then
1893
                return 1.0;
1894
        end if;
1895
 
1896
        -- Compute value for general case
1897
        return ( LOG(X)/LOG(BASE));
1898
    end LOG;
1899
 
1900
 
1901
    function  SIN (X : in REAL ) return REAL is
1902
        -- Description:
1903
        --         See function declaration in IEEE Std 1076.2-1996
1904
        -- Notes:
1905
        --         a) SIN(-X) = -SIN(X)
1906
        --         b) SIN(X) = X if ABS(X) < EPS
1907
        --         c) SIN(X) = X - X**3/3! if EPS < ABS(X) < BASE_EPS
1908
        --         d) SIN(MATH_PI_OVER_2 - X) = COS(X)
1909
        --         e) COS(X) = 1.0 - 0.5*X**2 if ABS(X) < EPS
1910
        --         f) COS(X) = 1.0 - 0.5*X**2 + (X**4)/4! if
1911
        --                                         EPS< ABS(X) <BASE_EPS
1912
 
1913
        constant EPS : REAL := BASE_EPS*BASE_EPS; -- Convergence criteria
1914
 
1915
        variable N : INTEGER;
1916
        variable NEGATIVE : BOOLEAN := X < 0.0;
1917
        variable XLOCAL : REAL := ABS(X) ;
1918
        variable VALUE: REAL;
1919
        variable TEMP : REAL;
1920
 
1921
    begin
1922
        -- Make XLOCAL < MATH_2_PI
1923
        if XLOCAL > MATH_2_PI then
1924
                TEMP := FLOOR(XLOCAL/MATH_2_PI);
1925
                XLOCAL := XLOCAL - TEMP*MATH_2_PI;
1926
        end if;
1927
 
1928
        if XLOCAL < 0.0 then
1929
                assert FALSE
1930
                        report "XLOCAL <= 0.0 after reduction in SIN(X)"
1931
                        severity ERROR;
1932
                XLOCAL := -XLOCAL;
1933
        end if;
1934
 
1935
        -- Compute value for special cases
1936
        if XLOCAL = 0.0  or XLOCAL = MATH_2_PI or XLOCAL = MATH_PI  then
1937
                return 0.0;
1938
        end if;
1939
 
1940
        if  XLOCAL = MATH_PI_OVER_2 then
1941
                if NEGATIVE then
1942
                        return -1.0;
1943
                else
1944
                        return 1.0;
1945
                end if;
1946
        end if;
1947
 
1948
        if  XLOCAL = MATH_3_PI_OVER_2 then
1949
                if NEGATIVE then
1950
                        return 1.0;
1951
                else
1952
                        return -1.0;
1953
                end if;
1954
        end if;
1955
 
1956
        if XLOCAL < EPS then
1957
                if NEGATIVE then
1958
                        return -XLOCAL;
1959
                else
1960
                        return XLOCAL;
1961
                end if;
1962
        else
1963
                if XLOCAL < BASE_EPS then
1964
                        TEMP := XLOCAL - (XLOCAL*XLOCAL*XLOCAL)/6.0;
1965
                        if NEGATIVE then
1966
                                return -TEMP;
1967
                        else
1968
                                return TEMP;
1969
                        end if;
1970
                end if;
1971
        end if;
1972
 
1973
        TEMP := MATH_PI - XLOCAL;
1974
        if ABS(TEMP) < EPS then
1975
                if NEGATIVE then
1976
                        return -TEMP;
1977
                else
1978
                        return TEMP;
1979
                end if;
1980
        else
1981
                if ABS(TEMP) < BASE_EPS then
1982
                        TEMP := TEMP - (TEMP*TEMP*TEMP)/6.0;
1983
                        if NEGATIVE then
1984
                                return -TEMP;
1985
                        else
1986
                                return TEMP;
1987
                        end if;
1988
                end if;
1989
        end if;
1990
 
1991
        TEMP := MATH_2_PI - XLOCAL;
1992
        if ABS(TEMP) < EPS then
1993
                if NEGATIVE then
1994
                        return TEMP;
1995
                else
1996
                        return -TEMP;
1997
                end if;
1998
        else
1999
                if ABS(TEMP) < BASE_EPS then
2000
                        TEMP := TEMP - (TEMP*TEMP*TEMP)/6.0;
2001
                        if NEGATIVE then
2002
                                return TEMP;
2003
                        else
2004
                                return -TEMP;
2005
                        end if;
2006
                end if;
2007
        end if;
2008
 
2009
        TEMP := ABS(MATH_PI_OVER_2 - XLOCAL);
2010
        if TEMP < EPS then
2011
                TEMP := 1.0 - TEMP*TEMP*0.5;
2012
                if NEGATIVE then
2013
                        return -TEMP;
2014
                else
2015
                        return TEMP;
2016
                end if;
2017
        else
2018
                if TEMP < BASE_EPS then
2019
                        TEMP := 1.0 -TEMP*TEMP*0.5 + TEMP*TEMP*TEMP*TEMP/24.0;
2020
                        if NEGATIVE then
2021
                                return -TEMP;
2022
                        else
2023
                                return TEMP;
2024
                        end if;
2025
                end if;
2026
        end if;
2027
 
2028
        TEMP := ABS(MATH_3_PI_OVER_2 - XLOCAL);
2029
        if TEMP < EPS then
2030
                TEMP := 1.0 - TEMP*TEMP*0.5;
2031
                if NEGATIVE then
2032
                        return TEMP;
2033
                else
2034
                        return -TEMP;
2035
                end if;
2036
        else
2037
                if TEMP < BASE_EPS then
2038
                        TEMP := 1.0 -TEMP*TEMP*0.5 + TEMP*TEMP*TEMP*TEMP/24.0;
2039
                        if NEGATIVE then
2040
                                return TEMP;
2041
                        else
2042
                                return -TEMP;
2043
                        end if;
2044
                end if;
2045
        end if;
2046
 
2047
        -- Compute value for general cases
2048
        if ((XLOCAL < MATH_PI_OVER_2 ) and (XLOCAL > 0.0)) then
2049
                 VALUE:=  CORDIC( KC, 0.0, x, 27, ROTATION)(1);
2050
        end if;
2051
 
2052
        N := INTEGER ( FLOOR(XLOCAL/MATH_PI_OVER_2));
2053
        case QUADRANT( N mod 4) is
2054
           when 0 =>
2055
                VALUE := CORDIC( KC, 0.0, XLOCAL, 27, ROTATION)(1);
2056
           when 1 =>
2057
                VALUE := CORDIC( KC, 0.0, XLOCAL - MATH_PI_OVER_2, 27,
2058
                                                                ROTATION)(0);
2059
           when 2 =>
2060
                VALUE := -CORDIC( KC, 0.0, XLOCAL - MATH_PI, 27, ROTATION)(1);
2061
           when 3 =>
2062
                VALUE := -CORDIC( KC, 0.0, XLOCAL - MATH_3_PI_OVER_2, 27,
2063
                                                                ROTATION)(0);
2064
        end case;
2065
 
2066
        if NEGATIVE then
2067
                return -VALUE;
2068
        else
2069
                return VALUE;
2070
        end if;
2071
    end SIN;
2072
 
2073
 
2074
   function COS (X : in REAL) return REAL is
2075
        -- Description:
2076
        --        See function declaration in IEEE Std 1076.2-1996
2077
        -- Notes:
2078
        --        a) COS(-X) = COS(X)
2079
        --        b) COS(X) = SIN(MATH_PI_OVER_2 - X)
2080
        --        c) COS(MATH_PI + X)  = -COS(X)
2081
        --        d) COS(X) = 1.0 - X*X/2.0 if ABS(X) < EPS
2082
        --        e) COS(X) = 1.0 - 0.5*X**2 + (X**4)/4! if
2083
        --                                           EPS< ABS(X) <BASE_EPS
2084
        --
2085
        constant EPS : REAL := BASE_EPS*BASE_EPS;
2086
 
2087
        variable XLOCAL : REAL := ABS(X);
2088
        variable VALUE: REAL;
2089
        variable TEMP : REAL;
2090
 
2091
    begin
2092
        -- Make XLOCAL < MATH_2_PI
2093
        if XLOCAL > MATH_2_PI then
2094
                TEMP := FLOOR(XLOCAL/MATH_2_PI);
2095
                XLOCAL := XLOCAL - TEMP*MATH_2_PI;
2096
        end if;
2097
 
2098
        if XLOCAL < 0.0 then
2099
                assert FALSE
2100
                        report "XLOCAL <= 0.0 after reduction in COS(X)"
2101
                        severity ERROR;
2102
                XLOCAL := -XLOCAL;
2103
        end if;
2104
 
2105
        -- Compute value for special cases
2106
        if XLOCAL = 0.0  or XLOCAL = MATH_2_PI then
2107
                return 1.0;
2108
        end if;
2109
 
2110
        if  XLOCAL = MATH_PI then
2111
                return -1.0;
2112
        end if;
2113
 
2114
        if XLOCAL = MATH_PI_OVER_2 or XLOCAL = MATH_3_PI_OVER_2 then
2115
                return 0.0;
2116
        end if;
2117
 
2118
        TEMP := ABS(XLOCAL);
2119
        if ( TEMP < EPS) then
2120
                return (1.0 - 0.5*TEMP*TEMP);
2121
        else
2122
                if (TEMP < BASE_EPS) then
2123
                        return (1.0 -0.5*TEMP*TEMP + TEMP*TEMP*TEMP*TEMP/24.0);
2124
                end if;
2125
        end if;
2126
 
2127
        TEMP := ABS(XLOCAL -MATH_2_PI);
2128
        if ( TEMP < EPS) then
2129
                return (1.0 - 0.5*TEMP*TEMP);
2130
        else
2131
                if (TEMP < BASE_EPS) then
2132
                        return (1.0 -0.5*TEMP*TEMP + TEMP*TEMP*TEMP*TEMP/24.0);
2133
                end if;
2134
        end if;
2135
 
2136
        TEMP := ABS (XLOCAL - MATH_PI);
2137
        if TEMP < EPS then
2138
                return (-1.0 + 0.5*TEMP*TEMP);
2139
        else
2140
                if (TEMP < BASE_EPS) then
2141
                        return (-1.0 +0.5*TEMP*TEMP - TEMP*TEMP*TEMP*TEMP/24.0);
2142
                end if;
2143
        end if;
2144
 
2145
        -- Compute value for general cases
2146
        return SIN(MATH_PI_OVER_2 - XLOCAL);
2147
   end COS;
2148
 
2149
   function TAN (X : in REAL) return REAL is
2150
        -- Description:
2151
        --        See function declaration in IEEE Std 1076.2-1996
2152
        -- Notes:
2153
        --        a) TAN(0.0) = 0.0
2154
        --        b) TAN(-X) = -TAN(X)
2155
        --        c) Returns REAL'LOW on error if X < 0.0
2156
        --        d) Returns REAL'HIGH on error if X > 0.0
2157
 
2158
        variable NEGATIVE : BOOLEAN := X < 0.0;
2159
        variable XLOCAL : REAL := ABS(X) ;
2160
        variable VALUE: REAL;
2161
        variable TEMP : REAL;
2162
 
2163
    begin
2164
        -- Make 0.0 <= XLOCAL <= MATH_2_PI
2165
        if XLOCAL > MATH_2_PI then
2166
                TEMP := FLOOR(XLOCAL/MATH_2_PI);
2167
                XLOCAL := XLOCAL - TEMP*MATH_2_PI;
2168
        end if;
2169
 
2170
        if XLOCAL < 0.0 then
2171
                assert FALSE
2172
                        report "XLOCAL <= 0.0 after reduction in TAN(X)"
2173
                        severity ERROR;
2174
                XLOCAL := -XLOCAL;
2175
        end if;
2176
 
2177
        -- Check validity of argument
2178
        if XLOCAL = MATH_PI_OVER_2 then
2179
                assert FALSE
2180
                        report "X is a multiple of MATH_PI_OVER_2 in TAN(X)"
2181
                        severity ERROR;
2182
                if NEGATIVE then
2183
                        return(REAL'LOW);
2184
                else
2185
                        return(REAL'HIGH);
2186
                end if;
2187
        end if;
2188
 
2189
        if XLOCAL = MATH_3_PI_OVER_2 then
2190
                assert FALSE
2191
                        report "X is a multiple of MATH_3_PI_OVER_2 in TAN(X)"
2192
                        severity ERROR;
2193
                if NEGATIVE then
2194
                        return(REAL'HIGH);
2195
                else
2196
                        return(REAL'LOW);
2197
                end if;
2198
        end if;
2199
 
2200
        -- Compute value for special cases
2201
        if XLOCAL = 0.0 or XLOCAL = MATH_PI then
2202
                return 0.0;
2203
        end if;
2204
 
2205
        -- Compute value for general cases
2206
        VALUE := SIN(XLOCAL)/COS(XLOCAL);
2207
        if NEGATIVE then
2208
                return -VALUE;
2209
        else
2210
                return VALUE;
2211
        end if;
2212
   end TAN;
2213
 
2214
   function ARCSIN (X : in REAL ) return REAL is
2215
        -- Description:
2216
        --        See function declaration in IEEE Std 1076.2-1996
2217
        -- Notes:
2218
        --        a) ARCSIN(-X) = -ARCSIN(X)
2219
        --        b) Returns X on error
2220
 
2221
        variable NEGATIVE : BOOLEAN := X < 0.0;
2222
        variable XLOCAL : REAL := ABS(X);
2223
        variable VALUE : REAL;
2224
 
2225
   begin
2226
      -- Check validity of arguments
2227
      if XLOCAL > 1.0 then
2228
         assert FALSE
2229
                report "ABS(X) > 1.0 in ARCSIN(X)"
2230
                severity ERROR;
2231
         return X;
2232
      end if;
2233
 
2234
      -- Compute value for special cases
2235
      if XLOCAL = 0.0 then
2236
         return 0.0;
2237
      elsif XLOCAL = 1.0 then
2238
         if NEGATIVE then
2239
                return -MATH_PI_OVER_2;
2240
         else
2241
                return MATH_PI_OVER_2;
2242
         end if;
2243
      end if;
2244
 
2245
      -- Compute value for general cases
2246
      if XLOCAL < 0.9 then
2247
         VALUE := ARCTAN(XLOCAL/(SQRT(1.0 - XLOCAL*XLOCAL)));
2248
      else
2249
         VALUE := MATH_PI_OVER_2 - ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL);
2250
      end if;
2251
 
2252
      if NEGATIVE then
2253
         VALUE := -VALUE;
2254
      end if;
2255
 
2256
      return VALUE;
2257
   end ARCSIN;
2258
 
2259
   function ARCCOS (X : in REAL) return REAL is
2260
        -- Description:
2261
        --        See function declaration in IEEE Std 1076.2-1996
2262
        -- Notes:
2263
        --        a) ARCCOS(-X) = MATH_PI - ARCCOS(X)
2264
        --        b) Returns X on error
2265
 
2266
        variable NEGATIVE : BOOLEAN := X < 0.0;
2267
        variable XLOCAL : REAL := ABS(X);
2268
        variable VALUE : REAL;
2269
 
2270
   begin
2271
      -- Check validity of argument
2272
      if XLOCAL > 1.0 then
2273
         assert FALSE
2274
                report "ABS(X) > 1.0 in ARCCOS(X)"
2275
                severity ERROR;
2276
         return X;
2277
      end if;
2278
 
2279
      -- Compute value for special cases
2280
      if X = 1.0 then
2281
         return 0.0;
2282
      elsif X = 0.0 then
2283
         return MATH_PI_OVER_2;
2284
      elsif X = -1.0 then
2285
         return MATH_PI;
2286
      end if;
2287
 
2288
      -- Compute value for general cases
2289
      if XLOCAL > 0.9 then
2290
         VALUE := ARCTAN(SQRT(1.0 - XLOCAL*XLOCAL)/XLOCAL);
2291
      else
2292
         VALUE := MATH_PI_OVER_2 - ARCTAN(XLOCAL/SQRT(1.0 - XLOCAL*XLOCAL));
2293
      end if;
2294
 
2295
 
2296
      if NEGATIVE then
2297
         VALUE := MATH_PI - VALUE;
2298
      end if;
2299
 
2300
      return VALUE;
2301
   end ARCCOS;
2302
 
2303
 
2304
   function ARCTAN (Y : in REAL) return REAL is
2305
        -- Description:
2306
        --        See function declaration in IEEE Std 1076.2-1996
2307
        -- Notes:
2308
        --        a) ARCTAN(-Y) = -ARCTAN(Y)
2309
        --        b) ARCTAN(Y) = -ARCTAN(1.0/Y) + MATH_PI_OVER_2 for |Y| > 1.0
2310
        --        c) ARCTAN(Y) = Y for |Y| < EPS
2311
 
2312
        constant EPS : REAL := BASE_EPS*BASE_EPS*BASE_EPS;
2313
 
2314
        variable NEGATIVE : BOOLEAN := Y < 0.0;
2315
        variable RECIPROCAL : BOOLEAN;
2316
        variable YLOCAL : REAL := ABS(Y);
2317
        variable VALUE : REAL;
2318
 
2319
   begin
2320
      -- Make argument |Y| <=1.0
2321
      if YLOCAL > 1.0 then
2322
                YLOCAL := 1.0/YLOCAL;
2323
                RECIPROCAL := TRUE;
2324
      else
2325
                RECIPROCAL := FALSE;
2326
      end if;
2327
 
2328
      -- Compute value for special cases
2329
      if YLOCAL = 0.0 then
2330
         if RECIPROCAL then
2331
                if NEGATIVE then
2332
                        return (-MATH_PI_OVER_2);
2333
                else
2334
                        return (MATH_PI_OVER_2);
2335
                end if;
2336
         else
2337
                return 0.0;
2338
         end if;
2339
      end if;
2340
 
2341
      if YLOCAL < EPS then
2342
         if NEGATIVE then
2343
                if RECIPROCAL then
2344
                        return (-MATH_PI_OVER_2 + YLOCAL);
2345
                else
2346
                        return -YLOCAL;
2347
                end if;
2348
         else
2349
                if RECIPROCAL then
2350
                        return (MATH_PI_OVER_2 - YLOCAL);
2351
                else
2352
                        return YLOCAL;
2353
                end if;
2354
         end if;
2355
      end if;
2356
 
2357
      -- Compute value for general cases
2358
      VALUE :=  CORDIC( 1.0, YLOCAL, 0.0, 27, VECTORING )(2);
2359
 
2360
      if RECIPROCAL then
2361
         VALUE := MATH_PI_OVER_2 - VALUE;
2362
      end if;
2363
 
2364
      if NEGATIVE then
2365
        VALUE := -VALUE;
2366
      end if;
2367
 
2368
      return VALUE;
2369
   end ARCTAN;
2370
 
2371
 
2372
   function ARCTAN (Y : in REAL; X : in REAL) return REAL is
2373
        -- Description:
2374
        --        See function declaration in IEEE Std 1076.2-1996
2375
        -- Notes:
2376
        --         a) Returns 0.0 on error
2377
 
2378
        variable YLOCAL : REAL;
2379
        variable VALUE : REAL;
2380
   begin
2381
 
2382
     -- Check validity of arguments
2383
     if (Y = 0.0 and X = 0.0 ) then
2384
           assert FALSE report
2385
                "ARCTAN(0.0, 0.0) is undetermined"
2386
                severity ERROR;
2387
           return 0.0;
2388
     end if;
2389
 
2390
     -- Compute value for special cases
2391
     if Y = 0.0 then
2392
        if X > 0.0 then
2393
           return 0.0;
2394
        else
2395
           return MATH_PI;
2396
        end if;
2397
     end if;
2398
 
2399
     if X = 0.0 then
2400
        if Y > 0.0 then
2401
           return MATH_PI_OVER_2;
2402
        else
2403
           return -MATH_PI_OVER_2;
2404
        end if;
2405
     end if;
2406
 
2407
 
2408
     -- Compute value for general cases
2409
     YLOCAL := ABS(Y/X);
2410
 
2411
     VALUE := ARCTAN(YLOCAL);
2412
 
2413
     if X < 0.0 then
2414
         VALUE := MATH_PI - VALUE;
2415
     end if;
2416
 
2417
     if Y < 0.0 then
2418
         VALUE := -VALUE;
2419
     end if;
2420
 
2421
     return VALUE;
2422
   end ARCTAN;
2423
 
2424
 
2425
    function SINH (X : in REAL) return REAL is
2426
        -- Description:
2427
        --        See function declaration in IEEE Std 1076.2-1996
2428
        -- Notes:
2429
        --        a) Returns (EXP(X) - EXP(-X))/2.0
2430
        --        b) SINH(-X) = SINH(X)
2431
 
2432
        variable NEGATIVE : BOOLEAN := X < 0.0;
2433
        variable XLOCAL : REAL := ABS(X);
2434
        variable TEMP : REAL;
2435
        variable VALUE : REAL;
2436
 
2437
    begin
2438
        -- Compute value for special cases
2439
        if XLOCAL = 0.0 then
2440
                return 0.0;
2441
        end if;
2442
 
2443
        -- Compute value for general cases
2444
        TEMP := EXP(XLOCAL);
2445
        VALUE := (TEMP - 1.0/TEMP)*0.5;
2446
 
2447
         if NEGATIVE then
2448
                VALUE := -VALUE;
2449
        end if;
2450
 
2451
        return VALUE;
2452
    end SINH;
2453
 
2454
    function  COSH (X : in REAL) return REAL is
2455
        -- Description:
2456
        --        See function declaration in IEEE Std 1076.2-1996
2457
        -- Notes:
2458
        --        a) Returns (EXP(X) + EXP(-X))/2.0
2459
        --        b) COSH(-X) = COSH(X)
2460
 
2461
        variable XLOCAL : REAL := ABS(X);
2462
        variable TEMP : REAL;
2463
        variable VALUE : REAL;
2464
    begin
2465
        -- Compute value for special cases
2466
        if XLOCAL = 0.0 then
2467
                return 1.0;
2468
        end if;
2469
 
2470
 
2471
        -- Compute value for general cases
2472
        TEMP := EXP(XLOCAL);
2473
        VALUE := (TEMP + 1.0/TEMP)*0.5;
2474
 
2475
        return VALUE;
2476
    end COSH;
2477
 
2478
    function  TANH (X : in REAL) return REAL is
2479
        -- Description:
2480
        --        See function declaration in IEEE Std 1076.2-1996
2481
        -- Notes:
2482
        --        a) Returns (EXP(X) - EXP(-X))/(EXP(X) + EXP(-X))
2483
        --        b) TANH(-X) = -TANH(X)
2484
 
2485
        variable NEGATIVE : BOOLEAN := X < 0.0;
2486
        variable XLOCAL : REAL := ABS(X);
2487
        variable TEMP : REAL;
2488
        variable VALUE : REAL;
2489
 
2490
    begin
2491
        -- Compute value for special cases
2492
        if XLOCAL = 0.0 then
2493
                return 0.0;
2494
        end if;
2495
 
2496
        -- Compute value for general cases
2497
        TEMP := EXP(XLOCAL);
2498
        VALUE := (TEMP - 1.0/TEMP)/(TEMP + 1.0/TEMP);
2499
 
2500
        if NEGATIVE then
2501
            return -VALUE;
2502
        else
2503
            return VALUE;
2504
        end if;
2505
    end TANH;
2506
 
2507
    function ARCSINH (X : in REAL) return REAL is
2508
        -- Description:
2509
        --        See function declaration in IEEE Std 1076.2-1996
2510
        -- Notes:
2511
        --        a) Returns LOG( X + SQRT( X*X + 1.0))
2512
 
2513
    begin
2514
        -- Compute value for special cases
2515
        if X = 0.0 then
2516
                return 0.0;
2517
        end if;
2518
 
2519
        -- Compute value for general cases
2520
        return ( LOG( X + SQRT( X*X + 1.0)) );
2521
    end ARCSINH;
2522
 
2523
 
2524
 
2525
   function ARCCOSH (X : in REAL) return REAL is
2526
        -- Description:
2527
        --        See function declaration in IEEE Std 1076.2-1996
2528
        -- Notes:
2529
        --        a) Returns LOG( X + SQRT( X*X - 1.0));   X >= 1.0
2530
        --        b) Returns X on error
2531
 
2532
    begin
2533
        -- Check validity of arguments
2534
        if X < 1.0 then
2535
                 assert FALSE
2536
                        report "X < 1.0 in ARCCOSH(X)"
2537
                        severity ERROR;
2538
                 return X;
2539
        end if;
2540
 
2541
        -- Compute value for special cases
2542
        if X = 1.0 then
2543
                return 0.0;
2544
        end if;
2545
 
2546
        -- Compute value for general cases
2547
        return ( LOG( X + SQRT( X*X - 1.0)));
2548
    end ARCCOSH;
2549
 
2550
    function ARCTANH (X : in REAL) return REAL is
2551
        -- Description:
2552
        --        See function declaration in IEEE Std 1076.2-1996
2553
        -- Notes:
2554
        --        a) Returns (LOG( (1.0 + X)/(1.0 - X)))/2.0 ; | X | < 1.0
2555
        --        b) Returns X on error
2556
    begin
2557
        -- Check validity of arguments
2558
        if ABS(X) >= 1.0 then
2559
                assert FALSE
2560
                        report "ABS(X) >= 1.0 in ARCTANH(X)"
2561
                        severity ERROR;
2562
                return X;
2563
        end if;
2564
 
2565
        -- Compute value for special cases
2566
        if X = 0.0 then
2567
                return 0.0;
2568
        end if;
2569
 
2570
        -- Compute value for general cases
2571
        return( 0.5*LOG( (1.0+X)/(1.0-X) ) );
2572
    end ARCTANH;
2573
 
2574
end  MATH_REAL;

powered by: WebSVN 2.1.0

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