Ana içeriğe geç

UVM'de Blocking ve Non-blocking Put/Get Port Kullanımı

· loading · loading · ·
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Blocking Port Non-Blocking Port TLM
Eğitim UVM Doğrulama
Axolot Logic
Yazar
Axolot Logic
Sayısal Tasarım Mühendisi
Table of Contents
UVM Serisi - This article is part of a series.
Part 27: This Article

🚀 Giriş
#

Bu sayfada UVM TLM’de Blocking ve Non-blocking put/get portlarının kullanımı ile port-export-imp topolojisi anlatılmaktadır. Ayrıca, her port tipi için gönderici (driver) ve alıcı (monitor) taraflarının hangi metodları implemente etmesi gerektiğine de değinilecektir.


1️⃣ Blocking Put Kullanımı
#

📌 Açıklama
#

  • Blocking put port, veriyi gönderirken gönderici tarafı bloke eder ve alıcı tarafından işlem tamamlanana kadar bekler.
  • put() metodu, sender tarafından çağrılır ve receiver tarafından implement edilir.

📌 Gönderici
#

  • uvm_blocking_put_port kullanır.
  • put() metodunu çağırır.

📌 Alıcı
#

  • uvm_blocking_put_imp kullanır.
  • put() metodunu implement eder.

📦 Örnek
#

import uvm_pkg::*;
`include "uvm_macros.svh"

// Transaction Class
class my_transaction extends uvm_sequence_item;
  rand int data;
  `uvm_object_utils(my_transaction)
  function new(string name = "my_transaction");
    super.new(name);
  endfunction
  function string convert2string();
    return $sformatf("data = %0d", data);
  endfunction
endclass

// Driver
class my_driver extends uvm_driver #(my_transaction);
  `uvm_component_utils(my_driver)
  uvm_blocking_put_port #(my_transaction) put_port;
  function new(string name, uvm_component parent);
    super.new(name, parent);
    put_port = new("put_port", this);
  endfunction
  task run_phase(uvm_phase phase);
    my_transaction tr;
    phase.raise_objection(this);
    tr = my_transaction::type_id::create("tr");
    assert(tr.randomize() with { data inside {[1:100]}; });
    `uvm_info("DRV", $sformatf("Sending: %s", tr.convert2string()), UVM_LOW)
    put_port.put(tr);
    phase.drop_objection(this);
  endtask
endclass

// Monitor
class my_monitor extends uvm_component;
  `uvm_component_utils(my_monitor)
  uvm_blocking_put_imp #(my_transaction, my_monitor) put_imp;
  function new(string name, uvm_component parent);
    super.new(name, parent);
    put_imp = new("put_imp", this);
  endfunction
  task put(my_transaction tr);
    `uvm_info("MON", $sformatf("Received: %s", tr.convert2string()), UVM_LOW)
  endtask
endclass

2️⃣ Non-blocking Put Kullanımı
#

📌 Açıklama
#

  • Non-blocking put port, veriyi gönderirken receiver hazır olup olmadığını kontrol eder ve anında cevap döner.
  • try_put() ve can_put() metodları kullanılır.

📌 Gönderici
#

  • uvm_nonblocking_put_port kullanır.
  • try_put() metodunu çağırır.

📌 Alıcı
#

  • uvm_nonblocking_put_imp kullanır.
  • try_put() ve can_put() metodlarını implement eder.

📦 Kod Örneği
#



