hi,
there is a function in the IEEE.MATH_REAL named uniform that generate uniform distributed random values from 0.0 to 1.0. you can use it.
if you want to make anyother distributions like gaussian, you will have to use an algorithm that convert uniform to the other distribution.
I have implemented the gaussian distribution in VHDL-AMS code.
here it is:
Code:---------------------------------------------------------
-- Implementing a gaussian random number generator.
--
-- procedure gaussian_pos(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL;variable X:out REAL)
-- procedure gaussian(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL;variable X:out REAL)
-- Purpose:
-- - For gaussian_pos:
-- Returns, in X, a pseudo-random number with gaussian
-- distribution in the open interval (mu , 4*sigma+mu).
-- - For gaussian:
-- Returns, in X, a pseudo-random number with gaussian
-- distribution in the open interval (-4*sigma+mu , 4*sigma+mu).
-- Special values:
-- None
-- Domain:
-- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398;sigma > 0.0
-- Error conditions:
-- Error if SEED1 or SEED2 outside of valid domain, and sigma < 0.0
-- Range of Output:
-- - For gaussian_pos:
-- mu < X < 4.0 * sigma + mu
-- - For gaussian_pos:
-- mu - 4.0 * sigma < X < 4.0 * sigma + mu
-- Notes:
-- a) The semantics for this function are described by the
-- algorithm published by Richard Saucier in "Computer Generation
-- of Statistical Distributions,",From the Army Research Laboratory
-- The algorithm is based on using 2 uniformly distributed
-- random numbers and looping on them to generate another
-- random number with gaussian dsistribution.
--
-- b) Before the first call to gaussian, the seed values
-- (SEED1, SEED2) have to be initialized to values in the range
-- [1, 2147483562] and [1, 2147483398] respectively. The
-- seed values are modified after each call to gaussian inside the
-- uniform function call.
--
-- c) gaussian_pos doubles the probablity of the postive part of the
-- gaussian distribution curve, because it takes the samples of
-- negative side and move it to the positive side.
--
----------------------------------------------------------
----------------------------------------------------------------
-- Declaring Package
----------------------------------------------------------------
package Maths is
procedure gaussian_pos(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL; variable X:out REAL);
procedure gaussian(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL; variable X:out REAL);
end package Maths;
-- Library used
library IEEE;
use IEEE.MATH_REAL.all;
----------------------------------------------------------------------------
-- Implementation
----------------------------------------------------------------------------
package body Maths is
----------------------------------------------------------------------------
-- Implementing gaussian_pos
----------------------------------------------------------------------------
procedure gaussian_pos(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL; variable X:out REAL) is
-- Variables needed for calculations
variable x1:REAL:= 0.0;
variable x2:REAL:= 0.0;
variable temp:REAL:= 2.0;
variable tempdiv:REAL:= 0.0;
constant max_div:REAL:= 4.0 * sigma;
begin
-- loop untill we get
while temp > 1.0 loop
-- Generating 2 unifrom random variables
uniform(SEED1,SEED2,x1);
uniform(SEED1,SEED2,X2);
-- temp = x1^2+ x2^2
temp := x1 * x1 + x2 * x2;
end loop;
-- Calculating output
tempdiv := sigma * x1 * sqrt(-2.0 * log(temp)/temp);
-- checking that value in the range of output and moving negative
-- side to positive side.
if ((tempdiv > max_div) or (tempdiv < -max_div)) then
X := mu + max_div;
elsif ((tempdiv < 0.0) and (tempdiv > -max_div)) then
X := mu - tempdiv;
else
X := mu + tempdiv;
end if;
end procedure gaussian_pos;
----------------------------------------------------------------------------
-- Implementing gaussian
----------------------------------------------------------------------------
procedure gaussian(variable SEED1,SEED2:inout POSITIVE;variable mu,sigma:in REAL; variable X:out REAL) is
-- Variables needed for calculations
variable x1:REAL:= 0.0;
variable x2:REAL:= 0.0;
variable temp:REAL:= 2.0;
constant max_div:REAL:= 4.0 * sigma;
variable tempdiv:REAL:= 0.0;
begin
-- loop untill we get
while temp > 1.0 loop
-- Generating 2 unifrom random variables
uniform(SEED1,SEED2,x1);
uniform(SEED1,SEED2,X2);
-- temp = x1^2+ x2^2
temp := x1 * x1 + x2 * x2;
end loop;
-- Calculating output
tempdiv := sigma * x1 * sqrt(-2.0 * log(temp)/temp);
-- checking that value in the range of output
if (tempdiv > max_div) then
X := mu + max_div;
elsif (tempdiv < - max_div) then
X := mu - max_div;
else
X := mu + tempdiv;
end if;
end procedure gaussian;
end package body Maths;
Thank you,
Amrsfmt