Generating Random Data with the OSVVM Randomization Library

In this tutorial, we will discuss the most useful randomization functions supported by the OSVVM library.

One way to improve the quality of our verification is to add randomness to stimulus generation. Randomized stimuli can help us reach corner cases that would have been difficult to imagine with directed testing. And even when we can plan specific testing scenarios, randomizing the DUT inputs can help us exercise them more quickly, making the overall verification process more efficient.

Even though VHDL natively supports randomization, verification libraries such as the Open-Source VHDL Verification Methodology (OSVVM) and the Universal VHDL Verification Methodology (UVVM) offer more advanced capabilities for generating random stimulus.

In this tutorial, we will discuss the most useful randomization functions supported by the OSVVM library. We will go over code samples and discuss the simulation outputs. The testbench source file and simulation script are available for download.

Prerequisites

This tutorial assumes that a VHDL simulator is available and that the OSVVM libraries have been compiled and are ready to use. We'll use GHDL as our simulator; the OSVVM has been compiled following the process described in a previous tutorial.

Initializing the Randomization Seed

We start by declaring a variable of type RandomPType, which encapsulates the seed and randomization methods. We also declare the integer_array variable, which we'll use later to store the results of the vector randomization function calls.

  osvvm_random_test : process
    variable random_variable : RandomPType;
    variable integer_array   : integer_vector(0 to 9);
  begin
  ...
  end process osvvm_random_test;

Inside the osvvm_random_test process, we initialize the seed so that each process generates unique random values. This is only needed if the randomization functions are called from more than one process, but it is good practice to do it regardless.

