Random System Methods in SV

SystemVerilog offers a variety of tools for generating random numbers, which are essential for testbench design in constrained random verification (CRV). Among these tools, the random system methods—$random, $urandom, and $random_range()—provide flexible and straightforward ways to generate random values for diverse use cases.

In this article, we’ll dive deep into each of these methods, understand their differences, and explore practical examples to illustrate their applications.

1. $random: The Classic Random Number Generator

The $random system function is the traditional random number generator in SystemVerilog. It generates a signed 32-bit random integer.

Syntax

int random_value = $random(seed);
  • seed: An optional integer value used to initialize the random number generator. Using the same seed produces the same sequence of random numbers.

Characteristics

  1. Generates signed 32-bit integers.
  2. Output can include negative values.
  3. Suitable for basic randomization tasks but has limitations for modern verification needs.

Example

module test;
    initial begin
        int val1 = $random;         // Generates a random number
        int val2 = $random(42);     // Uses 42 as the seed
        int val3 = $random(42);     // Reproduces the same sequence if seed is reused

        $display("Random value 1: %d", val1);
        $display("Random value 2: %d", val2);
        $display("Random value 3 (same seed): %d", val3);
    end
endmodule

Output:

Random value 1:   303379748
Random value 2: -2144582656
Random value 3 (same seed): -2144582656

Limitations

  • Signed outputs may not be desirable for all use cases.
  • Non-thread-safe in multi-threaded environments, leading to potential conflicts.

2. $urandom: The Unsigned Alternative

The $urandom system function improves upon $random by generating unsigned 32-bit random numbers. It also addresses some of the limitations of $random in modern multi-threaded testbenches.

Syntax

int unsigned random_value = $urandom(seed);
  • seed: Optional, same behavior as $random.

Characteristics

  1. Generates unsigned 32-bit integers.
  2. Thread-safe, making it better suited for multi-threaded environments.
  3. Ideal for most hardware verification scenarios.

Example

module test;
    initial begin
        int unsigned val1 = $urandom;        // Generates an unsigned random number
        int unsigned val2 = $urandom(123);  // Uses a seed for reproducibility

        $display("Random value 1: %0d", val1);
        $display("Random value 2 (seeded): %0d", val2);
    end
endmodule

Output:

Random value 1: 1107807303
Random value 2 (seeded): 2720986350

Advantages Over $random

  • Prevents negative numbers.
  • More suitable for constrained randomization in modern test environments.

3. $urandom_range(): Random Numbers Within a Range

SystemVerilog introduces $urandom_range() for generating random numbers within a specific range, which is not directly supported by $random or $urandom.

Syntax

int unsigned random_value = $urandom_range(max, min);
  • max: The upper bound of the range (inclusive).
  • min: The lower bound of the range (inclusive).

Characteristics

  1. Generates unsigned 32-bit integers within the specified range.
  2. Ensures the output always falls between min and max.
  3. Convenient for constrained scenarios.

Example

module test;
    initial begin
        int unsigned rand_in_range = $urandom_range(50, 10); // Generates a value between 10 and 50
        $display("Random value within range (10 to 50): %0d", rand_in_range);
    end
endmodule

Output:

Random value within range (10 to 50): 23

Advantages

  • Simplifies bounded randomization.
  • Eliminates the need for manual range mapping.

Practical Applications

Application 1: Generating Testbench Values

Using $urandom_range(), you can quickly generate random stimulus for a testbench.

module test;
    initial begin
        // Random delay in the range of 5 to 20
        int delay = $urandom_range(20, 5);
        $display("Random delay: %0d cycles", delay);
    end
endmodule

Output:

Random delay: 12 cycles

Application 2: Seeding for Reproducibility

Seeding allows you to reproduce a specific sequence of random values, useful for debugging.

module test;
    initial begin
        int unsigned seed = 101;
        $display("Random value 1: %0d", $urandom(seed));
        $display("Random value 2: %0d", $urandom(seed));
    end
endmodule

Application 3: Constrained Initialization

Initialize an array with random values within a specific range using $urandom_range().

module test;
    initial begin
        int unsigned array[10];
        for (int i = 0; i < 10; i++) begin
            array[i] = $urandom_range(100, 50);
            $display("Array[%0d] = %0d", i, array[i]);
        end
    end
endmodule

Output:

Array[0] = 82
Array[1] = 70
Array[2] = 60
Array[3] = 86
Array[4] = 99
Array[5] = 52
Array[6] = 96
Array[7] = 92
Array[8] = 62
Array[9] = 58