🚀 Giriş#
Bu sayfada, UVM TLM ortamında TLM FIFO, Analysis Port ve _decl makrosunun nasıl kullanıldığı anlatılmaktadır. Bu yapı taşları, testbench tasarımında veri transferini kolaylaştırır ve modülerliği artırır.
1️⃣ TLM FIFO Kullanımı#
📌 Nedir?#
uvm_tlm_fifo
, UVM’de transaction’ların sıralı olarak tutulmasını sağlar.- Blocking ve non-blocking interface’leri destekler.
📌 Avantajları#
✅ FIFO kullanarak producer/consumer bağımsızlığı sağlanır.
✅ Veri kaybı olmadan asenkron veri akışı yapılabilir.
📦 Örnek Kullanım#
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
// Producer
class my_producer extends uvm_component;
uvm_tlm_fifo #(my_transaction) fifo;
`uvm_component_utils(my_producer)
function new(string name = "my_producer", uvm_component parent = null);
super.new(name, parent);
fifo = new("fifo", this);
endfunction
task run_phase(uvm_phase phase);
my_transaction tr;
phase.raise_objection(this);
for (int i = 0; i < 5; i++) begin
tr = my_transaction::type_id::create("tr");
assert(tr.randomize()) else `uvm_error("PRODUCER", "Failed to randomize transaction")
`uvm_info("PRODUCER", $sformatf("Sending data: %0d", tr.data), UVM_LOW)
fifo.put(tr); // Blocking put
#100; // Simüle edilen gecikme
end
phase.drop_objection(this);
endtask
endclass
// Consumer
class my_consumer extends uvm_component;
uvm_tlm_fifo #(my_transaction) fifo;
`uvm_component_utils(my_consumer)
function new(string name = "my_consumer", uvm_component parent = null);
super.new(name, parent);
fifo = new("fifo", this);
endfunction
task run_phase(uvm_phase phase);
my_transaction tr;
phase.raise_objection(this);
repeat (5) begin
fifo.get(tr);
`uvm_info("CONSUMER", $sformatf("Received data: %0d", tr.data), UVM_LOW)
#50;
end
phase.drop_objection(this);
endtask
endclass
// Testbench
class my_env extends uvm_env;
my_producer producer;
my_consumer consumer;
uvm_tlm_fifo #(my_transaction) shared_fifo;
`uvm_component_utils(my_env)
function new(string name = "my_env", uvm_component parent = null);
super.new(name, parent);
shared_fifo = new("shared_fifo", this);
producer = my_producer::type_id::create("producer", this);
consumer = my_consumer::type_id::create("consumer", this);
producer.fifo = shared_fifo; // Producer'ın FIFO'sunu paylaş
consumer.fifo = shared_fifo; // Consumer'ın FIFO'sunu paylaş
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
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
📌 Not#
- FIFO, blocking port’larla kullanıldığında senkron veri transferi sağlanır.
- Non-blocking metodlar: try_put(), can_put(), try_get(), can_get().
2️⃣ Analysis Port Kullanımı#
📌 Nedir?#
- Analysis port, birden fazla alıcıya (subscriber) aynı anda veri göndermek için kullanılır.
write()
metodu ile veri yayını yapılır.
📌 Avantajları#
✅ Broadcast yapısı ile coverage veya scoreboard gibi yapılar kolayca bağlanabilir. ✅ Non-blocking çalışır.
📦 Örnek Kullanım#
package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
// Transaction sınıfı
class my_transaction extends uvm_sequence_item;
int data;
`uvm_object_utils(my_transaction)
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass
// Producer
class my_producer extends uvm_component;
uvm_analysis_port #(my_transaction) analysis_port;
`uvm_component_utils(my_producer)
function new(string name = "my_producer", uvm_component parent = null);
super.new(name, parent);
analysis_port = new("analysis_port", this);
endfunction
task run_phase(uvm_phase phase);
my_transaction tr;
phase.raise_objection(this);
for (int i = 0; i < 5; i++) begin
tr = my_transaction::type_id::create("tr");
tr.data = i;
`uvm_info("PRODUCER", $sformatf("Sending data: %0d", tr.data), UVM_LOW)
analysis_port.write(tr); // Analysis port üzerinden yayın
#100; // Simüle edilen gecikme
end
phase.drop_objection(this);
endtask
endclass
// Subscriber 1
class my_subscriber1 extends uvm_subscriber #(my_transaction);
`uvm_component_utils(my_subscriber1)
function new(string name = "my_subscriber1", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void write(my_transaction t);
`uvm_info("SUBSCRIBER1", $sformatf("Received data: %0d", t.data), UVM_LOW)
endfunction
endclass
// Subscriber 2
class my_subscriber2 extends uvm_subscriber #(my_transaction);
`uvm_component_utils(my_subscriber2)
function new(string name = "my_subscriber2", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void write(my_transaction t);
`uvm_info("SUBSCRIBER2", $sformatf("Received data: %0d", t.data), UVM_LOW)
endfunction
endclass
// Testbench
class my_env extends uvm_env;
my_producer producer;
my_subscriber1 subscriber1;
my_subscriber2 subscriber2;
`uvm_component_utils(my_env)
function new(string name = "my_env", uvm_component parent = null);
super.new(name, parent);
producer = my_producer::type_id::create("producer", this);
subscriber1 = my_subscriber1::type_id::create("subscriber1", this);
subscriber2 = my_subscriber2::type_id::create("subscriber2", this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
producer.analysis_port.connect(subscriber1.analysis_export);
producer.analysis_port.connect(subscriber2.analysis_export);
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
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