Metodlar ve Constructor
Gün 2: Nesne Yönelimli Programlama (OOP) | Sınıf metodları (task/function), new() constructor, copy, compare
Bu derste bir sınıfın davranışını tanımlayan metodları öğreneceğiz: anında sonuç döndüren function'lar, simülasyon zamanı tüketebilen task'lar, nesneyi başlatan new() constructor'ı ve doğrulamada çok kullanılan copy() ile compare() yardımcı metodları.
Function ve Task Farkı
SystemVerilog'da iki tür metod vardır ve aralarındaki en temel fark zaman ile ilgilidir:
function: Simülasyon zamanı tüketemez (içinde#,@,waitgibi gecikme yapıları bulunamaz). Anında çalışır ve genellikle bir değer döndürür. Hesaplama, dönüştürme, karşılaştırma gibi işler için idealdir.task: Simülasyon zamanı tüketebilir (gecikme ve olay bekleme içerebilir). Zaman içinde gerçekleşen davranışları (örneğin bir protokol adımını) modellemek için kullanılır.
Constructor (new) ve Yardımcı Metodlar
Her sınıfın bir constructor'ı (new) vardır; nesne oluşturulurken çağrılır ve özelliklere başlangıç değerleri atar. Varsayılan argümanlar sayesinde aynı constructor hem parametresiz hem parametreli çağrılabilir.
Doğrulama ortamlarında iki yardımcı metod kalıbı çok yaygındır:
copy(): Mevcut nesnenin özelliklerini yeni bir nesneye aktararak bağımsız bir kopya üretir.compare(): İki nesnenin alanlarını karşılaştırıp eşit olup olmadıklarını döndürür; beklenen ve gözlemlenen veriyi kıyaslamak için kullanılır.
Kaynak Kod
// =============================================================================
// GUN 2 - Konu 2: Sinif Metodlari (Tasks ve Functions), new() Constructor
// =============================================================================
class ALU_Transaction;
typedef enum {ADD, SUB, MUL, DIV, AND, OR, XOR} op_e;
logic [15:0] operand_a;
logic [15:0] operand_b;
op_e operation;
logic [31:0] result;
bit done;
// Constructor: Varsayilan ve parametreli
function new(logic [15:0] a = 0, logic [15:0] b = 0, op_e op = ADD);
this.operand_a = a;
this.operand_b = b;
this.operation = op;
this.result = 0;
this.done = 0;
endfunction
// Function: Aninda sonuc doner (zaman tuketmez)
function logic [31:0] calculate();
case (operation)
ADD: result = operand_a + operand_b;
SUB: result = operand_a - operand_b;
MUL: result = operand_a * operand_b;
DIV: result = (operand_b != 0) ? operand_a / operand_b : 'hFFFF_FFFF;
AND: result = operand_a & operand_b;
OR: result = operand_a | operand_b;
XOR: result = operand_a ^ operand_b;
endcase
done = 1;
return result;
endfunction
// Task: Zaman tuketebilir (simulasyon zamani ilerleyebilir)
task execute(input int delay_ns);
#delay_ns;
void'(calculate());
$display(" [%0t] Islem tamamlandi: %s", $time, to_string());
endtask
// Function: String formatinda dondur
function string to_string();
return $sformatf("0x%04h %s 0x%04h = 0x%08h",
operand_a, operation.name(), operand_b, result);
endfunction
// Function: Paketi kopyala
function ALU_Transaction copy();
ALU_Transaction c = new();
c.operand_a = this.operand_a;
c.operand_b = this.operand_b;
c.operation = this.operation;
c.result = this.result;
c.done = this.done;
return c;
endfunction
// Function: Iki islemi karsilastir
function bit compare(ALU_Transaction other);
return (this.operand_a == other.operand_a &&
this.operand_b == other.operand_b &&
this.operation == other.operation);
endfunction
// Function: Yazdir
function void display(string prefix = "");
$display(" %s%s [done=%0b]", prefix, to_string(), done);
endfunction
endclass
module metodlar_ve_constructor;
initial begin
ALU_Transaction txn1, txn2, txn3;
$display("=== Sinif Metodlari ve Constructor ===\n");
// --- Constructor kullanimi ---
$display("--- Constructor ---");
txn1 = new(); // Varsayilan
txn2 = new(16'h000A, 16'h0005, ALU_Transaction::SUB); // Parametreli
txn3 = new(16'h00FF, 16'h0003, ALU_Transaction::MUL);
txn1.display("Varsayilan: ");
txn2.display("Parametreli: ");
// --- Function kullanimi ---
$display("\n--- Function: calculate() ---");
void'(txn2.calculate());
txn2.display("Hesaplandi: ");
void'(txn3.calculate());
txn3.display("Hesaplandi: ");
// --- Task kullanimi (zaman tuketir) ---
$display("\n--- Task: execute() ---");
txn1 = new(16'h0064, 16'h0032, ALU_Transaction::ADD);
txn1.execute(10);
txn1 = new(16'h00FF, 16'h0001, ALU_Transaction::AND);
txn1.execute(5);
// --- copy() ---
$display("\n--- Kopyalama ---");
begin
ALU_Transaction original, copied;
original = new(16'h1234, 16'h5678, ALU_Transaction::XOR);
void'(original.calculate());
copied = original.copy();
$display(" Orijinal:");
original.display(" ");
$display(" Kopya:");
copied.display(" ");
copied.operand_a = 16'hAAAA;
$display(" Kopya degistirildi - Orijinal etkilenmez:");
original.display(" Orijinal: ");
copied.display(" Kopya: ");
end
// --- compare() ---
$display("\n--- Karsilastirma ---");
begin
ALU_Transaction a, b;
a = new(16'h10, 16'h20, ALU_Transaction::ADD);
b = new(16'h10, 16'h20, ALU_Transaction::ADD);
$display(" a == b ? %s", a.compare(b) ? "EVET" : "HAYIR");
b.operation = ALU_Transaction::SUB;
$display(" a == b ? %s (op degisti)", a.compare(b) ? "EVET" : "HAYIR");
end
$display("\n=== Sinif Metodlari Sonu ===");
$finish;
end
endmodule
Kodun Açıklaması
ALU_Transactionsınıfı: Bir aritmetik-mantık işlemini modeller.operand_a,operand_b,operation,resultvedoneözelliklerine sahiptir.operation, sınıf içindetypedef enumile tanımlananop_etüründedir (ADD,SUB,MUL,DIV,AND,OR,XOR).new()constructor'ı: Varsayılan değerli argümanlar alır vethisile gelen parametreleri özelliklere atar;resultvedonealanlarını sıfırlar.calculate()function'ı: Bircasebloğuylaoperationdeğerine göre sonucu hesaplar,donebayrağını1yapar veresult'ı döndürür.functionolduğu için anında çalışır.DIVdurumunda sıfıra bölmeye karşı koruma vardır.execute()task'ı:#delay_nsile simülasyon zamanını ilerletir, sonravoid'(calculate())ile hesaplamayı yapar.taskolduğu için zaman tüketebilir; bu yüzden gecikme içerir.to_string()function'ı:$sformatfile işlemi okunur bir metne dönüştürür veoperation.name()ile enum değerinin ismini metin olarak alır.copy()function'ı:new()ile yeni bir nesne (c) oluşturur, tüm alanlarıthis'ten kopyalar ve döndürür. Bu sayede kopya üzerinde yapılan değişiklik (copied.operand_a = 16'hAAAA) orijinali etkilemez.compare()function'ı: İki nesneninoperand_a,operand_bveoperationalanlarını kıyaslayıpbitdöndürür. Örnekteb.operationdeğişince karşılaştırma sonucununHAYIR'a döndüğü gösterilir.void'(...)kullanımı:calculate()bir değer döndürür; bu değer kullanılmayacaksavoid'(...)ile açıkça yok sayılır.
Önemli Noktalar
- Bir
functioniçinde gecikme (#,@,wait) kullanılamaz. Zaman tüketmesi gereken davranışlar içintaskkullanın. - Dönüş değeri olan bir metodu yan etkisi için çağırıyor ve dönüşü kullanmıyorsanız,
void'(metot())ile derleyici uyarılarını engelleyebilirsiniz. copy()metodu burada alan alan kopyalama yapar; bu, sınıf içinde başka nesne handle'ları yoksa güvenli bir tam kopyadır (içinde alt-nesne olsaydı sığ/derin kopya ayrımına dikkat edilmeliydi).compare()'in hangi alanları karşılaştıracağı bir tasarım kararıdır; örnekteresultvedonedışarıda bırakılıp yalnızca girdi alanları kıyaslanmıştır.- Enum sabitlerine sınıf dışından
ALU_Transaction::SUBgibi kapsam çözümleme operatörü (::) ile erişilir. - Constructor'da varsayılan argümanlar tanımlamak, aynı
new()'i hemnew()hemnew(a, b, op)şeklinde esnekçe çağırmayı sağlar.