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

Subversion Repositories rng_lib

[/] [rng_lib/] [trunk/] [bench/] [vhdl/] [rng_lib.vhd] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 gedra
----------------------------------------------------------------------
2
----                                                              ----
3
---- Rand number generator library.                               ----
4
----                                                              ----
5
---- This file is part of the Random Number Generator project     ----
6
---- http://www.opencores.org/cores/rng_lib/                      ----
7
----                                                              ----
8
---- Description                                                  ----
9
---- This library has function for generation random numbers with ----
10
---- the following distributions:                                 ----
11
---- - Uniform (continous)                                        ----
12
---- - Exponential (continous)                                    ----
13
---- - Gaussian (continous)                                       ----
14
----                                                              ----
15
---- Random numbers are produced with a combination of 3          ----
16
---- Tausworthe generators which gives very good statistical      ----
17
---- properties.                                                  ----
18
----                                                              ----
19
---- NOTE! These functions will NOT synthesize. They are for test ----
20
----       bench use only!                                        ----
21
----                                                              ----
22
---- To Do:                                                       ----
23
---- -                                                            ----
24
----                                                              ----
25
---- Author(s):                                                   ----
26
---- - Geir Drange, gedra@opencores.org                           ----
27
----                                                              ----
28
----------------------------------------------------------------------
29
----                                                              ----
30
---- Copyright (C) 2004 Authors and OPENCORES.ORG                 ----
31
----                                                              ----
32
---- This source file may be used and distributed without         ----
33
---- restriction provided that this copyright statement is not    ----
34
---- removed from the file and that any derivative work contains  ----
35
---- the original copyright notice and the associated disclaimer. ----
36
----                                                              ----
37
---- This source file is free software; you can redistribute it   ----
38
---- and/or modify it under the terms of the GNU General          ----
39
---- Public License as published by the Free Software Foundation; ----
40
---- either version 2.0 of the License, or (at your option) any   ----
41
---- later version.                                               ----
42
----                                                              ----
43
---- This source is distributed in the hope that it will be       ----
44
---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
45
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
46
---- PURPOSE. See the GNU General Public License for more details.----
47
----                                                              ----
48
---- You should have received a copy of the GNU General           ----
49
---- Public License along with this source; if not, download it   ----
50
---- from http://www.gnu.org/licenses/gpl.txt                     ----
51
----                                                              ----
52
----------------------------------------------------------------------
53
--
54
-- CVS Revision History
55
--
56
-- $Log: not supported by cvs2svn $
57 7 gedra
-- Revision 1.1  2004/09/28 15:12:28  gedra
58
-- Random number library functions.
59 4 gedra
--
60
--
61 7 gedra
--
62
 
63 4 gedra
library ieee;
64
use ieee.std_logic_1164.all;
65
use ieee.numeric_std.all;
66
use std.textio.all;
67
use work.math_lib.all;
68
 
69
package rng_lib is
70
 
71 7 gedra
   type distribution is (UNIFORM, GAUSSIAN, EXPONENTIAL);
72
   type rand_var is record                          -- random variable record
73
      rnd                 : real;                   -- random number
74
      rnd_v               : unsigned(31 downto 0);  -- random number vector
75
      dist                : distribution;           -- distribution type
76
      y, z                : real;                   -- distribution parameters
77
      s1, s2, s3          : unsigned(31 downto 0);  -- seeds
78
      mask1, mask2, mask3 : unsigned(31 downto 0);
79
      shft1, shft2, shft3 : natural;
80
   end record;
81 4 gedra
 
82 7 gedra
   function rand (rnd : rand_var) return rand_var;
83
   function init_uniform(constant a, b, c : natural;
84
                         constant lo, hi  : real) return rand_var;
85
   function init_gaussian(constant a, b, c     : natural;
86
                          constant mean, stdev : real) return rand_var;
87
   function init_exponential(constant a, b, c : natural;
88
                             constant mean    : real) return rand_var;
89
 
