Connecting TLM Port and Imp Port
Table of Contents
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.
- Declare and Create TLM Port in comp_a
- Declare and Create TLM Imp Port in comp_b
- Connect TLM Port and Imp Port in env
- Call interface method in comp_a to send the transaction
- 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]