Ready-to-run snippets

Code Examples

Ready-to-run Verilog, SystemVerilog, and UVM examples. Click any to open it live in the IDE.

← All examples

TLM Put Port to Port to Export to Export to Imp

UVM

UVM example from the ChipVerify tutorial: TLM Put Port to Port to Export to Export to Imp.

Open in IDE
Related tutorial:
testbench.sv
//--------------------------------------------------------------
// Author  : Admin, ChipVerify
// Website : www.chipverify.com
// Notes   :
// subCompA is trying to send to subCompB crossing hierarchies
// All Ports/Exports are terminated by an IMP. Port to Port
// or Export to Export forwards packets. Port to Export connection
// happens at the top level of the hierarchy. Until then its all
// Port to Port and once Export is reached, it is all Export until
// it reaches IMP
//
// +--------------+   	+-------------------+
// |    CompA     |   	| 	  CompB 	    |
// |              |   	| +---------------+ |
// |    	      |     | |   subCompB1   | |
// | +----------+ |  	| | +-----------+ | |
// | | subCompA P P     E E I subCompB2 | | |
// | +----------+ |     | | +-----------+ | |
// |              |     | +---------------+ |
// +--------------+     +-------------------+
//
//--------------------------------------------------------------

`include "uvm_macros.svh"
import uvm_pkg::*;
typedef class subCompA;
typedef class subCompB1;
typedef class subCompB2;
`include "Packet.sv"
`include "subCompA.sv"
`include "componentA.sv"
`include "componentB.sv"
`include "subCompB1.sv"
`include "subCompB2.sv"
`include "my_test.sv"
//--------------------------------------------------------------
// Testbench top module starts running UVM test
//--------------------------------------------------------------
module tb;
  initial
    run_test("my_test");
endmodule
Packet.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// Create a class data object that can be sent from one 
// component to another
//--------------------------------------------------------------
class Packet extends uvm_object;
  rand bit[7:0] addr;
  rand bit[7:0] data;
  
  `uvm_object_utils_begin(Packet)
  	`uvm_field_int(addr, UVM_ALL_ON)
  	`uvm_field_int(data, UVM_ALL_ON)
  `uvm_object_utils_end
  
  function new(string name = "Packet");
    super.new(name);
  endfunction
endclass
subCompA.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// subCompA generates packets and sends to its Port
//--------------------------------------------------------------
class subCompA extends uvm_component;
  `uvm_component_utils (subCompA)
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  
  uvm_blocking_put_port #(Packet) m_put_port;
  int m_num_tx=2;
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    m_put_port = new ("m_put_port", this);
  endfunction
  
  // Create a packet, randomize it and send it through the port
  // Note that put() is a method defined by the receiving component
  // Repeat these steps N times to send N packets
   virtual task run_phase (uvm_phase phase);
     phase.raise_objection(this);
     repeat (m_num_tx) begin
         Packet pkt = Packet::type_id::create ("pkt");
         assert(pkt.randomize ()); 
       
       	 // Print the packet to be displayed in log
       `uvm_info ("SUBCOMPA", "Packet sent to subCompB2", UVM_LOW)
         pkt.print (uvm_default_line_printer);
       
         // Call the TLM put() method of put_port class and pass packet as argument
         m_put_port.put (pkt);
      end
      phase.drop_objection(this);
   endtask
endclass
componentA.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// ComponentA will get the packet from subCompA on its Port 
// and forward it to the connected export
//--------------------------------------------------------------
class componentA extends uvm_component;
   `uvm_component_utils (componentA)
   function new (string name = "componentA", uvm_component parent= null);
      super.new (name, parent);
   endfunction

    subCompA m_subcomp_A;
    uvm_blocking_put_port #(Packet) m_put_port;
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    m_subcomp_A = subCompA::type_id::create("m_subcomp_A", this);
    m_put_port = new ("m_put_port", this);
  endfunction
  
  // Connection with subCompA
  virtual function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    m_subcomp_A.m_put_port.connect(this.m_put_port);
  endfunction
endclass
componentB.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// ComponentB gets the packet on its Export
//--------------------------------------------------------------
class componentB extends uvm_component;
   `uvm_component_utils (componentB)
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
 
	subCompB1 m_subcomp_B1;
   uvm_blocking_put_export#(Packet) m_put_export;
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    m_subcomp_B1 = subCompB1::type_id::create("m_subcomp_B1", this);
    m_put_export = new("m_put_export", this);
  endfunction
  
  // Connection with subCompB
  virtual function void connect_phase(uvm_phase phase);
    m_put_export.connect(m_subcomp_B1.m_put_export);
  endfunction
endclass
subCompB1.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// subCompB1 gets the packet on its Export
//--------------------------------------------------------------
class subCompB1 extends uvm_component;
   `uvm_component_utils (subCompB1)
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
 
	subCompB2 m_subcomp_B2;
   uvm_blocking_put_export#(Packet) m_put_export;
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    m_subcomp_B2 = subCompB2::type_id::create("m_subcomp_B2", this);
    m_put_export = new("m_put_export", this);
  endfunction
  
  // Connection with subCompB2
  virtual function void connect_phase(uvm_phase phase);
    m_put_export.connect(m_subcomp_B2.m_put_imp);
  endfunction
endclass
subCompB2.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// subCompB implements the "put" method and gets the packet via
// its implementation port IMP
//--------------------------------------------------------------
class subCompB2 extends uvm_component;
  `uvm_component_utils (subCompB2)
  function new (string name = "subCompB2", uvm_component parent = null);
      super.new (name, parent);
   endfunction

   // Mention type of transaction, and type of class that implements the put ()
  uvm_blocking_put_imp #(Packet, subCompB2) m_put_imp;
 
   virtual function void build_phase (uvm_phase phase);
      super.build_phase (phase);
     m_put_imp = new ("m_put_imp", this);
   endfunction
 
    // Implementation of the 'put()' method in this case simply prints it.
  	virtual task put (Packet pkt);            
      `uvm_info ("SUBCOMPB2", "Packet received from subCompA", UVM_LOW)
      pkt.print(uvm_default_line_printer);
   endtask
endclass
my_test.sv
`include "uvm_macros.svh"
import uvm_pkg::*;

//--------------------------------------------------------------
// Test class instantiates both components and connects them
//--------------------------------------------------------------
class my_test extends uvm_test;
  `uvm_component_utils (my_test)
 
   componentA compA;
   componentB compB;
 
  function new (string name = "my_test", uvm_component parent = null);
      super.new (name, parent);
   endfunction
 
   // Create objects of both components, set number of transfers
   virtual function void build_phase (uvm_phase phase);
      super.build_phase (phase);
      compA = componentA::type_id::create ("compA", this);
      compB = componentB::type_id::create ("compB", this);
   endfunction
 
   // Connection between componentA and componentB is done here
   virtual function void connect_phase (uvm_phase phase);
     compA.m_put_port.connect (compB.m_put_export);  
   endfunction
  
   virtual function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    uvm_top.print_topology();
  endfunction
endclass
design.sv
// Code your design here
Admin mode — edit and delete controls are visible on each row. Use the IDE to add new snippets via File → Save as Snippet.