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

Subversion Repositories rng_lib

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/trunk/bench/vhdl/math_lib.vhd
44,9 → 44,12
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.1 2004/09/28 15:02:56 gedra
-- Math functions library.
--
--
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
53,177 → 56,177
 
package math_lib is
 
function sqrt(x: real) return real; -- returns square root
function ln(x: real ) return real; -- natural logarithm
function log(x: real) return real; -- base 10 logarithm
function exp(x: real ) return real; -- exponential function
-- Some mathematical constants
constant MATH_E: real := 2.71828_18284_59045_23536;
function sqrt(x : real) return real; -- returns square root
function ln(x : real) return real; -- natural logarithm
function log(x : real) return real; -- base 10 logarithm
function exp(x : real) return real; -- exponential function
 
-- Some mathematical constants
constant MATH_E : real := 2.71828_18284_59045_23536;
end math_lib;
 
package body math_lib is
 
-- Square root calculation
function sqrt (x : real ) return real is
-- returns square root of X; X >= 0
--
-- Computes square root using the Newton-Raphson approximation:
-- F(n+1) = 0.5*[F(n) + x/F(n)];
--
constant inival: real := 1.5;
constant eps : real := 0.000001;
constant relative_err : real := eps*X;
variable oldval : real;
variable newval : real;
function sqrt (x : real) return real is
-- returns square root of X; X >= 0
--
-- Computes square root using the Newton-Raphson approximation:
-- F(n+1) = 0.5*[F(n) + x/F(n)];
--
constant inival : real := 1.5;
constant eps : real := 0.000001;
constant relative_err : real := eps*X;
 
begin
-- check validity of argument
if x < 0.0 then
report "x < 0 in sqrt(x)"
severity failure;
return (0.0);
end if;
-- get the square root for special cases
if x = 0.0 then
return 0.0;
else
if x = 1.0 then
return 1.0; -- return exact value
variable oldval : real;
variable newval : real;
 
begin
-- check validity of argument
if x < 0.0 then
report "x < 0 in sqrt(x)"
severity failure;
return (0.0);
end if;
end if;
-- get the square root for general cases
oldval := inival;
newval := (X/oldval + oldval)/2.0;
while ( abs(newval -oldval) > relative_err ) loop
oldval := newval;
 
-- get the square root for special cases
if x = 0.0 then
return 0.0;
else
if x = 1.0 then
return 1.0; -- return exact value
end if;
end if;
 
-- get the square root for general cases
oldval := inival;
newval := (X/oldval + oldval)/2.0;
end loop;
return newval;
end sqrt;
 
while (abs(newval -oldval) > relative_err) loop
oldval := newval;
newval := (X/oldval + oldval)/2.0;
end loop;
 
return newval;
end sqrt;
 
-- Natural logarithm calculation
function ln (x: real ) return real is
-- returns natural logarithm of X; X > 0
--
-- This function computes the exponential using the following series:
-- log(x) = 2[ (x-1)/(x+1) + (((x-1)/(x+1))**3)/3.0 + ...] ; x > 0
--
constant eps : real := 0.000001; -- precision criteria
function ln (x : real) return real is
-- returns natural logarithm of X; X > 0
--
-- This function computes the exponential using the following series:
-- log(x) = 2[ (x-1)/(x+1) + (((x-1)/(x+1))**3)/3.0 + ...] ; x > 0
--
constant eps : real := 0.000001; -- precision criteria
 