90
   constant q1 : natural := 13;
91
   constant q2 : natural := 2;
92
   constant q3 : natural := 3;
93
   constant p1 : natural := 12;
94
   constant p2 : natural := 4;
95
   constant p3 : natural := 17;
96
 
97 4 gedra
end rng_lib;
98
 
99
package body rng_lib is
100
 
101
-- Function to convert 32bit unsigned vector to real
102
-- Integers only go to 2**31 (VHDL'87), so do it clever
103 7 gedra
   function unsigned_2_real (constant a : unsigned(31 downto 0)) return real is
104
      variable r : real;
105
   begin
106
      r := 2.0*real(to_integer(a(31 downto 1)));
107
      if a(0) = '1' then
108
         r := r + 1.0;
109
      end if;
110
      return(r);
111
   end unsigned_2_real;
112
 
113 4 gedra
-- Generate random number using a combination of 3 tausworthe generators 
114
-- Source: Pierre L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
115
-- Generators". Mathematics of Computation, vol.65, no.213(1996), pp203--213.
116 7 gedra
   function rng (rnd : rand_var) return rand_var is
117
      variable new_rnd : rand_var;
118
      variable b       : unsigned(31 downto 0);
119
   begin
120
      new_rnd       := rnd;
121
      b             := ((new_rnd.s1 sll q1) xor new_rnd.s1) srl new_rnd.shft1;
122
      new_rnd.s1    := ((new_rnd.s1 and new_rnd.mask1) sll p1) xor b;
123
      b             := ((new_rnd.s2 sll q2) xor new_rnd.s2) srl new_rnd.shft2;
124
      new_rnd.s2    := ((new_rnd.s2 and new_rnd.mask2) sll p2) xor b;
125
      b             := ((new_rnd.s3 sll q3) xor new_rnd.s3) srl new_rnd.shft3;
126
      new_rnd.s3    := ((new_rnd.s3 and new_rnd.mask3) sll p3) xor b;
127
      new_rnd.rnd_v := new_rnd.s1 xor new_rnd.s2 xor new_rnd.s3;
128
      -- normalize to range [0,1)
129
      new_rnd.rnd   := unsigned_2_real(new_rnd.rnd_v) / 65536.0;
130
      new_rnd.rnd   := new_rnd.rnd / 65536.0;
131
      return (new_rnd);
132
   end rng;
133 4 gedra
 
134
-- rand function generates a random variable with different distributions
135 7 gedra
   function rand (rnd : rand_var) return rand_var is
136
      variable rnd_out : rand_var;
137
      variable x, y, z : real;
138
      variable t       : real := 0.0;
139
   begin
140
      case rnd.dist is
141
         -- Uniform distribution
142
         when UNIFORM =>
143
            rnd_out     := rng(rnd);
144
            rnd_out.rnd := rnd.y + (rnd_out.rnd * (rnd.z - rnd.y));
145
            -- Gaussian distribution
146
         when GAUSSIAN =>               -- Box-Mueller method
147
            z       := 2.0;
148
            rnd_out := rnd;
149
            while z > 1.0 or z = 0.0 loop
150
               -- choose x,y in uniform square (-1,-1) to (+1,+1)
151
               rnd_out := rng(rnd_out);
152
               x       := -1.0 + 2.0 * rnd_out.rnd;
153
               rnd_out := rng(rnd_out);
154
               y       := -1.0 + 2.0 * rnd_out.rnd;
155
               z       := (x * x) + (y * y);
156
            end loop;
157
            -- Box-Mueller transform
158 11 gedra
            rnd_out.rnd := rnd_out.y + rnd_out.z * y * sqrt(-2.0 * ln(z)/z);
159 7 gedra
            -- Exponential distribution
160
         when EXPONENTIAL =>
161
            rnd_out     := rng(rnd);
162
            rnd_out.rnd := -rnd_out.y * log(1.0 - rnd_out.rnd);
163
         when others =>
164
            report "rand() function encountered an error!"
165
               severity failure;
166
      end case;
167
      return (rnd_out);
168
   end rand;
169 4 gedra
 
170
-- Initialize seeds, used by all init_ functions
171 7 gedra
   function gen_seed (constant a, b, c : natural) return rand_var is
172
      variable seeded : rand_var;
173
      variable x      : unsigned(31 downto 0) := "11111111111111111111111111111111";
174
      constant k1     : natural               := 31;
175
      constant k2     : natural               := 29;
176
      constant k3     : natural               := 28;
177
   begin
178
      seeded.shft1 := k1-p1;
179
      seeded.shft2 := k2-p2;
180
      seeded.shft3 := k3-p3;
181
      seeded.mask1 := x sll (32-k1);
182
      seeded.mask2 := x sll (32-k2);
183
      seeded.mask3 := x sll (32-k3);
184
      seeded.s1    := to_unsigned(390451501, 32);
185
      seeded.s2    := to_unsigned(613566701, 32);
186
      seeded.s3    := to_unsigned(858993401, 32);
187
      if to_unsigned(a, 32) > (to_unsigned(1, 32) sll (32-k1)) then
188
         seeded.s1 := to_unsigned(a, 32);
189
      end if;
190
      if to_unsigned(b, 32) > (to_unsigned(1, 32) sll (32-k2)) then
191
         seeded.s2 := to_unsigned(b, 32);
192
      end if;
193
      if to_unsigned(c, 32) > (to_unsigned(1, 32) sll (32-k3)) then
194
         seeded.s3 := to_unsigned(c, 32);
195
      end if;
196
      return(seeded);
197
   end gen_seed;
198
 
199 4 gedra
-- Uniform distribution random variable initialization
200
-- a,b,c are seeds
201
-- lo,hi is the range for the uniform distribution
202 7 gedra
   function init_uniform(constant a, b, c : natural;
203
                         constant lo, hi  : real) return rand_var is
204
      variable rnd, rout : rand_var;
205
   begin
206
      if lo >= hi then
207
         report "Uniform parameter error: 'hi' must be > 'lo'!"
208
            severity failure;
209
      end if;
210
      rnd      := gen_seed(a, b, c);
211
      rnd.dist := UNIFORM;
212
      rnd.y    := lo;
213
      rnd.z    := hi;
214
      rout     := rand(rnd);
215
      return(rout);
216
   end init_uniform;
217 4 gedra
 
218
-- Gaussian distribution random variable initialization
219
-- a,b,c are seeds
220
-- mean,stdev is mean and standard deviation
221 7 gedra
   function init_gaussian(constant a, b, c     : natural;
222
                          constant mean, stdev : real) return rand_var is
223
      variable rnd, rout : rand_var;
224
   begin
225
      if stdev = 0.0 then
226
         report "Gaussian parameter error: 'stdev' must be non-zero!"
227
            severity failure;
228
      end if;
229
      rnd      := gen_seed(a, b, c);
230
      rnd.dist := GAUSSIAN;
231
      rnd.y    := mean;
232
      rnd.z    := stdev;
233
      rout     := rand(rnd);
234
      return(rout);
235
   end init_gaussian;
236 4 gedra
 
237
-- Exponential distribution random variable initialization
238
-- a,b,c are seeds
239
-- mean: mean value
240 7 gedra
   function init_exponential(constant a, b, c : natural;
241
                             constant mean    : real) return rand_var is
242
      variable rnd, rout : rand_var;
243
   begin
244
      if mean <= 0.0 then
245
         report "Exponential parameter error: 'mean' must be > 0!"
246
            severity failure;
247
      end if;
248
      rnd      := gen_seed(a, b, c);
249
      rnd.dist := EXPONENTIAL;
250
      rnd.y    := mean;
251
      rout     := rand(rnd);
252
      return(rout);
253
   end init_exponential;
254
 
255 4 gedra
end rng_lib;

powered by: WebSVN 2.1.0

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