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

Subversion Repositories mdct

[/] [mdct/] [trunk/] [source/] [testbench/] [random1.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 mikel262
-- Random number generators (RNG)
2
-- Author: Gnanasekaran Swaminathan
3
 
4
-- Random number generator algorithm is due to D. E. Knuth as
5
-- given in W. H. Press et al., "Numerical Recipes in C: The Art
6
-- of Scientific Computing," New York: Cambridge Univ. Press, 1988.
7
-- Translated into VHDL by Gnanasekaran Swaminathan <gs4t@virginia.edu>
8
 
9
-- Other algorithms are from libg++ by Dirk Grunwald <grunwald@cs.uiuc.edu>
10
-- Translated into VHDL by Gnanasekaran Swaminathan <gs4t@virginia.edu>
11
 
12
--  math functions factorial, "**", exp, ln, and sqrt are from
13
--  math_functions package due to Tom Ashworth <ashworth@ERC.MsState.Edu>
14
 
15
--  USAGE:
16
--  Following 10 random variables are supported:
17
--      Uniform, Negative Exponential, Poisson, Normal, Log Normal,
18
--      Erlang, Geometric, Hyper Geometric, Binomial, Weibull.
19
--  
20
--  Each random variable has its own copy of random number generator.
21
--  Hence, you can have as many random variables of any type as you
22
--  want only limited by the amount of memory your system has.
23
--  
24
--  First a random variable must be initialized using the corresponding
25
--  Init function. Thenceforth, the new value of the random variable can
26
--  can be obtained by a call to GenRnd.
27
--
28
--  EXAMPLES:
29
--  Uniform random number in [-50, 100] with seed 7
30
--  process
31
--      variable unf:   Uniform := InitUniform(7, -50.0, 100.0);
32
--      variable rnd:   real := 0;
33
--  begin
34
--      GenRnd(unf);
35
--      rnd := unf.rnd;                  -- -50 <= rnd <= 100
36
--  end;
37
--
38
--  Negative exponential distribution with mean 25 and seed 13
39
--   variable nexp: NegExp := InitNegExp(13, 25.0);
40
--   GenRnd(nexp)
41
--   rnd := nexp.rnd;                    --  0 <= rnd <= real'High
42
--
43
--
44
--  Please send bug reports and additions and subtractions
45
--  to me at gs4t@virginia.edu
46
--
47
--  Enjoy!
48
--  Gnanasekaran Swaminathan
49
 
50
package RNG is
51
        subtype rn is Real range 0.0 to 1.0;
52
        subtype PositiveReal is Real range 0.0 to Real'High;
53
        type IntA0to98 is array (0 to 98) of Integer;
54
        type distribution is (  UniformDist,
55
                                NegExpDist,
56
                                PoissonDist,
57
                                BinomialDist,
58
                                GeomDist,
59
                                HypGeomDist,
60
                                NormalDist,
61
                                LogNormalDist,
62
                                ErlangDist,
63
                                WeibullDist
64
                                );
65
        type    realParams      is array (0 to 10) of Real;
66
        subtype intParams       is Integer;
67
        subtype booleanParams   is Boolean;
68
 
69
        type RndNum is
70
        record
71
                rnd             : rn;
72
                init            : Integer;
73
                iy              : Integer;
74
                ir              : IntA0to98;
75
                status          : Boolean;
76
        end record;
77
 
78
        type random is record
79
                rnd:            Real;
80
                r:              RndNum;
81
                a:              realParams;
82
                b:              intParams;
83
                c:              booleanParams;
84
                dist:           distribution;
85
        end record;
86
 
87
        type Uniform is
88
        record
89
                rnd             : Real;
90
                pHigh           : Real;
91
                pLow            : Real;
92
                delta           : Real;
93
                r               : RndNum;
94
        end record;
95
 
96
        type NegExp is
97
        record
98
                rnd             : Real;
99
                pMean           : PositiveReal;
100
                r               : RndNum;
101
        end record;
102
 
103
        type Poisson is
104
        record
105
                rnd             : Real;
106
                pMean           : PositiveReal;
107
                r               : RndNum;
108
        end record;
109
 
110
        type Normal is
111
        record
112
                rnd             : Real;
113
                pMean           : Real;
114
                pStdDev         : Real;
115
                pVariance       : Real;
116
                CachedNormal    : Real;
117
                haveCachedNormal: Boolean;
118
                r               : RndNum;
119
        end record;
120
 
121
        type LogNormal is
122
        record
123
                rnd             : Real;
124
                pLogMean        : Real;
125
                pLogVariance    : Real;
126
                n               : Normal;
127
        end record;
128
 
129
        type Erlang is
130
        record
131
                rnd             : Real;
132
                pMean           : Real;
133
                pVariance       : Real;
134
                a               : Real;
135
                k               : Integer;
136
                r               : RndNum;
137
        end record;
138
 
139
        type Binomial is
140
        record
141
                rnd             : Real;
142
                pU              : Real;
143
                pN              : Integer;
144
                r               : RndNum;
145
        end record;
146
 
147
        type Geom is
148
        record
149
                rnd             : Real;
150
                pMean           : Real;
151
                r               : RndNum;
152
        end record;
153
 
154
        type HypGeom is
155
        record
156
                rnd             : Real;
157
                pMean           : Real;
158
                pVariance       : Real;
159
                pP              : Real;
160
                r               : RndNum;
161
        end record;
162
 
163
        type Weibull is
164
        record
165
                rnd             : Real;
166
                pAlpha          : Real;
167
                pInvAlpha       : Real;
168
                pBeta           : Real;
169
                r               : RndNum;
170
        end record;
171
 
172
        constant LN2: real := 0.693147181;
173
 
174
        function factorial (n: integer) return real;
175
        function "**"(z: Real; y: Real) return Real;
176
        function ln  (z: Real) return Real;
177
        function ln1p(z: Real) return Real;
178
        function exp (z: Real) return Real;
179
        function sqrt(z: Real) return Real;
180
 
181
        procedure GenRnd(r: inout RndNum; seed: in Integer := 13);
182
        procedure GenRnd(r: inout Uniform);
183
        procedure GenRnd(r: inout NegExp);
184
        procedure GenRnd(r: inout Poisson);
185
        procedure GenRnd(r: inout Normal);
186
        procedure GenRnd(r: inout LogNormal);
187
        procedure GenRnd(r: inout Erlang);
188
        procedure GenRnd(r: inout Binomial);
189
        procedure GenRnd(r: inout Geom);
190
        procedure GenRnd(r: inout HypGeom);
191
        procedure GenRnd(r: inout Weibull);
192
        procedure GenRnd(r: inout random);
193
 
194
        --  Initialization functions
195
        function InitRndNum (seed: in Integer := 13) return RndNum;
196
        function InitUniform (seed: Integer := 13;
197
                              low: Real := 0.0;
198
                              high: Real := 100.0) return Uniform;
199
        function InitNegExp (seed: Integer := 13;
200
                             mean: PositiveReal := 50.0) return NegExp;
201
        function InitPoisson (seed: Integer := 13;
202
                              mean: PositiveReal := 50.0) return Poisson;
203
        function InitNormal (seed: Integer := 13;
204
                             mean: Real := 0.0;
205
                             var: Real := 100.0) return Normal;
206
        function InitLogNormal (seed: Integer := 13;
207
                                mean: Real := 50.0;
208
                                var: Real := 100.0) return LogNormal;
209
        function InitErlang (seed: Integer := 13;
210
                             mean: Real := 50.0;
211
                             var: Real := 100.0) return Erlang;
212
        function InitBinomial (seed: Integer := 13;
213
                               n: Integer := 0;
214
                               u: Real := 0.0) return Binomial;
215
        function InitGeom (seed: Integer := 13;
216
                           mean: Real := 0.0) return Geom;
217
        function InitHypGeom (seed: Integer := 13;
218
                              mean: Real := 0.0;
219
                              var:  Real := 0.0) return HypGeom;
220
        function InitWeibull (seed: Integer := 13;
221
                              alpha: Real := 0.0;
222
                              beta:  Real := 0.0) return Weibull;
223
 
224
        function InitUniform (low: Real := 0.0;
225
                              high: Real := 100.0;
226
                              seed: Integer := 13) return random;
227
        function InitNegExp (mean: PositiveReal := 50.0;
228
                             seed: Integer := 13) return random;
229
        function InitPoisson (mean: PositiveReal := 50.0;
230
                              seed: Integer := 13) return random;
231
        function InitNormal (mean: Real := 0.0;
232
                             var: Real := 100.0;
233
                             seed: Integer := 13) return random;
234
        function InitLogNormal (mean: Real := 50.0;
235
                                var: Real := 100.0;
236
                                seed: Integer := 13) return random;
237
        function InitErlang (mean: Real := 50.0;
238
                             var: Real := 100.0;
239
                             seed: Integer := 13) return random;
240
        function InitBinomial (n: Integer := 0;
241
                               u: Real := 0.0;
242
                               seed: Integer := 13) return random;
243
        function InitGeom (mean: Real := 0.0;
244
                           seed: Integer := 13) return random;
245
        function InitHypGeom (mean: Real := 0.0;
246
                              var:  Real := 0.0;
247
                              seed: Integer := 13) return random;
248
        function InitWeibull (alpha: Real := 0.0;
249
                              beta:  Real := 0.0;
250
                              seed: Integer := 13) return random;
251
 
252
        --  conversion functions
253
        function CvtRandom (uni: in Uniform) return random;
254
        function CvtRandom (nex: in NegExp) return random;
255
        function CvtRandom (poi: in Poisson) return random;
256
        function CvtRandom (nom: in Normal) return random;
257
        function CvtRandom (lnom: in LogNormal) return random;
258
        function CvtRandom (erl: in Erlang) return random;
259
        function CvtRandom (bin: in Binomial) return random;
260
        function CvtRandom (geo: in Geom) return random;
261
        function CvtRandom (hypg: in HypGeom) return random;
262
        function CvtRandom (wei: in Weibull) return random;
263
 
264
        function CvtUniform (r: in random) return Uniform;
265
        function CvtNegExp  (r: in random) return NegExp;
266
        function CvtPoisson (r: in random) return Poisson;
267
        function CvtNormal  (r: in random) return Normal;
268
        function CvtLogNormal (r: in random) return LogNormal;
269
        function CvtErlang  (r: in random) return Erlang;
270
        function CvtBinomial (r: in random) return Binomial;
271
        function CvtGeom    (r: in random) return Geom;
272
        function CvtHypGeom (r: in random) return HypGeom;
273
        function CvtWeibull (r: in random) return Weibull;
274
 
275
end RNG;
276
 
277
package body RNG is
278
-------------------------------------------------------------------------------
279
    function factorial(n : integer) return real is
280
        variable result : Integer;
281
    begin
282
        result := 1;
283
        if (n > 1) then
284
            for i in 2 to n loop
285
                result := result * i;
286
            end loop;
287
        end if;
288
        return Real(result);
289
    end factorial;
290
-------------------------------------------------------------------------------
291
        function "**" (z: Real; y: Real) return Real is
292
        begin
293
                return exp(y * ln(z));
294
        end;
295
-------------------------------------------------------------------------------
296
    function ln (z : real) return real is
297
        variable Result : real;
298
        variable tmpx   : real;
299
        variable n      : integer;
300
        variable acc    : integer;
301
    begin
302
        assert not (z <= 0.0)
303
            report "ERROR : Can't take the ln of a negative number"
304
                severity error;
305
 
306
        tmpx := z;
307
        n := 0;
308
        --reduce z to a number less than one in order
309
        --to use a more accurate model that converges
310
        --much faster. This will render the log function
311
        --to ln(z) = ln(tmpx) + n * ln(2) where ln(2) is
312
        --defined as a constant.
313
        while (tmpx >= 1.0) loop
314
            tmpx := tmpx / 2.0;
315
            n    := n +1;
316
        end loop;
317
 
318
        --acc determines the number of iterations of the series
319
        --these values are results from comparisons with the SUN
320
        --log() C function at a accuracy of at least 0.00001.
321
        if (tmpx < 0.5) then
322
            acc := 100;
323
        else
324
            acc := 20;
325
        end if;
326
 
327
        tmpx   := tmpx - 1.0;
328
        result := real(n) * LN2;
329
        n := 1;
330
 
331
        while (n < acc) loop
332
            result := result + (tmpx**n)/real(n) - (tmpx**(n+1))/real(n+1);
333
            n := n +2;
334
        end loop;
335
 
336
        return Result;
337
    end ln;
338
-------------------------------------------------------------------------------
339
        function ln1p(z: Real) return Real is
340
        begin
341
                assert false
342
                        report "ln1p is not implemented"
343
                        severity error;
344
                return ln(z);
345
        end;
346
-------------------------------------------------------------------------------
347
    function exp (z : real) return real is
348
        variable result,tmp : real;
349
        variable i : integer;
350
    begin
351
        if (z = 0.0) then
352
            result := 1.0;
353
        else
354
            result := z + 1.0;
355
            i      := 2;
356
            tmp    := z*z/2.0;
357
            result := result + tmp;
358
 
359
            while (abs(tmp) > 0.000005) loop
360
                i      := i +1;
361
                tmp    := tmp * z / Real(i);
362
                result := result + tmp;
363
            end loop;
364
        end if;
365
        return result;
366
    end exp;
367
-------------------------------------------------------------------------------
368
        function sqrt(z: Real) return Real is
369
        begin
370
                assert z >= 0.0
371
                        report "sqrt (negative number) is undefined"
372
                        severity error;
373
                return z ** 0.5;
374
        end;
375
-------------------------------------------------------------------------------
376
        procedure GenRnd(r: inout RndNum; seed: in Integer := 13) is
377
                constant RN_M : Integer := 714025;
378
                constant RN_IA: Integer := 1366;
379
                constant RN_IC: Integer := 150889;
380
                variable j : Integer := 0;
381
        begin
382
                if (not r.status) then
383
                        r.status := True;
384
                        r.init := seed;
385
                        r.init := abs ( (RN_IC - r.init) mod RN_M );
386
                        for i in 0 to 1 loop for j in 1 to 97 loop
387
                                r.init  := (RN_IA * r.init + RN_IC) mod RN_M;
388
                                r.ir(j) := r.init;
389
                        end loop; end loop;
390
                        r.init := (RN_IA * r.init + RN_IC) mod RN_M;
391
                        r.iy := r.init;
392
                        r.rnd := REAL(r.iy) / REAL(RN_M);
393
                        return;
394
                end if;
395
 
396
                j := 1 + 97 * r.iy / RN_M;
397
                assert (1 <= j and j <= 97)
398
                        report "this cannon happen in GenRnd(RndNum)"
399
                        severity error;
400
                r.iy    := r.ir(j);
401
                r.init  := (RN_IA * r.init + RN_IC) mod RN_M;
402
                r.ir(j) := r.init;
403
                r.rnd := REAL(r.iy) / REAL(RN_M);
404
        end GenRnd; -- RndNum
405
-------------------------------------------------------------------------------
406
        procedure GenRnd(r: inout Uniform) is
407
        begin
408
                assert r.r.status
409
                        report "Uniform variable is not initialized"
410
                        severity error;
411
 
412
                GenRnd(r.r);
413
                r.rnd  := r.pLow + r.delta * r.r.rnd;
414
        end GenRnd; -- Uniform
415
-------------------------------------------------------------------------------
416
        procedure GenRnd(r: inout NegExp) is
417
        begin
418
                assert r.r.status
419
                        report "NegExp variable is not initialized"
420
                        severity error;
421
 
422
                GenRnd(r.r);
423
                r.rnd := - r.pMean * ln(1.0 - r.r.rnd);
424
                                        --  ln1p will be better here
425
        end GenRnd; -- NegExp
426
-------------------------------------------------------------------------------
427
        procedure GenRnd(r: inout Poisson) is
428
                variable product: Real := 1.0;
429
                variable bound: Real := 0.0;
430
        begin
431
                assert r.r.status
432
                        report "Poisson variable is not initialized"
433
                        severity error;
434
 
435
                bound := exp(-1.0 * r.pMean);
436
                r.rnd := -1.0;
437
 
438
                while (product >= bound) loop
439
                        r.rnd := r.rnd + 1.0;
440
                        GenRnd(r.r);
441
                        product := product * r.r.rnd;
442
                end loop;
443
        end GenRnd; -- Poisson
444
-------------------------------------------------------------------------------
445
        procedure GenRnd(r: inout Normal) is
446
                variable v1: Real := 0.0;
447
                variable v2: Real := 0.0;
448
                variable w : Real := 0.0;
449
                variable x1: Real := 0.0;
450
                variable x2: Real := 0.0;
451
        begin
452
                assert r.r.status
453
                        report "Normal variable is not initialized"
454
                        severity error;
455
 
456
                if (r.haveCachedNormal) then
457
                        r.haveCachedNormal := False;
458
                        r.rnd := r.cachedNormal * r.pStdDev + r.pMean;
459
                        return;
460
                end if;
461
 
462
                while (True) loop
463
                        GenRnd(r.r);    v1 := 2.0 * r.r.rnd - 1.0;
464
                        GenRnd(r.r);    v2 := 2.0 * r.r.rnd - 1.0;
465
                        w := v1 * v1 + v2* v2;
466
 
467
                        if ( w <= 1.0 ) then
468
                                w  := sqrt(-2.0 * ln (w) / w);
469
                                x1 := v1 * w;
470
                                x2 := v2 * w;
471
 
472
                                r.haveCachedNormal := True;
473
                                r.CachedNormal     := x2;
474
                                r.rnd := x1 * r.pStdDev + r.pMean;
475
                                return;
476
                        end if;
477
                end loop;
478
        end GenRnd; -- Normal
479
 
480
-------------------------------------------------------------------------------
481
 
482
        procedure GenRnd(r: inout LogNormal) is
483
        begin
484
                assert r.n.r.status
485
                        report "LogNormal variable is not initialized"
486
                        severity error;
487
 
488
                GenRnd(r.n);
489
                r.rnd := exp(r.n.rnd);
490
        end GenRnd; -- LogNormal
491
 
492
-------------------------------------------------------------------------------
493
 
494
        procedure GenRnd(r: inout Erlang) is
495
                variable prod : Real := 1.0;
496
        begin
497
                assert r.r.status
498
                        report "Erlang variable is not initialized"
499
                        severity error;
500
 
501
                for i in 1 to r.k loop
502
                        GenRnd(r.r);
503
                        prod := prod * r.r.rnd;
504
                end loop;
505
                r.rnd := - ln( prod ) / r.a;
506
        end GenRnd; -- Erlang
507
-------------------------------------------------------------------------------
508
        procedure GenRnd(r: inout Binomial) is
509
        begin
510
                assert r.r.status
511
                        report "Binomial variable is not initialized"
512
                        severity error;
513
 
514
                r.rnd := 0.0;
515
                for i in 1 to r.pN loop
516
                        GenRnd(r.r);
517
                        if (r.r.rnd < r.pU) then
518
                                r.rnd := r.rnd + 1.0;
519
                        end if;
520
                end loop;
521
        end GenRnd; -- Binomial
522
 
523
-------------------------------------------------------------------------------
524
 
525
        procedure GenRnd(r: inout Geom) is
526
        begin
527
                assert r.r.status
528
                        report "Geom variable is not initialized"
529
                        severity error;
530
 
531
                r.rnd := 1.0;
532
                GenRnd(r.r);
533
                while (r.r.rnd < r.pMean) loop
534
                        r.rnd := r.rnd + 1.0;
535
                        GenRnd(r.r);
536
                end loop;
537
        end GenRnd; -- Geom
538
 
539
-------------------------------------------------------------------------------
540
 
541
        procedure GenRnd(r: inout HypGeom) is
542
                variable z: Real := 0.0;
543
        begin
544
                assert r.r.status
545
                        report "HypGeom variable is not initialized"
546
                        severity error;
547
 
548
                GenRnd(r.r);
549
                if (r.r.rnd > r.pP) then
550
                        z := 1.0 - r.pP;
551
                else
552
                        z := r.pP;
553
                end if;
554
                GenRnd(r.r);
555
                r.rnd := -r.pMean * ln( r.r.rnd )/ (2.0*z);
556
        end GenRnd; -- HypGeom
557
 
558
-------------------------------------------------------------------------------
559
 
560
        procedure GenRnd(r: inout Weibull) is
561
        begin
562
                assert r.r.status
563
                        report "Weibull variable r is not initialized"
564
                        severity error;
565
 
566
                GenRnd(r.r);
567
                r.rnd := ( -r.pBeta * ln(1.0 - r.r.rnd) ) ** r.pInvAlpha;
568
        end GenRnd; -- Weibull
569
 
570
-------------------------------------------------------------------------------
571
        function InitRndNum (seed: in Integer := 13) return RndNum is
572
                constant RN_M : Integer := 714025;
573
                constant RN_IA: Integer := 1366;
574
                constant RN_IC: Integer := 150889;
575
                variable j : Integer := 0;
576
                variable r : RndNum;
577
        begin
578
                r.status := True;
579
                r.init := seed;
580
                r.init := abs ( (RN_IC - r.init) mod RN_M );
581
                for i in 0 to 1 loop for j in 1 to 97 loop
582
                        r.init  := (RN_IA * r.init + RN_IC) mod RN_M;
583
                        r.ir(j) := r.init;
584
                end loop; end loop;
585
                r.init := (RN_IA * r.init + RN_IC) mod RN_M;
586
                r.iy := r.init;
587
                return r;
588
        end InitRndNum;
589
-------------------------------------------------------------------------------
590
        function InitUniform (seed:     Integer := 13;
591
                              low:      Real := 0.0;
592
                              high:     Real := 100.0) return Uniform is
593
                variable r : Uniform;
594
        begin
595
                r.r.status := False;
596
                if (low < high) then
597
                        r.pLow  := low;
598
                        r.pHigh := high;
599
                else
600
                        r.pLow  := high;
601
                        r.pHigh := low;
602
                end if;
603
                r.delta := high-low;
604
                GenRnd(r.r, seed);
605
                return r;
606
        end InitUniform;
607
-------------------------------------------------------------------------------
608
        function InitNegExp (seed:      Integer := 13;
609
                             mean:      PositiveReal := 50.0) return NegExp is
610
                variable r : NegExp;
611
        begin
612
                r.r.status := False;
613
                r.pMean := mean;
614
                GenRnd(r.r, seed);
615
                return r;
616
        end InitNegExp;
617
-------------------------------------------------------------------------------
618
        function InitPoisson (seed:     Integer := 13;
619
                              mean:     PositiveReal := 50.0) return Poisson is
620
                variable r : Poisson;
621
        begin
622
                r.r.status := False;
623
                r.pMean := mean;
624
                GenRnd(r.r, seed);
625
                return r;
626
        end InitPoisson;
627
-------------------------------------------------------------------------------
628
        function InitNormal (seed:      Integer := 13;
629
                             mean:      Real := 0.0;
630
                             var:       Real := 100.0) return Normal is
631
                variable r : Normal;
632
        begin
633
                r.r.status := False;
634
                r.haveCachedNormal := False;
635
                r.pMean     := mean;
636
                r.pVariance := var;
637
                r.pStdDev   := sqrt(r.pVariance);
638
                GenRnd(r.r, seed);
639
                return r;
640
        end InitNormal;
641
-------------------------------------------------------------------------------
642
        function InitLogNormal (seed:   Integer := 13;
643
                                mean:   Real := 50.0;
644
                                var:    Real := 100.0) return LogNormal is
645
                variable m2: Real := 0.0;
646
                variable mn: Real := 0.0;
647
                variable sd: Real := 0.0;
648
                variable r : LogNormal;
649
        begin
650
                r.n.r.status := False;
651
                r.pLogMean     := mean;
652
                r.pLogVariance := var;
653
                m2 := r.pLogMean * r.pLogMean;
654
                mn := ln( m2 / sqrt(r.pLogVariance + m2) );
655
                sd := sqrt( ln( (r.pLogVariance + m2) / m2 ) );
656
                r.n := InitNormal(seed, mn, sd);
657
                return  r;
658
        end InitLogNormal;
659
-------------------------------------------------------------------------------
660
        function InitErlang (seed:      Integer := 13;
661
                             mean:      Real := 50.0;
662
                             var:       Real := 100.0) return Erlang is
663
                variable r : Erlang;
664
        begin
665
                r.r.status := False;
666
                r.pMean     := mean;
667
                r.pVariance := var;
668
                r.k := Integer(r.pMean*r.pMean/r.pVariance+0.5);
669
                if (r.k <= 0) then
670
                        r.k := 1;
671
                end if;
672
                r.a := Real(r.k) / r.pMean;
673
                GenRnd(r.r, seed);
674
                return  r;
675
        end InitErlang;
676
-------------------------------------------------------------------------------
677
        function InitBinomial (seed:    Integer := 13;
678
                               n:       Integer := 0;
679
                               u:       Real := 0.0) return Binomial is
680
                variable r : Binomial;
681
        begin
682
                r.r.status := False;
683
                r.pN := n;
684
                r.pU := u;
685
                GenRnd(r.r, seed);
686
                return r;
687
        end InitBinomial;
688
-------------------------------------------------------------------------------
689
        function InitGeom (seed:        Integer := 13;
690
                           mean:        Real := 0.0) return Geom is
691
                variable r : Geom;
692
        begin
693
                r.r.status := False;
694
                r.pMean := mean;
695
                GenRnd(r.r, seed);
696
                return r;
697
        end InitGeom;
698
-------------------------------------------------------------------------------
699
        function InitHypGeom (seed:     Integer := 13;
700
                          mean: Real := 0.0;
701
                          var:  Real := 0.0) return HypGeom is
702
                variable z: Real := 0.0;
703
                variable r : HypGeom;
704
        begin
705
                r.r.status := False;
706
                r.pMean     := mean;
707
                r.pVariance := var;
708
                z    := r.pVariance / (r.pMean * r.pMean);
709
                z    := sqrt( (z-1.0) / (z+1.0) );
710
                r.pP := 0.5 * ( 1.0 - z );
711
                GenRnd(r.r, seed);
712
                return r;
713
        end InitHypGeom;
714
-------------------------------------------------------------------------------
715
        function InitWeibull (seed:     Integer := 13;
716
                              alpha:    Real := 0.0;
717
                              beta:     Real := 0.0) return Weibull is
718
                variable r : Weibull;
719
        begin
720
                r.r.status := False;
721
                r.pAlpha    := alpha;
722
                r.pBeta     := beta;
723
                r.pInvAlpha := 1.0 / r.pAlpha;
724
                GenRnd(r.r, seed);
725
                return r;
726
        end InitWeibull;
727
-------------------------------------------------------------------------------
728
        function InitUniform (low: Real := 0.0;
729
                              high: Real := 100.0;
730
                              seed: Integer := 13) return random is
731
        begin
732
           return CvtRandom (InitUniform (seed, low, high));
733
        end InitUniform;
734
-------------------------------------------------------------------------------
735
        function InitNegExp (mean: PositiveReal := 50.0;
736
                             seed: Integer := 13) return random is
737
        begin
738
           return CvtRandom (InitNegExp (seed, mean));
739
        end InitNegExp;
740
-------------------------------------------------------------------------------
741
        function InitPoisson (mean: PositiveReal := 50.0;
742
                              seed: Integer := 13) return random is
743
        begin
744
           return CvtRandom (InitPoisson (seed, mean));
745
        end InitPoisson;
746
-------------------------------------------------------------------------------
747
        function InitNormal (mean: Real := 0.0;
748
                             var:  Real := 100.0;
749
                             seed: Integer := 13) return random is
750
        begin
751
           return CvtRandom (InitNormal (seed, mean, var));
752
        end InitNormal;
753
-------------------------------------------------------------------------------
754
        function InitLogNormal (mean: Real := 50.0;
755
                                var:  Real := 100.0;
756
                                seed: Integer := 13) return random is
757
        begin
758
           return CvtRandom (InitLogNormal (seed, mean, var));
759
        end InitLogNormal;
760
-------------------------------------------------------------------------------
761
        function InitErlang (mean: Real := 50.0;
762
                             var:  Real := 100.0;
763
                             seed: Integer := 13) return random is
764
        begin
765
           return CvtRandom (InitErlang (seed, mean, var));
766
        end InitErlang;
767
-------------------------------------------------------------------------------
768
        function InitBinomial (n: Integer := 0;
769
                               u: Real := 0.0;
770
                               seed: Integer := 13) return random is
771
        begin
772
           return CvtRandom (InitBinomial (seed, n, u));
773
        end InitBinomial;
774
-------------------------------------------------------------------------------
775
        function InitGeom (mean: Real := 0.0;
776
                           seed: Integer := 13) return random is
777
        begin
778
           return CvtRandom (InitGeom (seed, mean));
779
        end InitGeom;
780
-------------------------------------------------------------------------------
781
        function InitHypGeom (mean: Real := 0.0;
782
                              var:  Real := 0.0;
783
                              seed: Integer := 13) return random is
784
        begin
785
           return CvtRandom (InitHypGeom (seed, mean, var));
786
        end InitHypGeom;
787
-------------------------------------------------------------------------------
788
        function InitWeibull (alpha: Real := 0.0;
789
                              beta:  Real := 0.0;
790
                              seed: Integer := 13) return random is
791
        begin
792
           return CvtRandom (InitWeibull (seed, alpha, beta));
793
        end InitWeibull;
794
-------------------------------------------------------------------------------
795
        procedure GenRnd (r: inout random) is
796
                variable unf : Uniform;
797
                variable nex : NegExp;
798
                variable poi : Poisson;
799
                variable nom : Normal;
800
                variable lnom : LogNormal;
801
                variable erl : Erlang;
802
                variable geo : Geom;
803
                variable hypg : HypGeom;
804
                variable bin : Binomial;
805
                variable wei : Weibull;
806
        begin
807
                case r.dist is
808
                        when UniformDist =>
809
                                unf := (r.rnd, r.a(2), r.a(1), r.a(3), r.r);
810
                                GenRnd(unf);
811
                                r.rnd := unf.rnd;
812
                                r.r   := unf.r;
813
                                return;
814
                        when NegExpDist =>
815
                                nex := (r.rnd, PositiveReal'(r.a(1)), r.r);
816
                                GenRnd(nex);
817
                                r.rnd := nex.rnd;
818
                                r.r   := nex.r;
819
                                return;
820
                        when PoissonDist =>
821
                                poi := (r.rnd, PositiveReal'(r.a(1)), r.r);
822
                                GenRnd(poi);
823
                                r.rnd := poi.rnd;
824
                                r.r   := poi.r;
825
                                return;
826
                        when NormalDist =>
827
                                nom := (r.rnd, r.a(1), r.a(3), r.a(2),
828
                                        r.a(4), r.c, r.r);
829
                                GenRnd(nom);
830
                                r.rnd := nom.rnd;
831
                                r.r   := nom.r;
832
                                r.a(4):= nom.CachedNormal;
833
                                r.c   := nom.haveCachedNormal;
834
                                return;
835
                        when LogNormalDist =>
836
                                nom := (r.rnd, r.a(1), r.a(3), r.a(2),
837
                                        r.a(4), r.c, r.r);
838
                                lnom := (r.rnd, r.a(5), r.a(6), nom);
839
                                GenRnd(lnom);
840
                                r.rnd := lnom.rnd;
841
                                r.r   := lnom.n.r;
842
                                r.a(4):= lnom.n.CachedNormal;
843
                                r.c   := lnom.n.haveCachedNormal;
844
                                return;
845
                        when ErlangDist =>
846
                                erl := (r.rnd, r.a(1), r.a(2), r.a(3),
847
                                        r.b, r.r);
848
                                GenRnd(erl);
849
                                r.rnd := erl.rnd;
850
                                r.r   := erl.r;
851
                                return;
852
                        when BinomialDist =>
853
                                bin := (r.rnd, r.a(1), r.b, r.r);
854
                                GenRnd(bin);
855
                                r.rnd := bin.rnd;
856
                                r.r   := bin.r;
857
                                return;
858
                        when GeomDist =>
859
                                geo := (r.rnd, r.a(1), r.r);
860
                                GenRnd(geo);
861
                                r.rnd := geo.rnd;
862
                                r.r   := geo.r;
863
                                return;
864
                        when HypGeomDist =>
865
                                hypg := (r.rnd, r.a(1), r.a(2), r.a(3), r.r);
866
                                GenRnd(hypg);
867
                                r.rnd := hypg.rnd;
868
                                r.r   := hypg.r;
869
                                return;
870
                        when WeibullDist =>
871
                                wei := (r.rnd, r.a(1), r.a(3), r.a(2), r.r);
872
                                GenRnd(wei);
873
                                r.rnd := wei.rnd;
874
                                r.r   := wei.r;
875
                                return;
876
                end case;
877
        end GenRnd;
878
-------------------------------------------------------------------------------
879
        function CvtRandom (uni: in Uniform) return random is
880
                variable r : random;
881
        begin
882
                r.dist  := UniformDist;
883
                r.rnd   := uni.rnd;
884
                r.a(1)  := uni.pLow;
885
                r.a(2)  := uni.pHigh;
886
                r.a(3)  := uni.delta;
887
                r.r     := uni.r;
888
                return r;
889
        end CvtRandom;
890
-------------------------------------------------------------------------------
891
        function CvtRandom (nex: in NegExp) return random is
892
                variable r : random;
893
        begin
894
                r.dist  := NegExpDist;
895
                r.rnd   := nex.rnd;
896
                r.a(1)  := nex.pMean;
897
                r.r     := nex.r;
898
                return r;
899
        end CvtRandom;
900
-------------------------------------------------------------------------------
901
        function CvtRandom (poi: in Poisson) return random is
902
                variable r : random;
903
        begin
904
                r.dist  := PoissonDist;
905
                r.rnd   := poi.rnd;
906
                r.a(1)  := poi.pMean;
907
                r.r     := poi.r;
908
                return r;
909
        end CvtRandom;
910
-------------------------------------------------------------------------------
911
        function CvtRandom (nom: in Normal) return random is
912
                variable r : random;
913
        begin
914
                r.dist  := NormalDist;
915
                r.rnd   := nom.rnd;
916
                r.a(1)  := nom.pMean;
917
                r.a(2)  := nom.pVariance;
918
                r.a(3)  := nom.pStdDev;
919
                r.a(4)  := nom.CachedNormal;
920
                r.c     := nom.haveCachedNormal;
921
                r.r     := nom.r;
922
                return r;
923
        end CvtRandom;
924
-------------------------------------------------------------------------------
925
        function CvtRandom (lnom: in LogNormal) return random is
926
                variable r : random := CvtRandom(lnom.n);
927
        begin
928
                r.dist  := LogNormalDist;
929
                r.a(5)  := lnom.pLogMean;
930
                r.a(6)  := lnom.pLogVariance;
931
                return r;
932
        end CvtRandom;
933
-------------------------------------------------------------------------------
934
        function CvtRandom (erl: in Erlang) return random is
935
                variable r : random;
936
        begin
937
                r.dist  := ErlangDist;
938
                r.rnd   := erl.rnd;
939
                r.a(1)  := erl.pMean;
940
                r.a(2)  := erl.pVariance;
941
                r.a(3)  := erl.a;
942
                r.b     := erl.k;
943
                r.r     := erl.r;
944
                return r;
945
        end CvtRandom;
946
-------------------------------------------------------------------------------
947
        function CvtRandom (bin: in Binomial) return random is
948
                variable r : random;
949
        begin
950
                r.dist  := BinomialDist;
951
                r.rnd   := bin.rnd;
952
                r.a(1)  := bin.pU;
953
                r.b     := bin.pN;
954
                r.r     := bin.r;
955
                return r;
956
        end CvtRandom;
957
-------------------------------------------------------------------------------
958
        function CvtRandom (geo: in Geom) return random is
959
                variable r : random;
960
        begin
961
                r.dist  := GeomDist;
962
                r.a(1)  := geo.pMean;
963
                r.r     := geo.r;
964
                return r;
965
        end CvtRandom;
966
-------------------------------------------------------------------------------
967
        function CvtRandom (hypg: in HypGeom) return random is
968
                variable r : random;
969
        begin
970
                r.dist  := HypGeomDist;
971
                r.a(1)  := hypg.pMean;
972
                r.a(2)  := hypg.pVariance;
973
                r.a(3)  := hypg.pP;
974
                r.r     := hypg.r;
975
                return r;
976
        end CvtRandom;
977
-------------------------------------------------------------------------------
978
        function CvtRandom (wei: in Weibull) return random is
979
                variable r : random;
980
        begin
981
                r.dist  := WeibullDist;
982
                r.a(1)  := wei.pAlpha;
983
                r.a(2)  := wei.pBeta;
984
                r.a(3)  := wei.pInvAlpha;
985
                r.r     := wei.r;
986
                return r;
987
        end CvtRandom;
988
-------------------------------------------------------------------------------
989
        function CvtUniform (r: in random) return Uniform is
990
                variable uni : Uniform := (r.rnd, r.a(2), r.a(1), r.a(3), r.r);
991
        begin
992
                return uni;
993
        end CvtUniform;
994
-------------------------------------------------------------------------------
995
        function CvtNegExp (r: in random) return NegExp is
996
                variable nex : NegExp := (r.rnd, PositiveReal'(r.a(1)), r.r);
997
        begin
998
                return nex;
999
        end CvtNegExp;
1000
-------------------------------------------------------------------------------
1001
        function CvtPoisson (r: in random) return Poisson is
1002
                variable poi : Poisson := (r.rnd, PositiveReal'(r.a(1)), r.r);
1003
        begin
1004
                return poi;
1005
        end CvtPoisson;
1006
-------------------------------------------------------------------------------
1007
        function CvtNormal (r: in random) return Normal is
1008
                variable nom : Normal := (r.rnd, r.a(1), r.a(3),
1009
                                          r.a(2), r.a(4), r.c, r.r);
1010
        begin
1011
                return nom;
1012
        end CvtNormal;
1013
-------------------------------------------------------------------------------
1014
        function CvtLogNormal (r: in random) return LogNormal is
1015
                variable nom : Normal := (r.rnd, r.a(1), r.a(3), r.a(2),
1016
                                          r.a(4), r.c, r.r);
1017
                variable lnom : LogNormal := (r.rnd, r.a(5), r.a(6), nom);
1018
        begin
1019
                return lnom;
1020
        end CvtLogNormal;
1021
-------------------------------------------------------------------------------
1022
        function CvtErlang (r: in random) return Erlang is
1023
                variable erl : Erlang := (r.rnd, r.a(1), r.a(2),
1024
                                          r.a(3), r.b, r.r);
1025
        begin
1026
                return erl;
1027
        end CvtErlang;
1028
-------------------------------------------------------------------------------
1029
        function CvtBinomial (r: in random) return Binomial is
1030
                variable bin : Binomial := (r.rnd, r.a(1), r.b, r.r);
1031
        begin
1032
                return bin;
1033
        end CvtBinomial;
1034
-------------------------------------------------------------------------------
1035
        function CvtGeom (r: in random) return Geom is
1036
                variable geo : Geom := (r.rnd, r.a(1), r.r);
1037
        begin
1038
                return geo;
1039
        end CvtGeom;
1040
-------------------------------------------------------------------------------
1041
        function CvtHypGeom (r: in random) return HypGeom is
1042
                variable hypg : HypGeom := (r.rnd, r.a(1), r.a(2),
1043
                                            r.a(3), r.r);
1044
        begin
1045
                return hypg;
1046
        end CvtHypGeom;
1047
-------------------------------------------------------------------------------
1048
        function CvtWeibull (r: in random) return Weibull is
1049
                variable wei : Weibull := (r.rnd, r.a(1), r.a(3),
1050
                                           r.a(2), r.r);
1051
        begin
1052
               return wei;
1053
        end CvtWeibull;
1054
-------------------------------------------------------------------------------
1055
end RNG;
1056
 

powered by: WebSVN 2.1.0

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