In SystemVerilog, variables declared as rand or randc inside a class can be randomized using the built-in randomize() method. This method returns 1 if the randomization is successful, and 0 if it fails. Randomization can fail due to reasons such as conflicting constraints, where the solver cannot find a valid value that meets all constraints. Class objects do not automatically get randomized; you need to call randomize() manually.

Syntax

virtual function int randomize();

Here’s an example demonstrating how to use the randomize() method.

Example: Simple Randomization

class Beverage;
  rand bit [7:0] beer_id;

  constraint c_beer_id { beer_id >= 10; beer_id <= 50; };
endclass

module tb;
   Beverage b;

   initial begin
      b = new();
      $display("Initial beerId = %0d", b.beer_id);
      if (b.randomize())
         $display("Randomization successful!");
      $display("After randomization beerId = %0d", b.beer_id);
   end
endmodule

Simulation Log

run -all;
# KERNEL: Initial beerId = 0
# KERNEL: Randomization successful!
# KERNEL: After randomization beerId = 25
# KERNEL: Simulation has finished. There are no more test vectors to simulate.

Pre_randomize() Function

The pre_randomize() function is automatically called before the randomize() method. You can define this function inside the class whose object will be randomized.

function void pre_randomize();
   $display("This will be called just before randomization");
endfunction

Example: Using Pre_randomize()

class Beverage;
  rand bit [7:0] beer_id;

  constraint c_beer_id { beer_id >= 10; beer_id <= 50; };

  function void pre_randomize();
    $display("This will be called just before randomization");
  endfunction
endclass

Simulation Log

run -all;
# KERNEL: Initial beerId = 0
# KERNEL: This will be called just before randomization
# KERNEL: Randomization successful!
# KERNEL: After randomization beerId = 25
# KERNEL: Simulation has finished. There are no more test vectors to simulate.

Post_randomize() Function

The post_randomize() function is called automatically after the randomize() method completes. You can define this function within the class whose object will be randomized.

function void post_randomize();
   $display("This will be called just after randomization");
endfunction

Example: Using Post_randomize()

class Beverage;
  rand bit [7:0] beer_id;

  constraint c_beer_id { beer_id >= 10; beer_id <= 50; };

  function void pre_randomize();
    $display("This will be called just before randomization");
  endfunction

  function void post_randomize();
    $display("This will be called just after randomization");
  endfunction
endclass

Simulation Log

run -all;
# KERNEL: Initial beerId = 0
# KERNEL: This will be called just before randomization
# KERNEL: This will be called just after randomization
# KERNEL: Randomization successful!
# KERNEL: After randomization beerId = 25
# KERNEL: Simulation has finished. There are no more test vectors to simulate.

Overriding Pre_randomize() and Post_randomize()

You can override the pre_randomize() and post_randomize() methods to change the randomization behavior. In derived classes, if no user-defined implementation of these functions exists, the parent class’s function is called automatically.

Note that pre_randomize() and post_randomize() are not virtual methods, although they behave like virtual methods. If you try to declare them as virtual, the compiler will generate an error:

class Beverage;
  rand bit [7:0] beer_id;

  virtual function void pre_randomize();
    $display("This will be called just before randomization");
  endfunction
endclass

Simulation Log

virtual function void pre_randomize();
                                      |
ncvlog: *E,CLSMNV (testbench.sv,7|36): The pre_randomize() method cannot be declared virtual.

Important Notes

  1. Randomization Failure: If randomize() fails, post_randomize() is not called.
  2. Built-in randomize(): The randomize() method cannot be overridden.
  3. Failure Effects: If randomization fails, variables retain their original values and are not modified.

Conclusion

The pre_randomize() and post_randomize() functions offer a way to control actions before and after the randomization process in SystemVerilog. They allow users to customize and extend the behavior of randomization, ensuring that each randomization event behaves as required in their testbenches.

Scroll to Top