EDA Playground'da Dene

Method Argüman Yönleri - input, output, inout ve ref Farkı

Gün 2: Method Argüman Yönleri | Yönlerin farkları

  • input: Dışarıdaki my_obj adresini içeriye kopyalar. İçerideki d.value = 10 dediğinde asıl nesneyi değiştirirsin (çünkü aynı adrese bakıyorlar). Ama içeride d = new(99) dediğinde, sadece içerideki kopya etiketin yönünü değiştirmiş olursun. Task bitince o kopya etiket silinir, dışarıdaki my_obj eski nesneye bakmaya devam eder.

  • output: İçeriye hiçbir bilgi almaz. İçeride sıfırdan bir adres yaratır (new). Task bittiği saniye, bu yeni adresi dışarıdaki my_obj'ye zorla yazar.

  • inout: input ve output'un birleşimidir. Dışarıdaki adresi alır, içeride kullanmana izin verir. Eğer içeride handle'ı başka bir yere yönlendirirsen (new(30)), task bittiği an bu yeni adresi dışarıya kopyalar.

  • ref: Kopya yoktur. İçerideki d ile dışarıdaki my_obj kelimenin tam anlamıyla aynı değişkendir. İçeride handle'a new() atadığın an, dışarıdaki değişken de anında o yeni nesneye bakmaya başlar (task'ın bitmesini bile beklemez). Performans açısından en hızlısıdır çünkü adres kopyalama işlemi bile yapılmaz.

Kaynak Kod

// =============================================================================
// GUN 2 Konu 2.1 - ARGÜMAN YÖNLERİ: input vs output vs inout vs ref
// =============================================================================

class Dummy;
  int value;
  
  // Kurucu Metot (Constructor)
  function new(int v = 0);
    value = v;
  endfunction
endclass

module arg_directions_demo;

  // 1. INPUT: İçeri giren handle'ı (işaretçiyi) kopyalar. 
  // Çağrıldığı yerdeki asıl handle'ın işaret ettiği yeri değiştiremez, 
  // ancak nesnenin İÇERİĞİNİ değiştirebilir.
  task automatic test_input(input Dummy d);
    // Nesnenin içeriğini değiştirmek dışarıdan görünür
    d.value = 10; 
    
    // Handle'ın kendisini değiştirmek dışarıdan GÖRÜNMEZ
    d = new(99); 
  endtask

  // 2. OUTPUT: Başlangıçta null'dır. Task bittiğinde handle'ı DIŞARI kopyalar.
  task automatic test_output(output Dummy d);
    // Task bittikten sonra dışarıdaki handle bu yeni nesneyi işaret edecektir
    d = new(20); 
  endtask

  // 3. INOUT: Handle'ı İÇERİ kopyalar ve task bittiğinde DIŞARI kopyalar.
  task automatic test_inout(inout Dummy d);
    // Gelen nesneyi değiştirir
    d.value = 35; 
    
    // Yeni bir nesneye işaret eder, task bittikten sonra dışarısı bu yeni adresi görecektir
    d = new(30); 
  endtask

  // 4. REF: Handle'ın GERÇEK hafıza referansını iletir (kopyalama yapılmaz).
  // Handle üzerindeki herhangi bir değişiklik anında dışarıdan görünür.
  task automatic test_ref(ref Dummy d);
    // Dışarıdaki handle anında bu yeni nesneyi işaret etmeye başlar
    d = new(40); 
  endtask

  initial begin
    Dummy my_obj;

    $display("=== Argüman Yönleri Demosu ===\n");

    // --- INPUT ---
    my_obj = new(1);
    test_input(my_obj);
    // my_obj.value 99 DEĞİL, 10 olacaktır. 'new(99)' task bittiğinde silindi.
    $display("[INPUT]  test_input sonrasi : my_obj.value = %0d", my_obj.value); 

    // --- OUTPUT ---
    // my_obj adresi tamamen üzerine yazılır.
    test_output(my_obj);
    $display("[OUTPUT] test_output sonrasi: my_obj.value = %0d", my_obj.value); 

    // --- INOUT ---
    test_inout(my_obj);
    // my_obj artık test_inout içinde oluşturulan yeni nesneyi işaret ediyor.
    $display("[INOUT]  test_inout sonrasi : my_obj.value = %0d", my_obj.value); 

    // --- REF ---
    test_ref(my_obj);
    // my_obj anında doğrudan değiştirildi.
    $display("[REF]    test_ref sonrasi   : my_obj.value = %0d", my_obj.value); 

    $finish;
  end
endmodule