random_variable.InitSeed(random_variable'instance_name); 

Range Randomization

The most common randomization that we'll use involves generating a random value within an allowed range. The OSVVM Randomization Package supports basic scalar randomization for Stanrd Logic Vector, Unsigned, Signed, Integer, Real, and Time types.

We call the randomization method of the random_variable (of the protected RandomPType type) for each data type, passing it the legal range to generate a random value. For Standard Logic Vector, Unsigned and Signed types, we must also pass the bit width of the vector.

The following code does a basic range randomization for all supported types except time.

report "Basic randomization with ranges for all supported types";
report "Random Integer: " & integer'image(random_variable.RandInt(0, 255));
report "Random Standard Logic Vector: " & to_hstring(random_variable.RandSlv(0, 255, 8));
report "Random Unsigned: " & to_string(to_integer(random_variable.RandUnsigned(0, 255, 8)));
report "Random Signed: " & to_string(to_integer(random_variable.RandSigned(-127, -1, 8)));
report "Random Real: " & real'image(random_variable.RandReal(0.1, 99.9));

We can see the randomized values in the simulator output.

osvvm_random_tb.vhd:27:5:@0ms:(report note): Basic randomization with ranges for all supported types
osvvm_random_tb.vhd:28:5:@0ms:(report note): Random Integer: 179
osvvm_random_tb.vhd:29:5:@0ms:(report note): Random Standard Logic Vector: 9D
osvvm_random_tb.vhd:30:5:@0ms:(report note): Random Unsigned: 253
osvvm_random_tb.vhd:31:5:@0ms:(report note): Random Signed: -4
osvvm_random_tb.vhd:32:5:@0ms:(report note): Random Real: 9.192441489777191e1

Randomization with Exclusion

Once we define a range for generating random values, we can also keep specific values from being generated. We do this by adding the values to be excluded after the range definition.

The following code first generates data between 1 and 3, excluding 2. Then it generates data between 0 and 10, excluding 2, 4, 6, and 8.

for i in 1 to 10 loop
  report "Random Integer (1-3, excluding 2): " & integer'image(random_variable.RandInt(1, 3, 2));
end loop;

for i in 1 to 10 loop
  report "Random Integer (0-10 excluding 2, 4, 6, and 8): " & integer'image(random_variable.RandInt(0, 10, (2, 4, 6, 8)));
end loop;

The simulator output confirms that the data was randomized as instructed.

Randomize with range and single-value exclusion
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 1
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 1
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 1
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 1
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3
osvvm_random_tb.vhd:36:7:@0ms:(report note): Random Integer (1-3, excluding 2): 3 


Randomize with range and set exclusion
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 7
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 10
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 0
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 5
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 3
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 7
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 10
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 7
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 0
osvvm_random_tb.vhd:41:7:@0ms:(report note): Random Integer (0-10 excluding 2, 4, 6, and 8): 3

Set Randomization

In addition to generating values within a range, the OSVVM randomization functions also allow us to select values from a specific set randomly. We pass the set as a list of comma-separated values.

In the following code, we cycle through the values 10, 20, and 30 at random.

for i in 1 to 10 loop
  report "Random Integer from set (10, 20, 30): " & integer'image(random_variable.RandInt((10, 20, 30)));
end loop;

The simulator output confirms that the data was randomized as desired.

Randomize a set
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 20
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 20
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 10
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 30
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 30
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 20
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 10
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 10
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 30
osvvm_random_tb.vhd:46:7:@0ms:(report note): Random Integer from set (10, 20, 30): 20

Weighted Randomization

By default, the set randomization assigns the same probability to each value in the set. We can adjust the likelihood of each value being generated by using weighted randomization.

In weighted randomization, we provide a value and a weight for each value in the set we want to randomize. For better results, the weights should add up to 10 or 100.

In the following example, we assign a weight of 80% to the value 1 and 20% to the value 2.

report "Weighted randomization" ;
for i in 1 to 10 loop
  report "Weighted Random Integer: " & integer'image(random_variable.DistValInt(((1,8), (2,2))));
end loop;

The simulator output matches our target probability distribution.

Weighted randomization
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 2
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 2
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1
osvvm_random_tb.vhd:51:7:@0ms:(report note): Weighted Random Integer: 1

Vector Randomization

Finally, the OSVVM randomization package also includes functions to randomize vector values. As shown in the code below, they support the range, exclusion, and set randomization modes we discussed earlier. In addition, we can instruct the vector randomization functions not to repeat the last N values when filling the target vector.

"Vector randomization" ;
integer_array(0 to 9) := random_variable.RandIntV(0, 255, 10);              -- Randomize range
for i in 0 to 9 loop
  report "Random Integer Array Element " & integer'image(i) & ": " & integer'image(integer_array(i)); 
end loop;
integer_array(0 to 9) := random_variable.RandIntV(0, 9, (2, 4, 6, 8), 10);  -- Randomize range with set exclusion
for i in 0 to 9 loop
  report "Random Integer Array Element " & integer'image(i) & ": " & integer'image(integer_array(i)); 
end loop;
integer_array(0 to 9) := random_variable.RandIntV((2, 4, 6, 8), 10);        -- Randomize set
for i in 0 to 9 loop
  report "Random Integer Array Element " & integer'image(i) & ": " & integer'image(integer_array(i)); 
end loop;
integer_array(0 to 9) := random_variable.RandIntV((2, 4, 6, 8), 3, 10);     -- Randomize set, do not repeat the last three values
for i in 0 to 9 loop
  report "Random Integer Array Element " & integer'image(i) & ": " & integer'image(integer_array(i)); 
end loop;

We can see the simulator output below.

Vector randomization
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 0: 225
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 1: 55
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 2: 166
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 3: 31
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 4: 43
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 5: 111
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 6: 148
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 7: 4
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 8: 23
osvvm_random_tb.vhd:57:7:@0ms:(report note): Random Integer Array Element 9: 100

osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 0: 0
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 1: 7
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 2: 0
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 3: 9
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 4: 0
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 5: 1
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 6: 0
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 7: 7
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 8: 5
osvvm_random_tb.vhd:61:7:@0ms:(report note): Random Integer Array Element 9: 1

osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 0: 4
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 1: 6
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 2: 6
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 3: 8
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 4: 4
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 5: 2
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 6: 6
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 7: 8
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 8: 6
osvvm_random_tb.vhd:65:7:@0ms:(report note): Random Integer Array Element 9: 8

osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 0: 8
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 1: 2
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 2: 6
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 3: 8
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 4: 2
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 5: 6
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 6: 8
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 7: 2
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 8: 4
osvvm_random_tb.vhd:69:7:@0ms:(report note): Random Integer Array Element 9: 6

Cheers,

Isaac

Source Files