Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Industrial programming >> VHDL

Generating Random Numbers in VHDL: From Uniform to OSVVM

VHDL includes a built‑in pseudo‑random generator that yields floating‑point values in the [0, 1] interval. By scaling and offsetting these values, you can create random data of any type—real, integer, std_logic_vector, or time—suitable for testbenches. The following guide shows how to build these generators with the IEEE MATH_REAL uniform procedure and how to leverage the OSVVM Random package for even greater flexibility.

The uniform procedure, defined in the IEEE MATH_REAL package, is the foundation of the examples below:

procedure UNIFORM(variable SEED1, SEED2 : inout POSITIVE;
                  variable X : out REAL);

It requires two seed variables that are updated on every call. The output, X, is a pseudo‑random real number between 0 and 1. Because the algorithm is deterministic, the same initial seed pair will produce the exact same sequence of numbers—an essential property for repeatable testbenches.

For a deeper understanding of the underlying algorithm, refer to Pierre L'Ecuyer’s Efficient and Portable Combined Random Number Generators paper, or inspect the implementation bundled with the GHDL simulator.

The test case

All examples below use 999 as both seed values. Declare the seeds in the process declarative region and implement the randomisation functions as impure functions inside the same process:

variable seed1, seed2 : integer := 999;

You can download a complete testbench containing every example in this article as a ZIP file. The archive also includes a ModelSim project with a script that compiles and runs the simulation.

Random real value

The uniform procedure returns a real number in the [0.0, 1.0] range. To map this to an arbitrary interval [min_val, max_val], multiply by the width and add the offset:

impure function rand_real(min_val, max_val : real) return real is
  variable r : real;
begin
  uniform(seed1, seed2, r);
  return r * (max_val - min_val) + min_val;
end function;

Random integer value

Generating a random integer from a real value is tricky because simple rounding skews the probability of the extreme values. The following function corrects this bias by adding 0.5 before rounding:

Generating Random Numbers in VHDL: From Uniform to OSVVM

impure function rand_int(min_val, max_val : integer) return integer is
  variable r : real;
begin
  uniform(seed1, seed2, r);
  return integer(
    round(r * real(max_val - min_val + 1) + real(min_val) - 0.5));
end function;

The adjustment ensures that every integer in the interval [min_val, max_val] has an equal chance of being selected.

Random std_logic_vector

To fill an arbitrary‑length std_logic_vector with random bits, iterate over each position and assign '1' when the random real exceeds 0.5, otherwise '0':

impure function rand_slv(len : integer) return std_logic_vector is
  variable r : real;
  variable slv : std_logic_vector(len - 1 downto 0);
begin
  for i in slv'range loop
    uniform(seed1, seed2, r);
    slv(i) := '1' when r > 0.5 else '0';
  end loop;
  return slv;
end function;

Random time value

When you need a random time stamp—for example, to simulate bursty data traffic—you can scale a random real to the desired interval and convert back to a VHDL time type:

impure function rand_time(min_val, max_val : time; unit : time := ns)
  return time is
  variable r, r_scaled, min_real, max_real : real;
begin
  uniform(seed1, seed2, r);
  min_real := real(min_val / unit);
  max_real := real(max_val / unit);
  r_scaled := r * (max_real - min_real) + min_real;
  return real(r_scaled) * unit;
end function;

Note that you must supply the simulator’s time unit (e.g., ns) to the function.

The OSVVM Random package

For users who prefer a ready‑made solution, OSVVM’s Random package offers a rich set of overloaded functions that generate random values for all standard VHDL types. Import the package with:

library osvvm;
use osvvm.RandomPkg.all;

ModelSim ships with OSVVM pre‑installed, so no additional download is required on that platform. For other simulators, refer to the OSVVM GitHub repository’s RandomPck.vhd file.

VHDL

  1. Creating String Lists in VHDL: Best Practices & Example
  2. Gracefully Ending a VHDL Testbench Simulation
  3. Using Impure Functions in VHDL: Enhancing FSM Readability and Maintainability
  4. Mastering VHDL Functions: A Practical Guide to Efficient Design
  5. Using Procedures in VHDL: Simplify Your Design with Reusable Code
  6. Build a Reliable Timer in VHDL: Counting Clock Cycles to Hours
  7. Building a Clock‑Triggered Process in VHDL: A Practical Guide
  8. Mastering While Loops in VHDL: Dynamic Iteration Control
  9. Mastering For‑Loops in VHDL: A Practical Guide
  10. Generate Random Numbers in Java: Practical Guide with Random and Math.random