UVM TLM Export

TLM Export

  • The TLM Export is a port that forwards a transaction from a child component to its parent
  • The TLM Export has unidirectional and bidirectional ports
  • An export can be connected to any compatible child export or imp port. It must ultimately be connected to at least one implementation of its associated interface

TLM Export Classes

uvm_*_export#(T)        //unidirectional export class
uvm_*_export #(REQ,RSP) //bidirectional export class

Type parameters,

  • T       – The type of transaction to be communicated by the export
  • REQ – The type of request transaction to be communicated by the export
  • RSP  – The type of response transaction to be communicated by the export

Export Methods

new

This is a constructor method used for the creation of TLM Export.

function new (string name,
              uvm_component parent,
              int min_size=1,
              int max_size=1);

The name and parent are the standard uvm_component constructor arguments.

Summary of TLM Exports

TLM Exports
TLM Exports

Next Section: TLM Port

For TLM Examples refer to TLM Examples
❮ Previous Next ❯

UVM Basic TLM Communication

TLM Communication

TLM is used for communication among the components. The most basic TLM operation allows one component to sends a transaction packet to another component.

Let’s consider the two components producer and consumer, where the producer generates and sends the transaction packet to the consumer through TLM ports.

Basic TLM Communication
Basic TLM Communication

The above diagram shows the Producer and Consumer connected via TLM ports.

Symbolic representation of TLM Ports is shown below,

TLM Symbolic Representation
TLM Symbolic Representation

It’s allowed to connect,

  • port-to-imp
  • port-to-port
  • port-to-export
  • export-to-export
  • export-to-imp

In the next section, These connections are explained in detail with an example.
❮ Previous Next ❯

UVM TLM Imp Port

TLM Imp Port

  • The TLM Imp Port is used to receive the transactions at destination
  • TLM Imp Ports has unidirectional and bidirectional ports

TLM Imp Port Classes

uvm_*_imp #(T,IMP)                 //unidirectional Imp port class
uvm_*_imp #(REQ, RSP,
            IMP, REQ_IMP, RSP_IMP) //bidirectional Imp port class

Type parameters,

  • T      – The type of transaction to be communicated by the imp
  • IMP – The type of the component implementing the interface. That is the class to which this imp will delegate.
  • REQ_IMP – The component type that implements the request side of the interface. Defaults to IMP. For master and slave imps only.
  • RSP_IMP – The component type that implements the response side of the interface. Defaults to IMP. For master and slave imps only.

Port Methods

new

This is a constructor method used for the creation of TLM Imp Port.

Transport imp constructor

function new(string name, IMP imp)

Master and slave imp constructor

function new(string name, IMP imp,
             REQ_IMP req_imp=imp, RSP_IMP rsp_imp=imp)

The name and parent are the standard uvm_component constructor arguments.

Summary of TLM Imp ports

TLM Imp Ports
TLM Imp Ports

Next Section: TLM FIFO

For TLM Examples refer to TLM Examples
❮ Previous Next ❯

UVM TLM Port

TLM Port

  • The TLM Port is used to send the transactions
  • TLM Ports has unidirectional and bidirectional ports
  • A port can be connected to any compatible port, export, or imp port

TLM Port Classes

uvm_*_port #(T)          //unidirectional port class
uvm_*_port #(REQ,RSP) //bidirectional port class

Type parameters,

  • T       – The type of transaction to be communicated by the port, type T is not restricted to class handles and may be a value type such as int, enum, struct or similar
  • REQ – The type of request transaction to be communicated by the port
  • RSP  – The type of response transaction to be communicated by the port

Port Methods

new

This is a constructor method used for the creation of TLM Port.

function new (string name,
              uvm_component parent,
              int min_size=1,
              int max_size=1);

The name and parent are the standard uvm_component constructor arguments.

Summary of TLM Ports

TLM Ports
TLM Ports

Next Section: TLM Imp Port

For TLM Examples refer to TLM Examples
❮ Previous Next ❯

UVM TLM Interface

UVM TLM Methods

The TLM Interface class declares all the methods required to perform communication.

put

  • put method is used to send a transaction to another component
  • Calling <port>.put(trans) sends a transaction to other component
  • put() method call is a blocking call. It will not return until the transaction has been successfully sent

