🎲 SystemVerilog: Class-Based Randomization and Constraints#
This section explores class-based random stimulus generation in SystemVerilog, detailing how to randomize class properties, use constraints, and manage randomization flows in complex testbenches.
1️⃣ Class-Based Random Stimulus#
SystemVerilog allows defining random variables inside classes using the rand
and randc
keywords. This makes it easy to create random test stimuli that model realistic scenarios.
Example:
class Packet;
rand bit [7:0] data;
endclass
Here, data
is marked as random and can be randomized using the randomize()
method.
2️⃣ Random Class Properties#
rand
: Generates random values with a uniform distribution.randc
: Generates random values by cycling through all possible values without repeating any until the cycle completes.
Example:
class Packet;
rand bit [7:0] data;
randc bit [3:0] id;
endclass
3️⃣ Class Object Randomization (randomize()
, pre_randomize()
, post_randomize()
)#
Call the randomize()
method on a class object to randomize its properties.
Example:
Packet pkt = new();
pkt.randomize();
You can customize the randomization process using:
pre_randomize()
: Called before randomization starts.post_randomize()
: Called after randomization completes.
Example:
class Packet;
rand bit [7:0] data;
function void pre_randomize();
$display("Before randomization");
endfunction
function void post_randomize();
$display("After randomization");
endfunction
endclass
4️⃣ Randomization in Aggregate Classes#
When a class contains other class objects, calling randomize()
also randomizes its sub-objects.
Example:
class Header;
rand bit [3:0] version;
endclass
class Packet;
rand Header hdr;
function new();
hdr = new();
endfunction
endclass
Packet pkt = new();
pkt.randomize(); // Also randomizes hdr.version
5️⃣ Inline Randomization Control (randomize() with {...}
)#
You can apply inline constraints at the time of randomization using the with
clause.
Example:
pkt.randomize() with { data > 8'h10; };
6️⃣ Controlling Randomization (rand_mode()
)#
Use rand_mode()
to enable or disable randomization for specific class members.
Example:
pkt.data.rand_mode(0); // Disable randomization for data
7️⃣ Constraint Blocks and Inheritance#
Use constraint
blocks inside classes to define rules that govern randomization.
Example:
class Packet;
rand bit [7:0] data;
constraint data_c { data > 8'h10; }
endclass
Constraints are inherited in subclasses unless explicitly overridden.
8️⃣ Constraint Expressions#
a. Set Membership#
constraint data_set { data inside {8'hAA, 8'hBB, 8'hCC}; }
b. Weighted Distributions#
constraint weighted { data dist {8'hAA:=2, 8'hBB:=1}; }
c. Iterative Constraints#
constraint loop_c { foreach (array[i]) array[i] > 0; }
9️⃣ Controlling Constraints (constraint_mode()
)#
Use constraint_mode()
to enable or disable a specific constraint at runtime.
Example:
pkt.data_c.constraint_mode(0); // Disable constraint data_c
🔟 Randomization Flow and solve_before
#
SystemVerilog uses a randomization solver to satisfy constraints. Sometimes, you need one variable to be solved before another—use solve ... before
.
Example:
constraint order_c { solve length before payload; }
1️⃣1️⃣ Randomization Failure#
Randomization can fail if constraints are unsatisfiable. Check the result of randomize()
:
if (!pkt.randomize())
$display("Randomization failed");
📖 Conclusion#
Mastering class-based random stimulus generation and constraints is essential for creating powerful and flexible SystemVerilog testbenches. These techniques help generate realistic scenarios and thoroughly test designs.
// File: tb_class_randomization.sv
`timescale 1ns/1ps
// Packet sınıfı: Basit randomizable veri yapısı
class Packet;
rand bit [7:0] data;
randc bit [3:0] id;
// Constraint örneği: data 0x10'dan büyük olacak
constraint data_c { data > 8'h10; }
// Inline debug için pre/post randomize fonksiyonları
function void pre_randomize();
$display("[Packet] Before randomization");
endfunction
function void post_randomize();
$display("[Packet] After randomization - data = %0h, id = %0d", data, id);
endfunction
endclass
// Header sınıfı: Aggregate sınıf örneği
class Header;
rand bit [3:0] version;
endclass
// Aggregate sınıf: Packet içinde Header nesnesi kullanılıyor
class ComplexPacket;
rand Packet pkt;
rand Header hdr;
function new();
pkt = new();
hdr = new();
endfunction
endclass
// WeightedPacket sınıfı: Weighted distribution constraint örneği
class WeightedPacket;
rand bit [7:0] priority_;
constraint weighted_c { priority_ dist {8'hAA:=3, 8'hBB:=1}; }
endclass
// ImpossiblePacket sınıfı: Çakışan constraint örneği
class ImpossiblePacket;
rand bit [7:0] data;
constraint impossible_c { data inside {8'h00} && data inside {8'hFF}; } // Çakışan constraint
endclass
// Testbench modülü
module tb_class_randomization;
Packet p;
ComplexPacket cp;
int status;
WeightedPacket wp;
ImpossiblePacket ip;
initial begin
// Basit Packet randomization
p = new();
status = p.randomize();
if (!status)
$display("[TB] Randomization failed!");
else
$display("[TB] Randomized Packet - data: %0h, id: %0d", p.data, p.id);
// Inline constraint kullanımı
p.randomize() with { data inside {8'hAA, 8'hBB}; };
$display("[TB] Inline randomized data = %0h", p.data);
// Constraint'leri runtime kontrol etme
p.data_c.constraint_mode(0); // constraint devre dışı
p.randomize();
$display("[TB] Constraint disabled data = %0h", p.data);
// Aggregated class randomization
cp = new();
status = cp.randomize();
if (status)
$display("[TB] ComplexPacket - pkt.data = %0h, hdr.version = %0d", cp.pkt.data, cp.hdr.version);
// Weighted distribution constraint örneği
wp = new();
repeat (5) begin
if (wp.randomize())
$display("[TB] WeightedPacket - priority: %0h", wp.priority_);
end
// Randomization failure örneği
ip = new();
if (!ip.randomize())
$display("[TB] Randomization failed due to conflicting constraints.");
else
$display("[TB] ImpossiblePacket - data = %0h", ip.data);
#10 $finish;
end
endmodule