Skip to main content

SystemVerilog: Class-Based Randomization and Constraints

· loading · loading · ·
Course Verification SystemVerilog SystemVerilog Randomization Verification Constraints
Course Verification SystemVerilog
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
SystemVerilog Design Series - This article is part of a series.
Part 29: This Article

🎲 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

SystemVerilog Design Series - This article is part of a series.
Part 29: This Article

Related

Advanced OOP in SystemVerilog: Aggregation, Inheritance, and More
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog
Advanced OOP in SystemVerilog: Constructors, Handles, and Static Members
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog
Mailboxes in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog IPC Mailboxes Verification Synchronization
Course Verification SystemVerilog
Named Events in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog IPC Named Events Verification Synchronization
Course Verification SystemVerilog
Object-Oriented Programming in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Classes
Course Verification SystemVerilog
Polymorphism and Virtuality in SystemVerilog
· loading · loading
Course Verification SystemVerilog SystemVerilog OOP Object-Oriented Programming Verification Virtuality
Course Verification SystemVerilog