EDA Playground'da Dene

Test Sınıfları

Gün 7: Bitirme Projesi - Bölüm 2 | Farklı test senaryoları: Random, Corner, Stress

Test sınıfları, doğrulama senaryolarını tanımlayan en üst seviye kontrol katmanıdır. ALU mimarimizde test, environment'ı oluşturur, yapılandırır ve çalıştırır; "hangi senaryoyu, kaç transaction ile koşacağız?" kararını verir.

Test Katmanı ve Mimarideki Yeri

Test, testbench top ile environment arasında durur. Top seviyesi yalnızca hangi testin koşulacağını seçer; testin içeriğini test sınıfları belirler. Bu katman sayesinde aynı environment, farklı senaryolarla tekrar tekrar kullanılabilir.

Bu derste kalıtım tabanlı bir test hiyerarşisi vardır:

  • ALU_Base_Test: Ortak akışı tanımlar (buildresetrunreport). run() ve get_num_transactions() metotları virtual'dır.
  • ALU_Random_Test: Taban testi miras alır; yalnızca transaction sayısını (200) değiştirir, varsayılan rastgele generator'ı kullanır.
  • ALU_Corner_Test: run() metodunu ezerek environment'ın generator'ını ALU_Corner_Generator ile değiştirir; böylece köşe durum testi koşar.

Polymorphism ile Generator Değiştirme

ALU_Corner_Test'in en öğretici yanı, environment kurulduktan sonra env.gen referansını türetilmiş bir generator'la değiştirmesidir. run() metodu virtual olduğundan, environment fork ettiğinde doğru (köşe) generator çalışır. Bu, çalışma zamanı çok biçimliliğinin (polymorphism) pratik bir örneğidir.

Kaynak Kod

// =============================================================================
// GUN 7 - Konu 4: Test Siniflari - Farkli Test Senaryolari
// =============================================================================

class ALU_Base_Test;
  ALU_Environment env;
  virtual alu_if.driver  drv_vif;
  virtual alu_if.monitor mon_vif;
  string test_name;

  function new(virtual alu_if.driver drv_vif, virtual alu_if.monitor mon_vif,
               string name = "Base_Test");
    this.drv_vif   = drv_vif;
    this.mon_vif   = mon_vif;
    this.test_name = name;
  endfunction

  virtual task run();
    $display("\n##########################################################");
    $display("  TEST: %s", test_name);
    $display("##########################################################\n");

    // Environment olustur
    env = new(drv_vif, mon_vif, get_num_transactions());
    env.build();
    env.reset();
    env.run();
    env.report();
  endtask

  virtual function int get_num_transactions();
    return 100;
  endfunction
endclass

// Rastgele test
class ALU_Random_Test extends ALU_Base_Test;
  function new(virtual alu_if.driver drv_vif, virtual alu_if.monitor mon_vif);
    super.new(drv_vif, mon_vif, "Random_Test");
  endfunction

  virtual function int get_num_transactions();
    return 200;
  endfunction
endclass

// Kose durumu testi
class ALU_Corner_Test extends ALU_Base_Test;
  function new(virtual alu_if.driver drv_vif, virtual alu_if.monitor mon_vif);
    super.new(drv_vif, mon_vif, "Corner_Case_Test");
  endfunction

  virtual task run();
    ALU_Corner_Generator alu_c_gen;
    env = new(drv_vif, mon_vif, get_num_transactions());
    env.build();
    alu_c_gen = new(env.gen2drv_mbx, get_num_transactions());
    env.gen = alu_c_gen;
    
    // 3. Run simulation
    env.reset();
    env.run();
    env.report();
  endtask
endclass

Kodun Açıklaması

  • ALU_Base_Test üyeleri: env referansı, drv_vif/mon_vif virtual interface'leri ve test_name etiketini tutar.
  • ALU_Base_Test.run(): Test başlığını basar, env = new(...) ile environment'ı get_num_transactions() kadar işlemle oluşturur, ardından build(), reset(), run(), report() sırasını çağırır.
  • get_num_transactions(): Taban sınıfta 100 döndürür; türetilmiş sınıflar bunu ezerek farklı yük belirleyebilir.
  • ALU_Random_Test: super.new(..., "Random_Test") ile isimlendirilir ve get_num_transactions()200 döndürecek şekilde ezer. Taban run()'ı olduğu gibi kullanır.
  • ALU_Corner_Test.run(): Burada akış özelleştirilir; environment kurulduktan sonra alu_c_gen = new(env.gen2drv_mbx, ...) ile bir köşe generator'ı oluşturulur ve env.gen = alu_c_gen ile environment'ın generator'ı değiştirilir. Sonra reset(), run(), report() çağrılır.

Önemli Noktalar

  • run() ve get_num_transactions()'ın virtual olması, test hiyerarşisinin temelidir; aynı taban akış farklı senaryolara uyarlanır.
  • ALU_Corner_Test, generator'ı build()'den sonra değiştirir; çünkü değiştirilecek generator'ın bağlanacağı env.gen2drv_mbx mailbox'ı build aşamasında oluşur.
  • env.gen'in çalışma zamanında yeniden atanması, gen.run()'ın virtual olması sayesinde doğru türetilmiş davranışı tetikler.
  • Yeni bir test senaryosu eklemek kolaydır: ALU_Base_Test'ten türeyip yalnızca farklı kısımları ezmek yeterlidir; mevcut kodu değiştirmeye gerek kalmaz (açık/kapalı prensibi).
  • Test ismi (test_name) anlamlı tutulmalıdır; raporlarda ve top seviyesindeki +TEST= seçiminde bu isim referans alınır.