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

Subversion Repositories fixed_extensions

[/] [fixed_extensions/] [trunk/] [sim/] [rtl_sim/] [src/] [math_real.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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