EDA Playground'da Dene

Environment Sınıfı

Gün 7: Bitirme Projesi - Bölüm 2 | Tüm bileşenleri kapsayan ortam sınıfı

Environment (ortam), tüm doğrulama bileşenlerini tek bir çatı altında toplayan, onları oluşturan ve birbirine bağlayan üst düzey kapsayıcıdır. ALU mimarimizde generator, driver, monitor, scoreboard ve coverage'ı barındırır; mailbox'ları üretip aralarındaki tüm bağlantıyı kurar.

Environment ve Mimarideki Yeri

Environment, testbench'in "montaj fabrikası"dır. Tek tek bileşenleri tanımak yerine, test sınıfı yalnızca environment ile konuşur. Sorumlulukları:

  • Mailbox'ları oluşturmak: gen2drv_mbx, drv2scb_mbx, mon2scb_mbx kanallarını üretir.
  • Bileşenleri bağlamak: Her bileşene doğru mailbox ve virtual interface referanslarını verir.
  • Yaşam döngüsünü yönetmek: buildresetrunreport aşamalarını sıralı yürütür.

Mailbox Bağlantı Topolojisi

Bileşenler arası veri akışı şu mailbox'larla kurulur:

  • gen2drv_mbx: Generator → Driver
  • drv2scb_mbx: Driver → Scoreboard (beklenen)
  • mon2scb_mbx: Monitor → Scoreboard (gerçek)

Bu topoloji sayesinde bileşenler birbirine doğrudan değil, yalnızca mailbox'lar üzerinden bağlıdır (gevşek bağlılık / loose coupling).

Paralel Çalışma ve Senkronizasyon

run() task'ı dört bileşeni (gen, drv, mon, scb) fork...join_any ile paralel başlatır. Generator işini bitirip done event'ini tetikleyince ve mailbox boşalınca simülasyon güvenli biçimde sonlandırılır.

Kaynak Kod

// =============================================================================
// GUN 7 - Konu 3: Environment - Tum Bilesenleri Kapsayan Sinif
// =============================================================================

class ALU_Environment;
  // Bilesenler
  ALU_Generator   gen;
  ALU_Driver      drv;
  ALU_Monitor     mon;
  ALU_Scoreboard  scb;
  ALU_Coverage    cov;  // 7_5_coverage.sv'de tanimli

  // Mailbox'lar
  mailbox #(ALU_Transaction) gen2drv_mbx;
  mailbox #(ALU_Transaction) drv2scb_mbx;
  mailbox #(ALU_Transaction) mon2scb_mbx;

  // Virtual interface
  virtual alu_if.driver  drv_vif;
  virtual alu_if.monitor mon_vif;

  // Konfigurasyon
  int num_transactions;

  function new(virtual alu_if.driver drv_vif, virtual alu_if.monitor mon_vif, int num_txn = 100);
    this.drv_vif = drv_vif;
    this.mon_vif = mon_vif;
    this.num_transactions = num_txn;
  endfunction

  // Tum bilesenleri olustur ve bagla
  function void build();
    $display("[Environment] Build asamasi");

    // Mailbox'lari olustur
    gen2drv_mbx = new();
    drv2scb_mbx = new();
    mon2scb_mbx = new();

    // Bilesenleri olustur
    gen = new(gen2drv_mbx, num_transactions);
    drv = new(drv_vif, gen2drv_mbx, drv2scb_mbx);
    mon = new(mon_vif, mon2scb_mbx);
    scb = new(drv2scb_mbx, mon2scb_mbx);
    cov = new();

    $display("[Environment] Tum bilesenler olusturuldu");
  endfunction

  // Reset
  task reset();
    $display("[Environment] Reset");
    drv.reset();
  endtask

  // Tum bilesenleri calistir
  task run();
    $display("[Environment] Calistiriliyor...\n");

    fork
      gen.run();
      drv.run();
      mon.run();
      scb.run();
    join_any

    // Generator bitene kadar bekle
    wait(gen.done.triggered);
    // Mailbox'taki transactionların gönderildiğinden emin ol. 
    wait(gen2drv_mbx.num() == 0);
    
    // Son transaction'ın gittiği garanti altına almak için bir süre daha bekleyelim
    #100;
  endtask

  // Rapor
  function void report();
    $display("\n[Environment] Final Rapor");
    $display("  Generator : %0d uretildi", gen.num_transactions);
    $display("  Driver    : %0d suruldu", drv.driven_count);
    $display("  Monitor   : %0d izlendi", mon.monitored_count);
    scb.report();
    cov.report();
  endfunction
endclass

Kodun Açıklaması

  • Bileşen üyeleri: gen, drv, mon, scb, cov referansları tüm doğrulama bileşenlerini tutar.
  • Mailbox üyeleri: gen2drv_mbx, drv2scb_mbx, mon2scb_mbx bileşenler arası veri kanallarıdır.
  • Virtual interface'ler: drv_vif ve mon_vif, driver ve monitor'ün DUT'a bağlanmasını sağlar; yapıcıda dışarıdan alınır.
  • build(): Önce üç mailbox new() ile oluşturulur. Ardından bileşenler doğru bağlantılarla kurulur: drv hem gen2drv_mbx'ten okur hem drv2scb_mbx'e yazar, mon mon2scb_mbx'e yazar, scb her iki giriş mailbox'ını alır.
  • reset(): Driver'ın reset() task'ını çağırarak DUT'u başlangıç durumuna getirir.
  • run(): fork ... join_any ile dört bileşeni paralel başlatır. Sonra wait(gen.done.triggered) ile üretim bitişini, wait(gen2drv_mbx.num() == 0) ile kuyruğun boşalmasını bekler; #100 ile son transaction'ın işlenmesine zaman tanır.
  • report(): Generator/driver/monitor sayaçlarını basar, ardından scb.report() ve cov.report() ile detaylı raporları tetikler.

Önemli Noktalar

  • Bağlantı (connection) tek noktadan yapılır: Mailbox eşleştirmelerinin tamamı build() içindedir; bu, hata ayıklamayı ve bakımı kolaylaştırır.
  • join_any kullanımı bilinçlidir: Bileşenlerin çoğu sonsuz döngüdür; tümünün bitmesini beklemek (join) yerine, generator bitince kontrol akışı devam eder.
  • wait(gen.done.triggered) + wait(num()==0) + #100 üçlüsü, son işlemlerin kaybolmadan tamamlanmasını garanti eden bir "boşaltma" (drain) mekanizmasıdır.
  • cov hem environment hem scoreboard içinde görünür; bu derste fonksiyonel örnekleme scoreboard'daki cov üzerinden yapılır, environment'taki cov ise raporlama için kullanılır. Bu ayrımı bilmek karışıklığı önler.
  • Virtual interface'lerin dışarıdan enjekte edilmesi, aynı environment'ın farklı top/test yapılarında yeniden kullanılabilmesini sağlar.