🚀 TLM Socket Nedir?#
UVM (Universal Verification Methodology) ortamlarında Transaction Level Modeling (TLM), bileşenler arasında veri transferini sağlayan güçlü bir yapıdır. TLM 2.0 ile birlikte, port/export mekanizmasının yerini socket yapısı almıştır.
📌 TLM Socket’in Temel Özellikleri#
🔹 Bağlantı: TLM 1.0’da port/export kullanılırken, TLM 2.0’da socket kullanılarak komponentler birbirine bağlanır. 🔹 Çift Yönlü İletişim: Socket yapısı, forward ve backward yönlerde veri akışını destekler. 🔹 Roller:
- Initiator: Transaction başlatır.
- Target: Transaction’ı alır.
- Initiator socket yalnızca target socket’e bağlanabilir.
✨ Passthrough ve Terminator Socket#
✅ Passthrough Socket: Hiyerarşi sınırlarını aşarak socket bağlantılarını yukarı seviyelere taşır. ✅ Terminator Socket: Bağlantıyı uç noktada sonlandırmak veya interconnect bileşenlerinde kullanılabilir.
📦 Socket Kullanımının Avantajları#
- Çift yönlü (initiator → target ve target → initiator) iletişim sağlar.
- Port/export eşleştirme karmaşıklığını ortadan kaldırır.
- Port/export/imp yapısını içeride otomatik olarak kullanır ve soyutlar.
- Hiyerarşik tasarımlar için daha kolay entegrasyon sunar.
- Blocking veya non-blocking interface desteğiyle esnek veri transferi sağlar.
🛠️ Socket Tipleri#
uvm_tlm_b_initiator_socket
uvm_tlm_b_target_socket
uvm_tlm_nb_initiator_socket
uvm_tlm_nb_target_socket
uvm_tlm_b_passthrough_initiator_socket
uvm_tlm_b_passthrough_target_socket
uvm_tlm_nb_passthrough_initiator_socket
uvm_tlm_nb_passthrough_target_socket
package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
// Master (Initiator)
class my_master extends uvm_component;
uvm_tlm_b_initiator_socket #(uvm_tlm_generic_payload) initiator_socket;
`uvm_component_utils(my_master)
function new(string name = "my_master", uvm_component parent = null);
super.new(name, parent);
initiator_socket = new("initiator_socket", this);
endfunction
task run_phase(uvm_phase phase);
// TLM 2.0 generic payload (standard transaction container)
uvm_tlm_generic_payload trans;
// UVM TLM time object (simülasyon zamanı için kullanılır)
uvm_tlm_time delay;
byte unsigned data[];
int i;
delay = new();
phase.raise_objection(this);
for (i = 0; i < 5; i++) begin
trans = uvm_tlm_generic_payload::type_id::create("trans");
data = new[4]; // Dynamic array!
data[0] = 0; data[1] = 0; data[2] = 0; data[3] = i[7:0]; // Last byte holds i
trans.set_data(data);
`uvm_info("MASTER", $sformatf("Sending data: %0d", i), UVM_LOW)
initiator_socket.b_transport(trans, delay);
#100;
end
phase.drop_objection(this);
endtask
endclass
// Slave (Target)
class my_slave extends uvm_component;
uvm_tlm_b_target_socket #(my_slave, uvm_tlm_generic_payload) target_socket;
`uvm_component_utils(my_slave)
function new(string name = "my_slave", uvm_component parent = null);
super.new(name, parent);
target_socket = new("target_socket", this);
endfunction
task b_transport(uvm_tlm_generic_payload trans, uvm_tlm_time delay);
byte unsigned data[];
int val;
trans.get_data(data);
val = data[3]; // Last byte holds i
`uvm_info("SLAVE", $sformatf("Received data: %0d", val), UVM_LOW)
#50; // Simulated delay
endtask
endclass
// Environment
class my_env extends uvm_env;
my_master master;
my_slave slave;
`uvm_component_utils(my_env)
function new(string name = "my_env", uvm_component parent = null);
super.new(name, parent);
master = my_master::type_id::create("master", this);
slave = my_slave::type_id::create("slave", this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
master.initiator_socket.connect(slave.target_socket);
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
// Top module
module top;
import uvm_pkg::*;
import my_pkg::*;
initial begin
uvm_top.enable_print_topology = 1;
run_test("my_test");
end
endmodule