🎲 SystemVerilog: Class Tabanlı Randomizasyon ve Kısıtlamalar#
Bu bölümde, SystemVerilog’ta class tabanlı random stimulus üretimi, class property’lerinin randomize edilmesi, constraint kullanımı ve karmaşık testbench’lerde randomizasyon akışlarının nasıl yönetileceği detaylıca anlatılıyor.
1️⃣ Class Tabanlı Random Stimulus#
SystemVerilog’ta, sınıf içinde rand
ve randc
anahtar kelimeleri kullanılarak random değişkenler tanımlanabilir. Bu sayede gerçekçi test senaryoları için random stimulus üretmek kolaylaşır.
Örnek:
class Packet;
rand bit [7:0] data;
endclass
Burada data
, randomize edilebilir olarak işaretlenmiş ve randomize()
metodu ile randomize edilebilir.
2️⃣ Random Class Properties#
rand
: Değerleri eşit olasılıkla (uniform dağılım) rastgele üretir.randc
: Tüm olası değerleri tekrar etmeden rastgele üretir ve değerler tüketildikten sonra tekrar başa döner.
Örnek:
class Packet;
rand bit [7:0] data;
randc bit [3:0] id;
endclass
3️⃣ Class Object Randomizasyonu (randomize()
, pre_randomize()
, post_randomize()
)#
Bir sınıf nesnesinde randomize edilebilir property’leri randomize etmek için randomize()
kullanılır.
Örnek:
Packet pkt = new();
pkt.randomize();
Randomizasyonu özelleştirmek için:
pre_randomize()
: Randomizasyon başlamadan önce çağrılır.post_randomize()
: Randomizasyon tamamlandıktan sonra çağrılır.
Örnek:
class Packet;
rand bit [7:0] data;
function void pre_randomize();
$display("Randomizasyon öncesi");
endfunction
function void post_randomize();
$display("Randomizasyon sonrası");
endfunction
endclass
4️⃣ Aggregate Class’larda Randomizasyon#
Bir sınıf başka bir sınıf nesnesini içeriyorsa, randomize()
çağrısı alt nesneleri de randomize eder.
Örnek:
class Header;
rand bit [3:0] version;
endclass
class Packet;
rand Header hdr;
function new();
hdr = new();
endfunction
endclass
Packet pkt = new();
pkt.randomize(); // hdr.version da randomize edilir
5️⃣ Inline Randomizasyon Kontrolü (randomize() with {...}
)#
with
ifadesi kullanılarak randomizasyon sırasında inline constraint uygulanabilir.
Örnek:
pkt.randomize() with { data > 8'h10; };
6️⃣ Randomizasyon Kontrolü (rand_mode()
)#
Belirli property’lerin randomize edilip edilmeyeceğini kontrol etmek için rand_mode()
kullanılır.
Örnek:
pkt.data.rand_mode(0); // data için randomizasyon kapalı
7️⃣ Constraint Block’ları ve Kalıtım#
Sınıf içinde constraint
blokları tanımlanarak randomizasyon için kurallar oluşturulur.
Örnek:
class Packet;
rand bit [7:0] data;
constraint data_c { data > 8'h10; }
endclass
Bu constraint’ler alt sınıflarda kalıtım yoluyla devralınır veya override edilebilir.
8️⃣ Constraint İfadeleri#
a. Küme Üyeliği (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. İteratif Constraints#
constraint loop_c { foreach (array[i]) array[i] > 0; }
9️⃣ Constraint’lerin Kontrolü (constraint_mode()
)#
constraint_mode()
ile belirli bir constraint runtime sırasında açılıp kapatılabilir.
Örnek:
pkt.data_c.constraint_mode(0); // data_c constraint’i devre dışı
🔟 Randomizasyon Akışı ve solve_before
#
SystemVerilog randomizasyon solver’ı constraint’leri çözerek randomizasyonu gerçekleştirir. Bazı durumlarda, bir değişkenin diğerinden önce çözümlenmesi gerekebilir; bunun için solve ... before
kullanılır.
Örnek:
constraint order_c { solve length before payload; }
1️⃣1️⃣ Randomizasyon Başarısızlığı#
Constraint’ler tutarsız veya çözümsüz ise randomizasyon başarısız olabilir. randomize()
fonksiyonunun sonucunu kontrol etmek gerekir:
if (!pkt.randomize())
$display("Randomizasyon başarısız");
📖 Sonuç#
Class tabanlı random stimulus üretimi ve constraint kullanımı, SystemVerilog testbench’lerinde güçlü ve esnek yapılar kurmak için kritik önem taşır. Bu teknikler, gerçekçi test senaryoları üretmeyi ve tasarımları kapsamlı şekilde test etmeyi mümkün kılar.
// 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