Contact / Report an issue

Connecting UVM TLM Port and Imp Port

Connecting TLM Port and Imp Port


Connecting TLM Port and Imp port
TLM Port Imp Port

* Click on image for a better view 

Let's consider an example consisting of two components component_a and component_b, and a transaction class.
  • component_a and component_b objects are created in the environment with the name comp_a and comp_b respectively
  • transaction class is randomized in comp_a and sent to the comp_b through TLM Communication mechanism

Below are the steps to implement a TLM Communication mechanism between comp_a and comp_b.
  1. Declare and Create TLM Port in comp_a
  2. Declare and Create TLM Imp Port in comp_b
  3. Connect TLM Port and Imp Port in env
  4. Call interface method in comp_a to send the transaction
  5. Implement an interface method in comp_b to receive the transaction 

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         
            trans_in     uvm_blocking_put_imp 
----------------------------------------------------------

Declare and Create TLM Port in comp_a


1. Declaring blocking put port with the name trans_out. As the comp_a sends the packet out of the component, so named as trans_out

uvm_blocking_put_port #(transaction) trans_out;

2. Creating the port

trans_out = new("trans_out", this);

3. comp_a code is as below,

class component_a extends uvm_component;
  
  uvm_blocking_put_port #(transaction) trans_out; //Step-1. Declaring blocking port
  
  `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);

  endtask : run_phase

endclass : component_a




Declare and Create TLM Port in comp_b


1. Declaring blocking put imp port with the name trans_in. As the comp_b receives the packet from another component, so named as trans_in

uvm_blocking_put_imp #(transaction,component_b) trans_in;

2. Creating the port

trans_in = new("trans_in", this);

3. comp_b code is as below,

class component_b extends uvm_component;
  
  transaction trans;
  uvm_blocking_put_imp #(transaction,component_b) trans_in;  //Step-1. Declaring blocking put imp port  

  `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 the port
  endfunction : new

endclass : component_b

Connect TLM Port and Imp Port in env


1. Declare and Create the componet_a and component_b in environment class
component_a comp_a;
component_b comp_b;

comp_a = component_a::type_id::create("comp_a", this);
comp_b = component_b::type_id::create("comp_b", this);

2. Connect comp_a port and comp_b imp port
comp_a.trans_out.connect(comp_b.trans_in);

3. Place the connection code in the connect phase
  function void connect_phase(uvm_phase phase);
    comp_a.trans_out.connect(comp_b.trans_in);
  endfunction : connect_phase

4. Complete env code
class environment extends uvm_env;
  
  //---------------------------------------
  // Components Instantiation
  //---------------------------------------
  //Step-1, Declaring the components
  component_a comp_a;
  component_b comp_b;
  
  `uvm_component_utils(environment)
  
  //--------------------------------------- 
  // Constructor
  //---------------------------------------
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction : new

  //---------------------------------------
  // build_phase - Create the components
  //---------------------------------------
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);

    //Step-1, Creating the components
    comp_a = component_a::type_id::create("comp_a", this);  
    comp_b = component_b::type_id::create("comp_b", this);
  endfunction : build_phase
  
  //---------------------------------------
  // Connect_phase 
  //---------------------------------------
  function void connect_phase(uvm_phase phase);
    //Step-3, Connecting the ports
    comp_a.trans_out.connect(comp_b.trans_in);
  endfunction : connect_phase
endclass : environment




Call interface method in comp_a to send the transaction


1. Randomize the transaction packet and send to comp_b by calling put() method
void'(trans.randomize());
trans_out.put(trans);

2. Place the conde in run_phase
  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    
    trans = transaction::type_id::create("trans", this);

    void'(trans.randomize());

    trans_out.put(trans);
    
    phase.drop_objection(this);
  endtask : run_phase

3. Complete code with uvm_info added

class component_a extends uvm_component;
  
  transaction trans;
  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); 
  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-1: randomize the trans
    `uvm_info(get_type_name(),$sformatf(" tranaction randomized"),UVM_LOW)
    trans.print();
    
    `uvm_info(get_type_name(),$sformatf(" Before calling port put method"),UVM_LOW)
    trans_out.put(trans); // Step-2: Calling put Method to send trans to comp_b
    `uvm_info(get_type_name(),$sformatf(" After  calling port put method"),UVM_LOW)
    
    phase.drop_objection(this);
  endtask : run_phase

endclass : component_a

Implement an interface method in comp_b to receive the transaction


1. In order to receive the transaction packet from imp port, explicit method has to be implemented
Implement put method with the input argument of transaction type
  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 

2. Complete comp_b code
class component_b extends uvm_component;
  
  transaction trans;
  uvm_blocking_put_imp #(transaction,component_b) 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);
  endfunction : new
  
  //---------------------------------------
  // Imp port put method
  //---------------------------------------
  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 : component_b

 Simulator Output 

UVM_INFO @ 0: reporter [RNTST] Running test basic_test...
---------------------------------------------------
Name Type Size Value
---------------------------------------------------
uvm_test_top basic_test - @1839
env environment - @1908
comp_a component_a - @1940
trans_out uvm_blocking_put_port - @1975
comp_b component_b - @2008
trans_in uvm_blocking_put_imp - @2043
---------------------------------------------------
UVM_INFO component_a.sv(29) @ 0: uvm_test_top.env.comp_a [component_a] tranaction randomized
---------------------------------
Name Type Size Value
---------------------------------
trans transaction - @1135
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 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 - @1135
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]

Execute the above code on