EDA Playground'da Dene

Monitor Modülü

Gün 7: Bitirme Projesi - Bölüm 2 | DUT çıkışlarını izleyen ve paketleyen modül

Monitor (izleyici), DUT'un arayüzündeki sinyal hareketlerini gözleyip tekrar transaction nesnelerine paketleyen pasif bileşendir. ALU mimarimizde driver'ın tersi yönde çalışır: pin seviyesinden transaction seviyesine geçiş yapar ve sonucu scoreboard'a iletir.

Monitor ve Mimarideki Yeri

Monitor doğrulamanın "gözüdür". Görevi yalnızca izlemektir; DUT'a hiçbir sinyal sürmez. Bu yüzden virtual alu_if.monitor modport'unu kullanır ki bu modport'ta tüm sinyaller input'tur.

İletişim akışı şöyledir:

  • Monitor, vif.mon_cb clocking block'unu her saat kenarında örnekler.
  • out_valid yüksek olduğunda DUT geçerli bir sonuç üretmiş demektir.
  • Bu anda gözlenen giriş ve çıkış değerleri yeni bir ALU_Transaction'a paketlenir ve mon2scb mailbox'ı ile scoreboard'a gönderilir.

Neden Ayrı Bir Monitor?

Driver "ne uyguladığımızı" bilirken, monitor "DUT'un gerçekte ne yaptığını" bağımsızca gözler. Scoreboard bu iki bağımsız kaynağı (driver kopyası vs. monitor gözlemi) karşılaştırarak DUT'un doğruluğunu test eder. İzlemenin sürüşten ayrılması, doğrulamanın güvenilirliğini artırır.

Kaynak Kod

// =============================================================================
// GUN 7 - Konu 1: Monitor - Arayuzdeki Hareketleri Izleyen Modul
// =============================================================================

class ALU_Monitor;
  virtual alu_if.monitor vif;
  mailbox #(ALU_Transaction) mon2scb;
  int monitored_count = 0;

  function new(virtual alu_if.monitor vif, mailbox #(ALU_Transaction) mbx);
    this.vif     = vif;
    this.mon2scb = mbx;
  endfunction

  task run();
    ALU_Transaction txn;
    $display("[Monitor] Baslatildi - DUT cikislari izleniyor");

    forever begin
      @(vif.mon_cb);
      if (vif.mon_cb.out_valid) begin
        txn = new();
        txn.operand_a = vif.mon_cb.operand_a;
        txn.operand_b = vif.mon_cb.operand_b;
        txn.opcode    = ALU_Transaction::opcode_e'(vif.mon_cb.opcode);
        txn.result    = vif.mon_cb.result;
        txn.flags     = vif.mon_cb.flags;
        txn.out_valid = 1;
        
        mon2scb.put(txn);
        monitored_count++;
      end
    end
  endtask
endclass

Kodun Açıklaması

  • Üyeler: virtual alu_if.monitor vif salt-okuma erişim sağlar; mon2scb gözlenen transaction'ları scoreboard'a taşır; monitored_count izlenen işlem sayısını tutar.
  • new(...): Virtual interface ve mailbox'ı dışarıdan alır.
  • run(): Sonsuz döngüde her @(vif.mon_cb) saat kenarında örnek alır.
  • if (vif.mon_cb.out_valid): Yalnızca DUT geçerli bir çıkış işaretlediğinde paketleme yapılır; geçersiz çevrimler atlanır.
  • Transaction paketleme: Gözlenen operand_a, operand_b, opcode, result, flags değerleri yeni bir txn'e kopyalanır. opcode, ALU_Transaction::opcode_e'(...) ile enum tipine dönüştürülür. out_valid alanı 1 olarak işaretlenir.
  • mon2scb.put(txn) ve monitored_count++: Paketlenen transaction scoreboard'a gönderilir ve sayaç artırılır.

Önemli Noktalar

  • Monitor tamamen pasiftir; mon_cb modport'u sayesinde hiçbir sinyale yazamaz, bu da yanlışlıkla DUT'u uyarmayı imkânsız kılar.
  • out_valid filtresi kritiktir: Yalnızca geçerli çevrimleri toplamak, scoreboard'da driver ile monitor akışlarının hizalı kalmasını sağlar.
  • opcode enum dönüşümü (opcode_e'(...)) yapılmadan ham logic değer scoreboard'da name() gibi enum metotlarıyla doğru yorumlanamaz.
  • DUT'un bir çevrimlik pipeline gecikmesi monitorün doğru zamanda örnekleme yapmasını gerektirir; clocking block bu hizalamayı otomatik sağlar.
  • run() sonsuz döngüdür; durması environment'ın yaşam döngüsü yönetimine bırakılmıştır.