Contact / Report an issue

Non Blocking TLM port Imp port connection

Nonblocking TLM port and Imp Port


NonBlocking Port Imp Port
NonBlocking Port Imp Port

This example shows how to declare, create and connect the TLM non-blocking ports, implementing and using the TLM non-blocking methods. In this example blocking ports of the previous example (Connecting TLM Port and Imp Port) are replaced with the non-blocking ports. It is preferred to refer to Connecting TLM Port and Imp Port example before going through this example.

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 interface methods 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_nonblocking_put_port
        comp_b         component_b       
            trans_in     uvm_nonblocking_put_imp
----------------------------------------------------------




Declare and Create TLM Port in comp_a


class component_a extends uvm_component;

  //Step-1. Declaring Non-blocking port
  uvm_nonblocking_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);

  endtask : run_phase

endclass : component_a

Declare and Create TLM Port in comp_b


class component_b extends uvm_component;
  
  transaction trans;
  //Step-1. Declaring nonblocking put imp port
  uvm_nonblocking_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);  //Step-2. Creating the port
  endfunction : new

endclass : component_b

Connect TLM Port and Imp Port in env


    function void connect_phase(uvm_phase phase);
      //Step-1, Connecting the ports
      comp_a.trans_out.connect(comp_b.trans_in);
    endfunction : connect_phase
    

    Call interface method in comp_a to send the transaction


    As the port declared is a nonblocking port, the try_put method has to be used for sending the transaction packet.
      void'(trans.randomize());
      trans_out.try_put(trans);
      




      Implement an interface method in comp_b to receive the transaction


      1. In order to receive the transaction on nonblocking imp port try_put and can_put methods has to be implemented.

      Note:
      As the port is nonblocking, methods should be implemented as function not task.

      In the blocking example, the put method is implemented as a task.
          virtual function try_put(transaction trans);
            `uvm_info(get_type_name(),$sformatf(" Inside try_put method"),UVM_LOW)
            `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)
          endfunction

        virtual function bit can_put();
        
        endfunction 

        * Implementing and using of can_put is shown in the next example

        2. Complete comp_b code
          class component_b extends uvm_component;
            
            transaction trans;
            uvm_nonblocking_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 try_put method
            //---------------------------------------
            virtual function bit try_put(transaction trans);
              `uvm_info(get_type_name(),$sformatf(" Inside try_put method"),UVM_LOW)
              `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)
            endfunction 
            
            //---------------------------------------
            // Imp port can_put method
            //---------------------------------------
            virtual function bit can_put();
          
            endfunction 
          
          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_nonblocking_put_port - @1975
          comp_b component_b - @2008
          trans_in uvm_nonblocking_put_imp - @2043
          ------------------------------------------------------
          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 - @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] Inside try_put method
          UVM_INFO component_b.sv(25) @ 0: uvm_test_top.env.comp_b [component_b] Recived trans On IMP Port
          UVM_INFO component_b.sv(26) @ 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 



          The next example shows the implementation of the can_put() method.