variable xlocal: real ; -- following variables are
variable oldval: real ; -- used to evaluate the series
variable xlocalsqr: real ;
variable factor : real ;
variable count: integer ;
variable newval: real ;
begin
-- check validity of argument
if x <= 0.0 then
report "x <= 0 in ln(x)"
severity failure;
return(real'LOW);
end if;
variable xlocal : real; -- following variables are
variable oldval : real; -- used to evaluate the series
variable xlocalsqr : real;
variable factor : real;
variable count : integer;
variable newval : real;
begin
-- check validity of argument
if x <= 0.0 then
report "x <= 0 in ln(x)"
severity failure;
return(real'low);
end if;
 
-- compute value for special cases
if x = 1.0 then
return 0.0;
else
if x = MATH_E then
return 1.0;
-- compute value for special cases
if x = 1.0 then
return 0.0;
else
if x = MATH_E then
return 1.0;
end if;
end if;
end if;
 
-- compute value for general cases
xlocal := (x - 1.0)/(x + 1.0);
oldval := xlocal;
xlocalsqr := xlocal*xlocal;
factor := xlocal*xlocalsqr;
count := 3;
newval := oldval + (factor/real(count));
while ( abs(newval - oldval) > eps ) loop
oldval := newval;
count := count +2;
factor := factor * xlocalsqr;
newval := oldval + factor/real(count);
end loop;
newval := newval * 2.0;
return newval;
end ln;
-- compute value for general cases
xlocal := (x - 1.0)/(x + 1.0);
oldval := xlocal;
xlocalsqr := xlocal*xlocal;
factor := xlocal*xlocalsqr;
count := 3;
newval := oldval + (factor/real(count));
 
while (abs(newval - oldval) > eps) loop
oldval := newval;
count := count +2;
factor := factor * xlocalsqr;
newval := oldval + factor/real(count);
end loop;
 
newval := newval * 2.0;
return newval;
end ln;
 
-- Base 10 logarithm calculation
function log (x: real) return real is
-- returns logarithm base 10 of x; x > 0
begin
-- check validity of argument
if x <= 0.0 then
assert false report "x <= 0.0 in log(x)"
severity ERROR;
return(real'LOW);
end if;
function log (x : real) return real is
-- returns logarithm base 10 of x; x > 0
begin
-- check validity of argument
if x <= 0.0 then
assert false report "x <= 0.0 in log(x)"
severity error;
return(real'low);
end if;
 
-- compute the value
return (ln(x)/2.30258509299);
end log;
-- compute the value
return (ln(x)/2.30258509299);
end log;
 
-- Calculate e**x
function exp (x: real ) return real is
-- returns e**X; where e = MATH_E
--
-- This function computes the exponential using the following series:
-- exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; x > 0
--
constant eps : real := 0.000001; -- precision criteria
variable reciprocal: boolean := x < 0.0;-- check sign of argument
variable xlocal : real := abs(x); -- use positive value
variable oldval: real ; -- following variables are
variable num: real ; -- used for series evaluation
variable count: integer ;
variable denom: real ;
variable newval: real ;
begin
-- compute value for special cases
if x = 0.0 then
return 1.0;
else
if x = 1.0 then
return MATH_E;
function exp (x : real) return real is
-- returns e**X; where e = MATH_E
--
-- This function computes the exponential using the following series:
-- exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; x > 0
--
constant eps : real := 0.000001; -- precision criteria
 
variable reciprocal : boolean := x < 0.0; -- check sign of argument
variable xlocal : real := abs(x); -- use positive value
variable oldval : real; -- following variables are
variable num : real; -- used for series evaluation
variable count : integer;
variable denom : real;
variable newval : real;
begin
-- compute value for special cases
if x = 0.0 then
return 1.0;
else
if x = 1.0 then
return MATH_E;
end if;
end if;
end if;
 
-- compute value for general cases
oldval := 1.0;
num := xlocal;
count := 1;
denom := 1.0;
newval:= oldval + num/denom;
while ( abs(newval - oldval) > eps ) loop
oldval := newval;
num := num*xlocal;
count := count +1;
denom := denom*(real(count));
-- compute value for general cases
oldval := 1.0;
num := xlocal;
count := 1;
denom := 1.0;
newval := oldval + num/denom;
end loop;
if reciprocal then
newval := 1.0/newval;
end if;
return newval;
end exp;
 
while (abs(newval - oldval) > eps) loop
oldval := newval;
num := num*xlocal;
count := count +1;
denom := denom*(real(count));
newval := oldval + num/denom;
end loop;
 
if reciprocal then
newval := 1.0/newval;
end if;
 
return newval;
end exp;
 
end math_lib;
/trunk/bench/vhdl/tb_rng.vhd
44,9 → 44,12
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.1 2004/09/28 15:12:52 gedra
-- Test bench for random numbers.
--
--
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
53,103 → 56,103
use std.textio.all;
use work.rng_lib.all;
 
entity tb_rng is
entity tb_rng is
 
end tb_rng;
 
architecture behav of tb_rng is
 
constant BIN_COUNT : integer := 15;
constant PLOT_HEIGHT : real := 40.0;
constant RAND_COUNT : integer := 10000;
type rand_array is array (0 to RAND_COUNT - 1) of real; -- array used for plot
type bin_array is array (0 to BIN_COUNT - 1) of integer;
constant BIN_COUNT : integer := 15;
constant PLOT_HEIGHT : real := 40.0;
constant RAND_COUNT : integer := 10000;
 
type rand_array is array (0 to RAND_COUNT - 1) of real; -- array used for plot
type bin_array is array (0 to BIN_COUNT - 1) of integer;
 
-- Plot a distribution of the numbers that are between lo,hi values
impure function plot_dist (numbs: rand_array; lo, hi: real) return integer is
variable bins: bin_array;
variable bin_size, height : real;
variable idx, max: integer;
variable bar : line;
begin
-- reset bins
for i in 0 to BIN_COUNT - 1 loop
bins(i) := 0;
end loop;
-- sort numbers into bins
bin_size := (hi - lo) / real(BIN_COUNT);
for i in 0 to RAND_COUNT - 1 loop
if numbs(i) > lo and numbs(i) < hi then
idx := integer(((numbs(i) - lo) / bin_size) - 0.5);
if idx > BIN_COUNT - 1 then
idx := BIN_COUNT - 1;
elsif idx < 0 then
idx := 0;
end if;
bins(idx) := bins(idx) + 1;
end if;
end loop;
-- find largest bin
max := 0;
for i in 0 to BIN_COUNT - 1 loop
if bins(i) > max then
max := bins(i);
end if;
end loop;
-- plot bins
for i in 0 to BIN_COUNT - 1 loop
height := PLOT_HEIGHT * real(bins(i)) / real(max);
for j in 1 to integer(height) loop
write(bar, string'("*"));
impure function plot_dist (numbs : rand_array; lo, hi : real) return integer is
variable bins : bin_array;
variable bin_size, height : real;
variable idx, max : integer;
variable bar : line;
begin
-- reset bins
for i in 0 to BIN_COUNT - 1 loop
bins(i) := 0;
end loop;
writeline(OUTPUT, bar);
end loop;
return 0;
end plot_dist;
-- sort numbers into bins
bin_size := (hi - lo) / real(BIN_COUNT);
for i in 0 to RAND_COUNT - 1 loop
if numbs(i) > lo and numbs(i) < hi then
idx := integer(((numbs(i) - lo) / bin_size) - 0.5);
if idx > BIN_COUNT - 1 then
idx := BIN_COUNT - 1;
elsif idx < 0 then
idx := 0;
end if;
bins(idx) := bins(idx) + 1;
end if;
end loop;
-- find largest bin
max := 0;
for i in 0 to BIN_COUNT - 1 loop
if bins(i) > max then
max := bins(i);
end if;
end loop;
-- plot bins
for i in 0 to BIN_COUNT - 1 loop
height := PLOT_HEIGHT * real(bins(i)) / real(max);
for j in 1 to integer(height) loop
write(bar, string'("*"));
end loop;
writeline(OUTPUT, bar);
end loop;
return 0;
end plot_dist;
begin
 
p1: process
variable r_uni, r_gauss, r_exp : rand_var;
variable r_poisson : rand_var;
variable txt : line;
variable a: integer;
variable numbs : rand_array;
begin
-- Test the uniform distribution
r_uni := init_uniform(0, 0, 0, 0.0, 10.0); -- range 0 to 10
t1: for i in 0 to RAND_COUNT - 1 loop
r_uni := rand(r_uni);
numbs(i) := r_uni.rnd;
end loop t1;
write(txt, string'("Uniform distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, 0.0, 10.0);
-- Test the gaussian distribution
r_gauss := init_gaussian(0, 0, 0, 0.0, 10.0); -- mean=0, stdev=10
t2: for i in 0 to RAND_COUNT - 1 loop
r_gauss := rand(r_gauss);
numbs(i) := r_gauss.rnd;
end loop t2;
write(txt, string'("Gaussian distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, -20.0, 20.0);
-- Test the exponential distribution
r_exp := init_exponential(0, 0, 0, 10.0); -- mean=10
t3: for i in 0 to RAND_COUNT - 1 loop
r_exp := rand(r_exp);
numbs(i) := r_exp.rnd;
end loop t3;
write(txt, string'("Exponential distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, 0.0, 20.0);
wait for 1 ns;
report "End of simulation! (ignore this failure)"
severity failure;
wait;
end process p1;
p1 : process
variable r_uni, r_gauss, r_exp : rand_var;
variable r_poisson : rand_var;
variable txt : line;
variable a : integer;
variable numbs : rand_array;
begin
-- Test the uniform distribution
r_uni := init_uniform(0, 0, 0, 0.0, 10.0); -- range 0 to 10
t1 : for i in 0 to RAND_COUNT - 1 loop
r_uni := rand(r_uni);
numbs(i) := r_uni.rnd;
end loop t1;
write(txt, string'("Uniform distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, 0.0, 10.0);
-- Test the gaussian distribution
r_gauss := init_gaussian(0, 0, 0, 0.0, 10.0); -- mean=0, stdev=10
t2 : for i in 0 to RAND_COUNT - 1 loop
r_gauss := rand(r_gauss);
numbs(i) := r_gauss.rnd;
end loop t2;
write(txt, string'("Gaussian distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, -20.0, 20.0);
-- Test the exponential distribution
r_exp := init_exponential(0, 0, 0, 10.0); -- mean=10
t3 : for i in 0 to RAND_COUNT - 1 loop
r_exp := rand(r_exp);
numbs(i) := r_exp.rnd;
end loop t3;
write(txt, string'("Exponential distribution:"));
writeline(OUTPUT, txt);
a := plot_dist (numbs, 0.0, 20.0);
 
wait for 1 ns;
 
report "End of simulation! (ignore this failure)"
severity failure;
wait;
end process p1;
end behav;
/trunk/bench/vhdl/rng_lib.vhd
54,9 → 54,12
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.1 2004/09/28 15:12:28 gedra
-- Random number library functions.
--
--
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
65,32 → 68,32
 
package rng_lib is
 
type distribution is (UNIFORM, GAUSSIAN, EXPONENTIAL);
type rand_var is record -- random variable record
rnd: real; -- random number
rnd_v: unsigned(31 downto 0); -- random number vector
dist: distribution; -- distribution type
y, z: real; -- distribution parameters
s1, s2, s3: unsigned(31 downto 0); -- seeds
mask1, mask2, mask3: unsigned(31 downto 0);
shft1, shft2, shft3: natural;
end record;
function rand (rnd: rand_var) return rand_var;
function init_uniform(constant a, b, c: natural;
constant lo, hi: real) return rand_var;
function init_gaussian(constant a, b, c: natural;
constant mean, stdev: real) return rand_var;
function init_exponential(constant a, b, c: natural;
constant mean: real) return rand_var;
type distribution is (UNIFORM, GAUSSIAN, EXPONENTIAL);
type rand_var is record -- random variable record
rnd : real; -- random number
rnd_v : unsigned(31 downto 0); -- random number vector
dist : distribution; -- distribution type
y, z : real; -- distribution parameters
s1, s2, s3 : unsigned(31 downto 0); -- seeds
mask1, mask2, mask3 : unsigned(31 downto 0);
shft1, shft2, shft3 : natural;
end record;
 
constant q1: natural:=13;
constant q2: natural:=2;
constant q3: natural:=3;
constant p1: natural:=12;
constant p2: natural:=4;
constant p3: natural:=17;
function rand (rnd : rand_var) return rand_var;
function init_uniform(constant a, b, c : natural;
constant lo, hi : real) return rand_var;
function init_gaussian(constant a, b, c : natural;
constant mean, stdev : real) return rand_var;
function init_exponential(constant a, b, c : natural;
constant mean : real) return rand_var;
 
constant q1 : natural := 13;
constant q2 : natural := 2;
constant q3 : natural := 3;
constant p1 : natural := 12;
constant p2 : natural := 4;
constant p3 : natural := 17;
end rng_lib;
 
package body rng_lib is
97,156 → 100,156
 
-- Function to convert 32bit unsigned vector to real
-- Integers only go to 2**31 (VHDL'87), so do it clever
function unsigned_2_real (constant a: unsigned(31 downto 0)) return real is
variable r: real;
begin
r := 2.0*real(to_integer(a(31 downto 1)));
if a(0) = '1' then
r := r + 1.0;
end if;
return(r);
end unsigned_2_real;
function unsigned_2_real (constant a : unsigned(31 downto 0)) return real is
variable r : real;
begin
r := 2.0*real(to_integer(a(31 downto 1)));
if a(0) = '1' then
r := r + 1.0;
end if;
return(r);
end unsigned_2_real;
 
-- Generate random number using a combination of 3 tausworthe generators
-- Source: Pierre L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
-- Generators". Mathematics of Computation, vol.65, no.213(1996), pp203--213.
function rng (rnd: rand_var) return rand_var is
variable new_rnd : rand_var;
variable b : unsigned(31 downto 0);
begin
new_rnd :=rnd;
b := ((new_rnd.s1 sll q1) xor new_rnd.s1) srl new_rnd.shft1;
new_rnd.s1 := ((new_rnd.s1 and new_rnd.mask1) sll p1) xor b;
b := ((new_rnd.s2 sll q2) xor new_rnd.s2) srl new_rnd.shft2;
new_rnd.s2 := ((new_rnd.s2 and new_rnd.mask2) sll p2) xor b;
b := ((new_rnd.s3 sll q3) xor new_rnd.s3) srl new_rnd.shft3;
new_rnd.s3 := ((new_rnd.s3 and new_rnd.mask3) sll p3) xor b;
new_rnd.rnd_v := new_rnd.s1 xor new_rnd.s2 xor new_rnd.s3;
-- normalize to range [0,1)
new_rnd.rnd := unsigned_2_real(new_rnd.rnd_v) / 65536.0;
new_rnd.rnd := new_rnd.rnd / 65536.0;
return (new_rnd);
end rng;
function rng (rnd : rand_var) return rand_var is
variable new_rnd : rand_var;
variable b : unsigned(31 downto 0);
begin
new_rnd := rnd;
b := ((new_rnd.s1 sll q1) xor new_rnd.s1) srl new_rnd.shft1;
new_rnd.s1 := ((new_rnd.s1 and new_rnd.mask1) sll p1) xor b;
b := ((new_rnd.s2 sll q2) xor new_rnd.s2) srl new_rnd.shft2;
new_rnd.s2 := ((new_rnd.s2 and new_rnd.mask2) sll p2) xor b;
b := ((new_rnd.s3 sll q3) xor new_rnd.s3) srl new_rnd.shft3;
new_rnd.s3 := ((new_rnd.s3 and new_rnd.mask3) sll p3) xor b;
new_rnd.rnd_v := new_rnd.s1 xor new_rnd.s2 xor new_rnd.s3;
-- normalize to range [0,1)
new_rnd.rnd := unsigned_2_real(new_rnd.rnd_v) / 65536.0;
new_rnd.rnd := new_rnd.rnd / 65536.0;
return (new_rnd);
end rng;
 
-- rand function generates a random variable with different distributions
function rand (rnd: rand_var) return rand_var is
variable rnd_out : rand_var;
variable x,y,z : real;
variable t: real := 0.0;
begin
case rnd.dist is
-- Uniform distribution
when UNIFORM =>
rnd_out := rng(rnd);
rnd_out.rnd := rnd.y + (rnd_out.rnd * (rnd.z - rnd.y));
-- Gaussian distribution
when GAUSSIAN => -- Box-Mueller method
z := 2.0;
rnd_out := rnd;
while z > 1.0 or z = 0.0 loop
-- choose x,y in uniform square (-1,-1) to (+1,+1)
rnd_out := rng(rnd_out);
x := -1.0 + 2.0 * rnd_out.rnd;
rnd_out := rng(rnd_out);
y := -1.0 + 2.0 * rnd_out.rnd;
z := (x * x) + (y * y);
end loop;
-- Box-Mueller transform
rnd_out.rnd := rnd_out.y + rnd_out.z * y * sqrt(-2.0 * log(z)/z);
-- Exponential distribution
when EXPONENTIAL =>
rnd_out := rng(rnd);
rnd_out.rnd := -rnd_out.y * log(1.0 - rnd_out.rnd);
when others =>
report "rand() function encountered an error!"
severity failure;
end case;
return (rnd_out);
end rand;
function rand (rnd : rand_var) return rand_var is
variable rnd_out : rand_var;
variable x, y, z : real;
variable t : real := 0.0;
begin
case rnd.dist is
-- Uniform distribution
when UNIFORM =>
rnd_out := rng(rnd);
rnd_out.rnd := rnd.y + (rnd_out.rnd * (rnd.z - rnd.y));
-- Gaussian distribution
when GAUSSIAN => -- Box-Mueller method
z := 2.0;
rnd_out := rnd;
while z > 1.0 or z = 0.0 loop
-- choose x,y in uniform square (-1,-1) to (+1,+1)
rnd_out := rng(rnd_out);
x := -1.0 + 2.0 * rnd_out.rnd;
rnd_out := rng(rnd_out);
y := -1.0 + 2.0 * rnd_out.rnd;
z := (x * x) + (y * y);
end loop;
-- Box-Mueller transform
rnd_out.rnd := rnd_out.y + rnd_out.z * y * sqrt(-2.0 * log(z)/z);
-- Exponential distribution
when EXPONENTIAL =>
rnd_out := rng(rnd);
rnd_out.rnd := -rnd_out.y * log(1.0 - rnd_out.rnd);
when others =>
report "rand() function encountered an error!"
severity failure;
end case;
return (rnd_out);
end rand;
 
-- Initialize seeds, used by all init_ functions
function gen_seed (constant a, b, c: natural) return rand_var is
variable seeded : rand_var;
variable x : unsigned(31 downto 0):= "11111111111111111111111111111111";
constant k1: natural:=31;
constant k2: natural:=29;
constant k3: natural:=28;
begin
seeded.shft1 := k1-p1;
seeded.shft2 := k2-p2;
seeded.shft3 := k3-p3;
seeded.mask1 := x sll (32-k1);
seeded.mask2 := x sll (32-k2);
seeded.mask3 := x sll (32-k3);
seeded.s1 := to_unsigned(390451501, 32);
seeded.s2 := to_unsigned(613566701, 32);
seeded.s3 := to_unsigned(858993401, 32);
if to_unsigned(a, 32) > (to_unsigned(1,32) sll (32-k1)) then
seeded.s1 := to_unsigned(a, 32);
end if;
if to_unsigned(b, 32) > (to_unsigned(1,32) sll (32-k2)) then
seeded.s2 := to_unsigned(b, 32);
end if;
if to_unsigned(c, 32) > (to_unsigned(1,32) sll (32-k3)) then
seeded.s3 := to_unsigned(c, 32);
end if;
return(seeded);
end gen_seed;
function gen_seed (constant a, b, c : natural) return rand_var is
variable seeded : rand_var;
variable x : unsigned(31 downto 0) := "11111111111111111111111111111111";
constant k1 : natural := 31;
constant k2 : natural := 29;
constant k3 : natural := 28;
begin
seeded.shft1 := k1-p1;
seeded.shft2 := k2-p2;
seeded.shft3 := k3-p3;
seeded.mask1 := x sll (32-k1);
seeded.mask2 := x sll (32-k2);
seeded.mask3 := x sll (32-k3);
seeded.s1 := to_unsigned(390451501, 32);
seeded.s2 := to_unsigned(613566701, 32);
seeded.s3 := to_unsigned(858993401, 32);
if to_unsigned(a, 32) > (to_unsigned(1, 32) sll (32-k1)) then
seeded.s1 := to_unsigned(a, 32);
end if;
if to_unsigned(b, 32) > (to_unsigned(1, 32) sll (32-k2)) then
seeded.s2 := to_unsigned(b, 32);
end if;
if to_unsigned(c, 32) > (to_unsigned(1, 32) sll (32-k3)) then
seeded.s3 := to_unsigned(c, 32);
end if;
return(seeded);
end gen_seed;
 
-- Uniform distribution random variable initialization
-- a,b,c are seeds
-- lo,hi is the range for the uniform distribution
function init_uniform(constant a, b, c: natural;
constant lo, hi: real) return rand_var is
variable rnd, rout : rand_var;
begin
if lo >= hi then
report "Uniform parameter error: 'hi' must be > 'lo'!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := UNIFORM;
rnd.y := lo;
rnd.z := hi;
rout := rand(rnd);
return(rout);
end init_uniform;
function init_uniform(constant a, b, c : natural;
constant lo, hi : real) return rand_var is
variable rnd, rout : rand_var;
begin
if lo >= hi then
report "Uniform parameter error: 'hi' must be > 'lo'!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := UNIFORM;
rnd.y := lo;
rnd.z := hi;
rout := rand(rnd);
return(rout);
end init_uniform;
 
-- Gaussian distribution random variable initialization
-- a,b,c are seeds
-- mean,stdev is mean and standard deviation
function init_gaussian(constant a, b, c: natural;
constant mean, stdev: real) return rand_var is
variable rnd, rout : rand_var;
begin
if stdev = 0.0 then
report "Gaussian parameter error: 'stdev' must be non-zero!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := GAUSSIAN;
rnd.y := mean;
rnd.z := stdev;
rout := rand(rnd);
return(rout);
end init_gaussian;
function init_gaussian(constant a, b, c : natural;
constant mean, stdev : real) return rand_var is
variable rnd, rout : rand_var;
begin
if stdev = 0.0 then
report "Gaussian parameter error: 'stdev' must be non-zero!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := GAUSSIAN;
rnd.y := mean;
rnd.z := stdev;
rout := rand(rnd);
return(rout);
end init_gaussian;
 
-- Exponential distribution random variable initialization
-- a,b,c are seeds
-- mean: mean value
function init_exponential(constant a, b, c: natural;
constant mean: real) return rand_var is
variable rnd, rout : rand_var;
begin
if mean <= 0.0 then
report "Exponential parameter error: 'mean' must be > 0!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := EXPONENTIAL;
rnd.y := mean;
rout := rand(rnd);
return(rout);
end init_exponential;
function init_exponential(constant a, b, c : natural;
constant mean : real) return rand_var is
variable rnd, rout : rand_var;
begin
if mean <= 0.0 then
report "Exponential parameter error: 'mean' must be > 0!"
severity failure;
end if;
rnd := gen_seed(a, b, c);
rnd.dist := EXPONENTIAL;
rnd.y := mean;
rout := rand(rnd);
return(rout);
end init_exponential;
end rng_lib;

powered by: WebSVN 2.1.0

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