get

  • get method is used to retrieve transaction from another component
  • Calling <port>.get(trans) retrieve transaction from other component
  • get() method call is a blocking call. It will not return until the transaction has been successfully retrieved
  • get() method call consumes the transaction. i.e like how FIFO get method will takeout the entry from FIFO
  • Subsequent calls to get must return a different transaction instance. Means as the previous get will takeout the trans, new trans is expected

peek

  • peek method obtain a transaction without consuming it
  • Calling <port>.peek(trans) retrieve transaction from other component
  • peek() method call is a blocking call.
  • The returned transaction is not consumed. A subsequent peek or get will return the same transaction

try_put

  • the try_put method is used to send a transaction to another component without blocking the execution
  • Calling <port>.try_put(trans) sends a transaction to another component, if possible
  • try_put method returns 1 If the component is ready to accept the transaction, otherwise it returns 0

can_put

  • can_put() method call returns 1 if the component is ready to accept the transaction, otherwise, it returns 0
  • no argument must be passed to can_put, this method is used to see whether the other component is ready to accept the trans

try_get

  • the try_get method is used to retrieve transaction from another component without blocking the execution
  • Calling <port>.try_get(trans) retrieve transaction from another component, if possible
  • try_get method returns 1 if the transaction is available, otherwise, it returns 0

can_get

  • can_get() method call returns 1 if the component can get transaction immediately, otherwise, it returns 0
  • no argument must be passed to can_get, this method is used to see whether any transaction is available to get

transport

  • Calling <port>.transport(req,resp) method executes the given request and returns the response in the given output argument
  • The transport method call is blocking, it may block until the operation is complete

nb_transport

  • Calling <port>.nb_transport(req,resp) the method executes the given request and returns the response in the given output argument, if possible
  • If for any reason the operation could not be executed immediately, then a 0 must be returned, otherwise 1

Analysis

Write

  • Calling <port>.write(trans) method will broadcasts a transaction to any number of listeners.
  • Write method call is a nonblocking call

As along with the interface methods, TLM ports are required for the communication between the components, Usage of these methods is described after knowing about ports and exports.

Summary of  UVM TLM Interface

TLM Interfaces
TLM Interfaces

❮ Previous Next ❯

UVM TLM

TLM

Transaction-Level Modeling (TLM) is used for communication among modules. TLM is the concept in which transaction based methods are implemented, these methods can be used for communication between the modules.

UVM TLM

The UVM provides TLM library with transaction-level interfaces, ports, exports, imp ports, and analysis ports. all these TLM elements are required to send a transaction, receive transaction, and transport from one component to another. where each one plays its unique role.

  • TLM Interfaces consists of methods for sending and receiving the transaction
  • All different types of TLM Ports are used like PIPES to connect between the components

The UVM TLM library provides,

  • TLM1 – The TLM1 ports provide blocking and non-blocking pass-by-value transaction-level interfaces.
  • TLM2 – The TLM2 sockets provide blocking and non-blocking transaction-level interfaces with well-defined completion semantics.
  • Sequencer Port – A push or pull port, with well-defined completion semantics.
  • Analysis – The analysis interface is used to perform non-blocking broadcasts of transactions to connected components

Summary of UVM TLM

UVM TLM
UVM TLM

TLM1

UVM TLM provides unidirectional and bidirectional,

  • TLM interfaces
  • ports
  • exports
  • imp ports
  • analysis portss
  • FIFOs

Each TLM interface is either blocking, non-blocking, or a combination of these two.

  • Blocking – Blocking TLM methods call will not return until the transaction has been successfully sent or retrieved
  • Non-blocking – Non-Blocking TLM methods call attempts to convey a transaction without consuming simulation time
  • Combination – A combination interface contains both the blocking and nonblocking variants.

Summary of UVM TLM1

UVM TLM1
UVM TLM1

❮ Previous Next ❯

TLM Port Port Export Export Imp Port Connection

Connecting TLM Port Port Export Export Imp port

Port Port Export Export Imp_port
Port Port Export Export Imp_port

This example shows connecting TLM Port -> Port -> Export -> Export -> Imp_port.

TLM TesetBench Components are,

