Skip to main content

Using TLM Sockets in UVM with Example Code

· loading · loading · ·
Education UVM Verification UVM Verification SystemVerilog TLM Socket Transaction Level Modeling
Education UVM Verification
Axolot Logic
Author
Axolot Logic
Digital Design Engineer
Table of Contents
UVM Series - This article is part of a series.
Part 30: This Article

🚀 What is a TLM Socket?
#

In UVM (Universal Verification Methodology) environments, Transaction Level Modeling (TLM) provides a robust framework for data transfer between components. With TLM 2.0, the socket structure has replaced the traditional port/export mechanism.


📌 Key Features of a TLM Socket
#

🔹 Connectivity: In TLM 1.0, port/export was used; in TLM 2.0, sockets are used to connect components. 🔹 Bidirectional Communication: The socket structure supports data flow in both forward and backward directions. 🔹 Roles:

  • Initiator: Starts transactions.
  • Target: Receives transactions.
  • An initiator socket can only connect to a target socket.

✨ Passthrough and Terminator Sockets
#

Passthrough Socket: Allows socket connections to cross hierarchical boundaries. ✅ Terminator Socket: Can terminate the connection at an endpoint or be used in interconnect components.


📦 Advantages of Using Sockets
#

  • Provides bidirectional communication (initiator → target and target → initiator).
  • Eliminates the complexity of port/export binding.
  • Automatically implements the port/export/imp structure internally and abstracts it.
  • Easier integration in hierarchical designs.
  • Offers flexible data transfer with support for both blocking and non-blocking interfaces.

🛠️ Socket Types
#

  • 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

UVM Series - This article is part of a series.
Part 30: This Article

Related

Getting Started with UVM: Setup and Supported Simulators
· loading · loading
Education UVM Verification UVM Verification SystemVerilog Simulation
Education UVM Verification
Introduction to UVM
· loading · loading
Education UVM Verification UVM Verification SystemVerilog
Education UVM Verification
UVM Agent Usage and Adder Example
· loading · loading
Education UVM Verification UVM Verification SystemVerilog Uvm_agent Testbench Structure
Education UVM Verification
UVM Base Classes
· loading · loading
Education UVM Verification UVM Verification SystemVerilog Class Hierarchy
Education UVM Verification
UVM Driver Usage and Adder Example
· loading · loading
Education UVM Verification UVM Verification SystemVerilog Uvm_driver Stimulus Driving
Education UVM Verification
UVM Environment Usage and adder_env Example
· loading · loading
Education UVM Verification UVM Verification SystemVerilog Uvm_env Testbench Structure
Education UVM Verification

comments powered by Disqus