EDA Playground'da Dene

wait(event.triggered) ve @(event) Karşılaştırması

Gün 4: Süreçler Arası İletişim (IPC) | Olay tetikleme (->), bekleme (@, wait) ve senkronizasyon

Özellikle karmaşık doğrulama ortamlarında (örneğin UVM tabanlı bir VIP geliştirirken veya katı standartlara tabi projelerin testbench'lerinde), simülatörün delta döngüleri (delta cycles) üzerinde tam kontrolümüz yoktur. Farklı bileşenlerin (sequence, monitor, scoreboard vb.) aynı zaman adımında (time step) hangi sırayla çalışacağı belirsizdir (non-deterministic). Bu belirsizlik, @(event) kullanıldığında "race condition" (yarış durumu) yaratır ve simülasyonların nedensiz yere kilitlenmesine (hang) yol açar.

Altın Kural:

  • State / Durum Kontrolü: "Bu olay oldu mu? (Olduysa devam et, geride kalmayayım)" mantığı varsa -> wait(event.triggered)
  • Zamanlama / Gecikme: "Bir sonraki tetiklemeye kadar (örneğin sonraki clock cycle) dur ve kesinlikle bekle" mantığı varsa -> @(event)

UVM mimarisinde daha gelişmiş componentler arası haberleşme için standart SystemVerilog event'leri yerine uvm_event ve uvm_event_pool kullanımı da çok yaygındır. Bu konuya da ilerideki derslerde değineceğiz.

Kaynak Kod

module wait_triggered_usage;
  event sync_event;

  initial begin
    #10;
    
    // Önce event'i tetikleyelim
    $display("[%0t] Triggering the event.", $time);
    -> sync_event;

    // wait(.triggered), event aynı time step'te tetiklense bile çalışır 
    wait(sync_event.triggered);
    $display("[%0t] wait(sync_event.triggered) caught the event successfully.", $time);

    -> sync_event;
    
    // NOT:Bir de bunu dene, Line 15'i yoruma al:
    /*fork
      begin
        #5;
        $display("[%0t] Parallel thread: Triggering the event again.", $time);
        -> sync_event;
      end
    join_none*/

    $display("[%0t] Now waiting with @(sync_event).", $time);
    @(sync_event);
    
    // Bu satırı göremezsin. Çünkü aynı thread'de aynı time slotta event'i
    // tetikledin ve bekledin. @ operatoru thread'i blokladı.
    // Yukarıdaki fork join_none'ı denediğinde paralel thread'de tetiklemiş oldun
    $display("[%0t] @(sync_event) caught the second trigger successfully!", $time);
  end

endmodule