Connecting UVM TLM Port and Imp Port

Connecting TLM Port and Imp Port

TLM Port Imp Port
TLM Port Imp Port

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]

Click to execute on   

❮ Previous Next ❯