package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
  // Transaction sınıfı
  class my_transaction extends uvm_sequence_item;
    rand int data;

    `uvm_object_utils(my_transaction) // type_id için gerekli

    function new(string name = "my_transaction");
      super.new(name);
    endfunction
  endclass

  // Alıcı (Consumer)
class my_consumer extends uvm_component;
  uvm_nonblocking_put_imp #(my_transaction, my_consumer) put_imp;

  `uvm_component_utils(my_consumer)

  function new(string name = "my_consumer", uvm_component parent = null);
    super.new(name, parent);
    put_imp = new("put_imp", this);
  endfunction

  // try_put() implementasyonu
  function bit try_put(my_transaction tr); // 'from' parametresi eklendi
    if (can_put()) begin
      `uvm_info("CONSUMER", $sformatf("Received data: %0d", tr.data), UVM_LOW)
      return 1; // Başarılı
    end
    return 0; // Başarısız
  endfunction

  // can_put() implementasyonu
function bit can_put();
  return 1; // Her zaman hazır
endfunction

endclass


  // Gönderici (Producer)
  class my_producer extends uvm_component;
    uvm_nonblocking_put_port #(my_transaction) put_port;

    `uvm_component_utils(my_producer) // type_id için gerekli

    function new(string name = "my_producer", uvm_component parent = null);
      super.new(name, parent);
      put_port = new("put_port", this);
    endfunction

    task send_data(int data);
      my_transaction tr;
      tr = my_transaction::type_id::create("tr"); // Doğru kullanım
      tr.data = data;

      if (put_port.try_put(tr)) begin
        `uvm_info("PRODUCER", $sformatf("Sent data: %0d", data), UVM_LOW)
      end else begin
        `uvm_warning("PRODUCER", "Failed to send data")
      end
    endtask
  endclass

  // Testbench
  class my_env extends uvm_env;
    my_producer producer;
    my_consumer consumer;

    `uvm_component_utils(my_env) // type_id için gerekli

    function new(string name = "my_env", uvm_component parent = null);
      super.new(name, parent);
      producer = my_producer::type_id::create("producer", this);
      consumer = my_consumer::type_id::create("consumer", this);
      producer.put_port.connect(consumer.put_imp);
    endfunction
  endclass

  // Test
  class my_test extends uvm_test;
  my_env env;

  `uvm_component_utils(my_test)

  function new(string name = "my_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env = my_env::type_id::create("env", this);
  endfunction

  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    #100;
    env.producer.send_data(42);
    #100;
    phase.drop_objection(this);
  endtask
endclass


endpackage

// Test çalıştırma
module top;
  import uvm_pkg::*;
  import my_pkg::*; // Paketi dahil et

  initial begin
    uvm_top.enable_print_topology = 1;
    run_test("my_test");
  end
endmodule

3️⃣ Blocking Get Kullanımı
#

📌 Açıklama
#

  • Blocking get port, veri almak isteyen bileşen tarafından çağrılır ve sender tarafından implement edilir.
  • get() metodu, receiver tarafından çağrılır ve sender tarafından implement edilir.

📌 Gönderici
#

  • uvm_blocking_get_imp kullanır.
  • get() metodunu implement eder.

📌 Alıcı
#

  • uvm_blocking_get_port kullanır.
  • get() metodunu çağırır.

📦 Kod Örneği
#

package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
  // Transaction sınıfı
  class my_transaction extends uvm_sequence_item;
    rand int data;

    `uvm_object_utils(my_transaction)

    function new(string name = "my_transaction");
      super.new(name);
    endfunction
  endclass

  // Gönderici (Sender)
  class my_sender extends uvm_component;
    uvm_blocking_get_imp #(my_transaction, my_sender) get_imp;

    `uvm_component_utils(my_sender)

    function new(string name = "my_sender", uvm_component parent = null);
      super.new(name, parent);
      get_imp = new("get_imp", this);
    endfunction

    // get() implementasyonu
    virtual task get(output my_transaction tr);
      tr = my_transaction::type_id::create("tr");
      assert(tr.randomize()) else `uvm_error("SENDER", "Failed to randomize transaction")
      `uvm_info("SENDER", $sformatf("Sent data: %0d", tr.data), UVM_LOW)
    endtask
  endclass

  // Alıcı (Receiver)
  class my_receiver extends uvm_component;
    uvm_blocking_get_port #(my_transaction) get_port;

    `uvm_component_utils(my_receiver)

    function new(string name = "my_receiver", uvm_component parent = null);
      super.new(name, parent);
      get_port = new("get_port", this);
    endfunction

    task receive_data();
      my_transaction tr;
      get_port.get(tr); // Blocking get çağrısı
      `uvm_info("RECEIVER", $sformatf("Received data: %0d", tr.data), UVM_LOW)
    endtask
  endclass

  // Testbench
  class my_env extends uvm_env;
    my_sender sender;
    my_receiver receiver;

    `uvm_component_utils(my_env)

    function new(string name = "my_env", uvm_component parent = null);
      super.new(name, parent);
      sender = my_sender::type_id::create("sender", this);
      receiver = my_receiver::type_id::create("receiver", this);
      receiver.get_port.connect(sender.get_imp); // Portları bağla
    endfunction
  endclass

  // Test
  class my_test extends uvm_test;
    my_env env;

    `uvm_component_utils(my_test)

    function new(string name = "my_test", uvm_component parent = null);
      super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      env = my_env::type_id::create("env", this);
    endfunction

    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      #100; // Örnek veri alma
      env.receiver.receive_data();
      #100;
      phase.drop_objection(this);
    endtask
  endclass


endpackage

// Test çalıştırma
module top;
  import uvm_pkg::*;
  import my_pkg::*;

  initial begin
    uvm_top.enable_print_topology = 1;
    run_test("my_test");
  end
endmodule

4️⃣ Non-blocking Get Kullanımı
#

📌 Açıklama
#

  • Non-blocking get port, veri almak isteyen bileşen tarafından try_get() veya can_get() ile çağrılır.
  • Sender, try_get() ve can_get() metodlarını implement eder.

📌 Gönderici
#

  • uvm_nonblocking_get_imp kullanır.
  • try_get() ve can_get() metodlarını implement eder.

📌 Alıcı
#

  • uvm_nonblocking_get_port kullanır.
  • try_get() veya can_get() metodlarını çağırır.

📦 Kod Örneği
#

package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
  // Transaction sınıfı
  class my_transaction extends uvm_sequence_item;
    rand int data;

    `uvm_object_utils(my_transaction)

    function new(string name = "my_transaction");
      super.new(name);
    endfunction
  endclass

  // Gönderici (Sender)
  class my_sender extends uvm_component;
    uvm_nonblocking_get_imp #(my_transaction, my_sender) get_imp;
    my_transaction available_tr; // Mevcut transaction

    `uvm_component_utils(my_sender)

    function new(string name = "my_sender", uvm_component parent = null);
      super.new(name, parent);
      get_imp = new("get_imp", this);
    endfunction

    // try_get() implementasyonu
// try_get() implementasyonu
function bit try_get(output my_transaction tr);
  if (can_get()) begin
    tr = available_tr;
    available_tr = null; // Transaction'ı teslim ettik
    `uvm_info("SENDER", $sformatf("Sent data: %0d", tr.data), UVM_LOW)
    return 1; // Başarılı
  end
  return 0; // Başarısız
endfunction

// can_get() implementasyonu
function bit can_get();
  return (available_tr != null); // Transaction mevcut mu?
endfunction


    // Transaction hazırlama
    task prepare_transaction();
      available_tr = my_transaction::type_id::create("tr");
      assert(available_tr.randomize()) else `uvm_error("SENDER", "Failed to randomize transaction")
      `uvm_info("SENDER", $sformatf("Prepared data: %0d", available_tr.data), UVM_LOW)
    endtask
  endclass

  // Alıcı (Receiver)
  class my_receiver extends uvm_component;
    uvm_nonblocking_get_port #(my_transaction) get_port;

    `uvm_component_utils(my_receiver)

    function new(string name = "my_receiver", uvm_component parent = null);
      super.new(name, parent);
      get_port = new("get_port", this);
    endfunction

    task receive_data();
      my_transaction tr;
      if (get_port.can_get()) begin // Transaction mevcut mu kontrol et
        if (get_port.try_get(tr)) begin // Non-blocking get çağrısı
          `uvm_info("RECEIVER", $sformatf("Received data: %0d", tr.data), UVM_LOW)
        end else begin
          `uvm_warning("RECEIVER", "Failed to get data")
        end
      end else begin
        `uvm_info("RECEIVER", "No data available", UVM_LOW)
      end
    endtask
  endclass

  // Testbench
  class my_env extends uvm_env;
    my_sender sender;
    my_receiver receiver;

    `uvm_component_utils(my_env)

    function new(string name = "my_env", uvm_component parent = null);
      super.new(name, parent);
      sender = my_sender::type_id::create("sender", this);
      receiver = my_receiver::type_id::create("receiver", this);
      receiver.get_port.connect(sender.get_imp); // Portları bağla
    endfunction

    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      sender.prepare_transaction(); // Transaction hazırla
      #100;
      receiver.receive_data(); // Veri al
      #100;
      phase.drop_objection(this);
    endtask
  endclass

  // Test
  class my_test extends uvm_test;
    my_env env;

    `uvm_component_utils(my_test)

    function new(string name = "my_test", uvm_component parent = null);
      super.new(name, parent);
    endfunction

    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      env = my_env::type_id::create("env", this);
    endfunction
  endclass

endpackage

// Test çalıştırma
module top;
  import uvm_pkg::*;
  import my_pkg::*;

  initial begin
    uvm_top.enable_print_topology = 1;
    run_test("my_test");
  end
endmodule

5️⃣ Port-Export-Imp Topolojisi
#

📌 Açıklama
#

  • Port: Transaction başlatan bileşende tanımlanır.
  • Export: Port ile imp arasında köprü görevi görür.
  • Imp: Transaction’ı sonlandıran bileşende implement edilir.

📦 Bağlantı Örneği
#

// Bağlantı Topolojisi
driver.put_port.connect(env.put_export);
env.put_export.connect(monitor.put_imp);

📌 İpuçları
#

  • Port doğrudan imp’e de bağlanabilir.
  • Export, hiyerarşik yapılarda portu alt bileşenlerden almak için kullanılır.
  • Imp, her zaman receiver bileşeninde implement edilir.

UVM Serisi - This article is part of a series.
Part 27: This Article

Related

UVM'de Transaction-Level Modeling (TLM) Nedir?
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog TLM Veri İletişimi
Eğitim UVM Doğrulama
UVM'de uvm_env Kullanımı ve adder_env Örneği
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Uvm_env Testbench Yapısı
Eğitim UVM Doğrulama
UVM Temel Sınıfları
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Sınıf Hiyerarşisi
Eğitim UVM Doğrulama
UVM Utility Field Makroları
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Utility Makroları
Eğitim UVM Doğrulama
UVM'de Factory Kullanımı
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Factory Pattern
Eğitim UVM Doğrulama
UVM'de Konfigürasyon Sınıfları Kullanımı
· loading · loading
Eğitim UVM Doğrulama UVM Doğrulama SystemVerilog Konfigürasyon Sınıfları Randomizasyon
Eğitim UVM Doğrulama