—————————————————————
Name                Type
—————————————————————
uvm_test_top                   basic_test
env                               environment
comp_a                      component_a
sub_comp_a_a       sub_component_a_a
trans_out              uvm_blocking_put_port
trans_out                uvm_blocking_put_port
comp_b                      component_b
sub_comp_b_a       sub_component_b_a
sub_comp_b_aa   sub_component_b_a
trans_in             uvm_blocking_put_imp
trans_in                uvm_blocking_put_export
trans_in                  uvm_blocking_put_export
—————————————————————

Implement TLM port in sub_comp_a_a

Implementing TLM port in sub_comp_a_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Randomize the transaction class
  4. Send the transaction to the comp_b through put() method
class sub_component_a_a extends uvm_component;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port #(transaction) trans_out;
  
  `uvm_component_utils(sub_component_a_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    trans = transaction::type_id::create("trans", this);
    void'(trans.randomize());  //Step-3. randomizing the transction
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.put(trans);  //Step-4. Sending trans through port put method
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : sub_component_a_a

Implement TLM port in comp_a

Implementing TLM port in comp_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Connect port with sub_comp_a_a port
class component_a extends uvm_component;
  
  sub_component_a_a sub_comp_a_a;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port#(transaction) trans_out; 
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_a_a = sub_component_a_a::type_id::create("sub_comp_a_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    sub_comp_a_a.trans_out.connect(trans_out);  //Step-3. Connecting port with sub_comp_a_a port
  endfunction : connect_phase
endclass : component_a

Implement TLM Imp port in sub_comp_b_aa

Implementing TLM port in sub_comp_b_aa involves below steps,

  1. Declare the uvm_blocking_put_imp
  2. Create the imp port
  3. Connect export with the imp_port of sub_comp_b_aa
class sub_component_b_aa extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring blocking imp port 
  uvm_blocking_put_imp#(transaction,sub_component_b_aa) trans_in; 
  `uvm_component_utils(sub_component_b_aa)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating imp port
  endfunction : new
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  //Step-3. Implementing imp port
  virtual task put(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
  endtask
endclass : sub_component_b_aa

Implement TLM Export in sub_comp_b_a

Implementing TLM port in sub_comp_b_a involves below steps,

  1. Declare the uvm_blocking_put_export
  2. Create the imp port
  3. Implement the put() method to receive the transaction
class sub_component_b_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring blocking imp port 
  uvm_blocking_put_export#(transaction) trans_in; 
  `uvm_component_utils(sub_component_b_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating imp port
  endfunction : new
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  //Step-3. Connecting export with the imp_port of sub_comp_b_aa
  function void connect_phase(uvm_phase phase);
    trans_in.connect(sub_comp_b_aa.trans_in);
  endfunction : connect_phase 
endclass : sub_component_b_a

Implement TLM Export in comp_b

Implementing TLM port in comp_b involves below steps,

  1. Declare the uvm_blocking_put_export
  2. Create the export
  3. Connect export to the export port of sub_comp_b_a
class component_b extends uvm_component;
  
  sub_component_b_a sub_comp_b_a;
  //Step-1. Declaring blocking export
  uvm_blocking_put_export#(transaction) trans_in; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating export
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_b_a = sub_component_b_a::type_id::create("sub_comp_b_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  //Step-3. Connecting export to the Export port of sub_comp_b_a
  function void connect_phase(uvm_phase phase);
    trans_in.connect(sub_comp_b_a.trans_in);
  endfunction : connect_phase
endclass : component_b

Environment code

In the environment file comp_a port is connected with the comp_b export.

function void connect_phase(uvm_phase phase);
  comp_a.trans_out.connect(comp_b.trans_in);  //Connecting port with export
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
-----------------------------------------------------------
Name Type Size Value
-----------------------------------------------------------
uvm_test_top basic_test - @1848
 env environment - @1917
 comp_a component_a - @1949
 sub_comp_a_a sub_component_a_a - @2047
 trans_out uvm_blocking_put_port - @2119
 trans_out uvm_blocking_put_port - @1984
 comp_b component_b - @2017
 sub_comp_b_a sub_component_b_a - @2154
 sub_comp_b_aa sub_component_b_aa - @2184
 trans_in uvm_blocking_put_imp - @2256
 trans_in uvm_blocking_put_export - @2189
 trans_in uvm_blocking_put_export - @2052
-----------------------------------------------------------
UVM_INFO sub_component_a_a.sv(29) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] tranaction randomized
UVM_INFO sub_component_a_a.sv(30) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2304
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------

UVM_INFO sub_component_a_a.sv(32) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Before calling port put method
UVM_INFO sub_component_b_aa.sv(24) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a.sub_comp_b_aa [sub_component_b_aa] Recived trans On 
 IMP Port
UVM_INFO sub_component_b_aa.sv(25) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a.sub_comp_b_aa [sub_component_b_aa] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2304
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------

UVM_INFO sub_component_a_a.sv(34) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

TLM Port Port Export Imp Port Connection

Connecting TLM Port Port Export Imp port

Port Port Export Imp_port
Port Port Export Imp_port

This example shows connecting TLM Port -> Port -> Export -> Imp_port

TLM TesetBench Components are,

—————————————————————
Name                Type
—————————————————————
uvm_test_top              basic_test
env                          environment
comp_a                 component_a
sub_comp_a_a  sub_component_a_a
trans_out         uvm_blocking_put_port
trans_out           uvm_blocking_put_port
comp_b                 component_b
sub_comp_b_a  sub_component_b_a
trans_in           uvm_blocking_put_imp
trans_in             uvm_blocking_put_export
—————————————————————

Implement TLM port in sub_comp_a_a

Implementing TLM port in sub_comp_a_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Randomize the transaction class
  4. Send the transaction to the comp_b through put() method
class sub_component_a_a extends uvm_component;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port #(transaction) trans_out;
  
  `uvm_component_utils(sub_component_a_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    trans = transaction::type_id::create("trans", this);
    void'(trans.randomize());  //Step-3. randomizing the transction
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.put(trans);  //Step-4. Sending trans through port put method
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : sub_component_a_a

Implement TLM port in comp_a

Implementing TLM port in comp_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Connect port with sub_comp_a_a port
class component_a extends uvm_component;
  
  sub_component_a_a sub_comp_a_a;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port#(transaction) trans_out; 
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_a_a = sub_component_a_a::type_id::create("sub_comp_a_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    sub_comp_a_a.trans_out.connect(trans_out);  //Step-3. Connecting port with sub_comp_a_a port
  endfunction : connect_phase
endclass : component_a

Implement TLM Imp port in sub_comp_b_a

Implementing TLM port in sub_comp_b_a involves below steps,

  1. Declare the uvm_blocking_put_imp
  2. Create the imp port
  3. Implement the put() method to receive the transaction
class sub_component_b_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring blocking imp port 
  uvm_blocking_put_imp#(transaction,sub_component_b_a) trans_in; 
  `uvm_component_utils(sub_component_b_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating imp port
  endfunction : new
  
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  //Step-3. Implementing imp port
  virtual task put(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
  endtask
endclass : sub_component_b_a

Implement TLM Export in comp_b

Implementing TLM port in comp_b involves below steps,

  1. Declare the uvm_blocking_put_export
  2. Create the export
  3. Connect export to the imp port
class component_b extends uvm_component;
  
  sub_component_b_a sub_comp_b_a;
  //Step-1. Declaring blocking export
  uvm_blocking_put_export#(transaction) trans_in; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating export
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_b_a = sub_component_b_a::type_id::create("sub_comp_b_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    trans_in.connect(sub_comp_b_a.trans_in);  //Step-3. Connecting export to the imp port
  endfunction : connect_phase
endclass : component_b

Environment code

In the environment file comp_a port is connected with the comp_b export.

function void connect_phase(uvm_phase phase);
  comp_a.trans_out.connect(comp_b.trans_in);  //Connecting port with export
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------------------------
Name Type Size Value
--------------------------------------------------------
uvm_test_top basic_test - @1845
 env environment - @1914
 comp_a component_a - @1946
 sub_comp_a_a sub_component_a_a - @2044
 trans_out uvm_blocking_put_port - @2116
 trans_out uvm_blocking_put_port - @1981
 comp_b component_b - @2014
 sub_comp_b_a sub_component_b_a - @2151
 trans_in uvm_blocking_put_imp - @2186
 trans_in uvm_blocking_put_export - @2049
--------------------------------------------------------
UVM_INFO sub_component_a_a.sv(29) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] tranaction randomized
UVM_INFO sub_component_a_a.sv(30) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2229
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------

UVM_INFO sub_component_a_a.sv(32) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Before calling port put method
UVM_INFO sub_component_b_a.sv(24) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a [sub_component_b_a] Recived trans On IMP Port
UVM_INFO sub_component_b_a.sv(25) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a [sub_component_b_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2229
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------

UVM_INFO sub_component_a_a.sv(34) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

TLM Port export imp port connection

Connecting TLM Port export imp port

Port Export Imp Port
Port Export Imp Port

In the previous examples, we have seen connecting the port to the imp port.This example shows connecting TLM Port -> Export -> Imp_port.

TLM TesetBench Components are,

—————————————————————
Name                Type
—————————————————————
uvm_test_top              basic_test
env                          environment
comp_a                 component_a
trans_out           uvm_blocking_put_port
comp_b                 component_b
sub_comp_b_a  sub_component_b_a
trans_in           uvm_blocking_put_imp
trans_in             uvm_blocking_put_export
—————————————————————

Implement TLM port in comp_a

Implementing TLM port in comp_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Randomize the transaction class
  4. Send the transaction to the comp_b through put() method
class component_a extends uvm_component;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port #(transaction) trans_out;
  
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    trans = transaction::type_id::create("trans", this);
    void'(trans.randomize());  //Step-3. randomizing the transction
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.put(trans);  //Step-4. Sending trans through port put method
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : component_a

Implement TLM port in sub_comp_b_a

Implementing TLM port in sub_comp_b_a involves below steps,

  1. Declare the uvm_blocking_put_imp
  2. Create the imp port
  3. Implement the put() method to receive the transaction
class sub_component_b_a extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring blocking imp port 
  uvm_blocking_put_imp#(transaction,sub_component_b_a) trans_in; 
  `uvm_component_utils(sub_component_b_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating imp port
  endfunction : new
  
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  //Step-3. Implementing imp port
  virtual task put(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
  endtask
endclass : sub_component_b_a

Implement TLM port in comp_b

Implementing TLM port in comp_b involves below steps,

  1. Declare the uvm_blocking_put_export
  2. Create the export
  3. Connect export to the imp port
class component_b extends uvm_component;
  
  sub_component_b_a sub_comp_b_a;
  //Step-1. Declaring blocking export
  uvm_blocking_put_export#(transaction) trans_in; 
  `uvm_component_utils(component_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating export
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_b_a = sub_component_b_a::type_id::create("sub_comp_b_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    trans_in.connect(sub_comp_b_a.trans_in);  //Step-3. Connecting export to the imp port
  endfunction : connect_phase
endclass : component_b

Environment code

In the environment file comp_a port is connected with the comp_b export.

function void connect_phase(uvm_phase phase);
  comp_a.trans_out.connect(comp_b.trans_in);  //Connecting port with export
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
--------------------------------------------------------
Name Type Size Value
--------------------------------------------------------
uvm_test_top basic_test - @1842
 env environment - @1911
 comp_a component_a - @1943
 trans_out uvm_blocking_put_port - @1978
 comp_b component_b - @2011
 sub_comp_b_a sub_component_b_a - @2080
 trans_in uvm_blocking_put_imp - @2115
 trans_in uvm_blocking_put_export - @2046
--------------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
UVM_INFO component_a.sv(30) @ 0: uvm_test_top.env.comp_a [component_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2157
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_a.sv(32) @ 0: uvm_test_top.env.comp_a [component_a] Before calling port put method
UVM_INFO sub_component_b_a.sv(24) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a [sub_component_b_a] Recived trans On IMP Port
UVM_INFO sub_component_b_a.sv(26) @ 0: uvm_test_top.env.comp_b.sub_comp_b_a [sub_component_b_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2157
 addr integral 4 'he 
 wr_rd integral 1 'h0 
 wdata integral 8 'h4 
---------------------------------

UVM_INFO component_a.sv(34) @ 0: uvm_test_top.env.comp_a [component_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯

TLM Port Port Imp Port Connection

Connecting TLM Port Port Imp port

Port Port Imp_port
Port Port Imp_port

This example shows connecting TLM Port -> Port -> Imp_port.

TLM TesetBench Components are,

—————————————————————
Name                Type
—————————————————————
uvm_test_top              basic_test
env                          environment
comp_a                 component_a
sub_comp_a_a  sub_component_a_a
trans_out         uvm_blocking_put_port
trans_out           uvm_blocking_put_port
comp_b                 component_b
trans_in             uvm_blocking_put_imp
—————————————————————

Implement TLM port in sub_comp_a_a

Implementing TLM port in sub_comp_a_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Randomize the transaction class
  4. Send the transaction to the comp_b through put() method
class sub_component_a_a extends uvm_component;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port #(transaction) trans_out;
  
  `uvm_component_utils(sub_component_a_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  //---------------------------------------
  // run_phase
  //---------------------------------------
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    trans = transaction::type_id::create("trans", this);
    void'(trans.randomize());  //Step-3. randomizing the transction
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.put(trans);  //Step-4. Sending trans through port put method
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase
endclass : sub_component_a_a

Implement TLM port in comp_a

Implementing TLM port in comp_a involves below steps,

  1. Declare the uvm_blocking_put_port
  2. Create the port
  3. Connect port with sub_comp_a_a port
class component_a extends uvm_component;
  
  sub_component_a_a sub_comp_a_a;
  //Step-1. Declaring blocking port
  uvm_blocking_put_port#(transaction) trans_out; 
  `uvm_component_utils(component_a)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_out = new("trans_out", this);  //Step-2. Creating the port
  endfunction : new
  
  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    sub_comp_a_a = sub_component_a_a::type_id::create("sub_comp_a_a", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    sub_comp_a_a.trans_out.connect(trans_out);  //Step-3. Connecting port with sub_comp_a_a port
  endfunction : connect_phase
endclass : component_a

Implement TLM Imp port in comp_b

Implementing TLM Imp port in comp_b involves below steps,

  1. Declare the uvm_blocking_put_imp
  2. Create the imp port
  3. Implement the put() method to receive the transaction
class comp_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring blocking imp port 
  uvm_blocking_put_imp#(transaction,comp_b) trans_in; 
  `uvm_component_utils(compo_b)
  
  //---------------------------------------
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
    trans_in = new("trans_in", this);  //Step-2. Creating imp port
  endfunction : new
  
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  //Step-3. Implementing imp port
  virtual task put(transaction trans);
    `uvm_info(get_type_name(),$sformatf(" Recived trans On IMP Port"),UVM_LOW)
    `uvm_info(get_type_name(),$sformatf(" Printing trans,
                                          \n %s",trans.sprint()),UVM_LOW)
  endtask
endclass : comp_b

Environment code

In the environment file comp_a port is connected with the comp_b export.

function void connect_phase(uvm_phase phase);
  comp_a.trans_out.connect(comp_b.trans_in);  //Connecting port with export
endfunction : connect_phase

Simulator Output

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
------------------------------------------------------
Name Type Size Value
------------------------------------------------------
uvm_test_top basic_test - @1842
 env environment - @1911
 comp_a component_a - @1943
 sub_comp_a_a sub_component_a_a - @2041
 trans_out uvm_blocking_put_port - @2113
 trans_out uvm_blocking_put_port - @1978
 comp_b component_b - @2011
 trans_in uvm_blocking_put_imp - @2046
------------------------------------------------------
UVM_INFO sub_component_a_a.sv(29) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] tranaction randomized
UVM_INFO sub_component_a_a.sv(30) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2151
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------

UVM_INFO sub_component_a_a.sv(32) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] Before calling port put method
UVM_INFO component_b.sv(24) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Printing trans, 
 ---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @2151
 addr integral 4 'h2 
 wr_rd integral 1 'h1 
 wdata integral 8 'h9d 
---------------------------------
UVM_INFO sub_component_a_a.sv(34) @ 0: uvm_test_top.env.comp_a.sub_comp_a_a [sub_component_a_a] After calling port put method
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_objection.svh(1271) @ 0: reporter [TEST_DONE] 
UVM_INFO /playground_lib/uvm-1.2/src/base/uvm_report_server.svh(847) @ 0: reporter [UVM/REPORT/SERVER]

Click to execute on   

❮ Previous Next ❯