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
- Randomization Failure: If
randomize()
fails,post_randomize()
is not called. - Built-in randomize(): The
randomize()
method cannot be overridden. - 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.