Tutorials

Learn More

The uvm_pool is a parameterized class that implements a pool data structure same as System Verilog associative array and it can be allocated based on demand. The items in the pool can be shared across different verification components as pass by reference. On copying the uvm_pool object, it copies the class handle instead of copying an entire associative array.

uvm_pool class declaration:

class uvm_pool # (type KEY = int, T = uvm_void) extends uvm_object

uvm_pool class hierarchy

uvm_pool hierarchy

uvm_pool class Methods

Methods

Description

function new ( string name = “” )

Creates pool for the given name

static function T get_global ( KEY key )

Returns the specified item instance from the global item pool.

static function this_type get_global_pool ()

Returns the singleton global pool for the item of type T.

virtual function int num ()

Returns the total number of items in the pool for unique keys.

virtual function void add ( KEY key, T item )

Adds given item for the given key as a (key, item) pair. If an item exists already for the given key, the previous item is overwritten with the new item.

virtual function T get ( KEY key )

Returns the item for the given key. If no item exists by that key, it creates a new item and returns the same for that key.

virtual function void delete ( KEY key )

Removes the item from the pool for the given key.

virtual function int exists ( KEY key )

Returns 1 if an item exists in the pool for the given key otherwise, it returns 0.

virtual function int next ( ref KEY key )

If the next key is found, then the function returns 1, and the key is updated with that key.

If the input key is the last key in the pool, then the function returns 0, and the key is left unchanged.

virtual function int prev ( ref KEY key )

If the previous key is found, then the function returns 1, and the key is updated with that key.

If the input key is the first key in the pool, then the function returns 0, and the key is left unchanged.

virtual function int first ( ref KEY key )

Returns the key of the first item as a key stored in the pool if the pool is not empty and 1 is returned.

The key is unchanged if the pool is empty and 0 is returned.

virtual function int last ( ref KEY key )

Returns the key of the last item as a key stored in the pool if the pool is not empty and 1 is returned

The key is unchanged if the pool is empty and 0 is returned.

UVM Pool Example

`include "uvm_macros.svh"
import uvm_pkg::*;

function void emp_exists(uvm_pool #(string, int) emp_pool, string emp_name);
  int is_emp_exist;
  is_emp_exist = emp_pool.exists(emp_name);
    `uvm_info("emp_pool", $sformatf("is_emp_exist = %0d", is_emp_exist), UVM_LOW);
    if(is_emp_exist) begin
      `uvm_info("emp_pool", $sformatf("%s exists in the emp_pool", emp_name), UVM_LOW);
    end
    else begin
      `uvm_info("emp_pool", $sformatf("%s does not exist in the emp_pool", emp_name), UVM_LOW);
    end
endfunction

module pool_example;
  uvm_pool #(string, int) emp_pool; // key = string and item = int
                                    // key = emp_name and item = emp_id
  string emp_name;
  int T;
  
  initial begin
    //run_test();
    emp_pool = new("emp");
    
    // add
    emp_pool.add("Angel", 1001);
    emp_pool.add("Bob", 1002);
    emp_pool.add("Charlie", 1003);
    emp_pool.add("David", 1004);
    
    // Exists
    emp_exists(emp_pool, "John");
    emp_exists(emp_pool, "Bob");
       
    // prev
    emp_name = "Bob";
    emp_pool.prev(emp_name);
    `uvm_info("emp_pool", $sformatf("prev key = %0s", emp_name), UVM_LOW);
    
    // next
    emp_name = "Bob";
    emp_pool.next(emp_name);
    `uvm_info("emp_pool", $sformatf("next key = %0s", emp_name), UVM_LOW);
    
    // first
    emp_pool.first(emp_name);
    `uvm_info("emp_pool", $sformatf("first key = %0s", emp_name), UVM_LOW);
    
    // last
    emp_pool.last(emp_name);
    `uvm_info("emp_pool", $sformatf("last key = %0s", emp_name), UVM_LOW);
    
    //get
    `uvm_info("emp_pool", $sformatf("get: emp_pool[\"Bob\"] = %0d", emp_pool.get("Bob")), UVM_LOW);
    
    //get_global
    emp_name = "Bob";
    uvm_pool::get_global(emp_name);
    `uvm_info("emp_pool", $sformatf("get_global: emp_pool[\"Bob\"] = %s", emp_name), UVM_LOW);
    
    //num
    `uvm_info("emp_pool", $sformatf("Number of entries in emp_pool = %0d", emp_pool.num()), UVM_LOW);
    
    // delete
    emp_pool.delete("Bob");
    `uvm_info("emp_pool", $sformatf("After delete method: Number of entries in emp_pool = %0d", emp_pool.num()), UVM_LOW);
  end
endmodule

Output:

UVM_INFO testbench.sv(7) @ 0: reporter [emp_pool] is_emp_exist = 0
UVM_INFO testbench.sv(12) @ 0: reporter [emp_pool] John does not exist in the emp_pool
UVM_INFO testbench.sv(7) @ 0: reporter [emp_pool] is_emp_exist = 1
UVM_INFO testbench.sv(9) @ 0: reporter [emp_pool] Bob exists in the emp_pool
UVM_INFO testbench.sv(39) @ 0: reporter [emp_pool] prev key = Angel
UVM_INFO testbench.sv(44) @ 0: reporter [emp_pool] next key = Charlie
UVM_INFO testbench.sv(48) @ 0: reporter [emp_pool] first key = Angel
UVM_INFO testbench.sv(52) @ 0: reporter [emp_pool] last key = David
UVM_INFO testbench.sv(55) @ 0: reporter [emp_pool] get: emp_pool["Bob"] = 1002
UVM_INFO testbench.sv(60) @ 0: reporter [emp_pool] get_global: emp_pool["Bob"] = Bob
UVM_INFO testbench.sv(63) @ 0: reporter [emp_pool] Number of entries in emp_pool = 4
UVM_INFO testbench.sv(67) @ 0: reporter [emp_pool] After delete method: Number of entries in emp_pool = 3

uvm_object_string_pool #(T)

The uvm_object_string_pool #(T) is derived from uvm_pool #(string, T) class for an associative array of uvm_object indexed by a string.

uvm_object_string_pool class declaration:

class uvm_object_string_pool #( type T = uvm_object ) extends uvm_pool #(string,T)

uvm_object_string_pool class methods

Methods

Description

function new ( string name = “” )

Creates pool for the given name

static function T get_global ( KEY key )

Returns the specified item instance from the global item pool.

static function this_type get_global_pool ()

Returns the singleton global pool for the item of type T.

virtual function string get_type_name()

Returns type name of this object

virtual function T get ( KEY key )

Returns the object item for the given string key. If no item exists by that key, it creates a new item and returns the same for that key.

virtual function void delete ( KEY key )

Removes the item from the pool for the given key.

Note: 

  1. uvm_pool #(string, T) class having key as a string is a specialized class of generic uvm_pool #(KEY, T) class.
  2. The pool uvm_object_string_pool of type T = uvm_barrier is known as uvm_barrier_pool.
    typedef uvm_object_string_pool #(uvm_barrier) uvm_barrier_pool;

          3. The pool uvm_object_string_pool of type T = uvm_event is known as uvm_event_pool.

    typedef uvm_object_string_pool #(uvm_event) uvm_event_pool;

    UVM Event Pool

    The UVM event provides synchronization between processes. Please refer to the UVM event for more details.

    The uvm_event_pool maintains a pool of uvm_events that helps to share the uvm_event handle across various testbench components.

    UVM Event Pool Example

    In the below example, componentA triggers the event after 5 time-units, and componentB, componentC waits for the event to be triggered.

    uvm_event_pool::get_global(“myevent”) returns an event handle with the event name as “myevent”.

    The componentB has uvm_event instance name as e1 and componentC has uvm_event instance name as e2. But both event instances refer to the same event.

    Note: The components must use the same name (for example “myevent”) that refer to the same event from the global event pool.

    componentA and componentB:

    class componentA extends uvm_component;
      `uvm_component_utils(componentA)
      uvm_event e1;
      
      function new(string name = "componentA", uvm_component parent = null);
        super.new(name, parent);
      endfunction
      
      task run_phase(uvm_phase phase);
        super.run_phase(phase);
        e1 = uvm_event_pool::get_global("myevent");
        
        `uvm_info(get_type_name(),$sformatf("%0t: Before triggering the event", $time),UVM_LOW)
        #5;
        e1.trigger();
        `uvm_info(get_type_name(),$sformatf("%0t: After triggering the event", $time),UVM_LOW)
      endtask
    endclass
    
    class componentB extends uvm_component;
      `uvm_component_utils(componentB)
      uvm_event e1;
      
      function new(string name = "componentB", uvm_component parent = null);
        super.new(name, parent);
      endfunction
      
      task run_phase(uvm_phase phase);
        super.run_phase(phase);
        e1 = uvm_event_pool::get_global("myevent");
        
        `uvm_info(get_type_name(),$sformatf("%0t: waiting for the event", $time),UVM_LOW)
        e1.wait_trigger();
        `uvm_info(get_type_name(),$sformatf("%0t: event is triggered", $time),UVM_LOW)
      endtask
    endclass
    
    class componentC extends uvm_component;
      `uvm_component_utils(componentC)
      uvm_event e2;
      
      function new(string name = "componentC", uvm_component parent = null);
        super.new(name, parent);
      endfunction
      
      task run_phase(uvm_phase phase);
        super.run_phase(phase);
        e2 = uvm_event_pool::get_global("myevent");
        
        `uvm_info(get_type_name(),$sformatf("%0t: waiting for the event", $time),UVM_LOW)
        e2.wait_trigger();
        `uvm_info(get_type_name(),$sformatf("%0t: event is triggered", $time),UVM_LOW)
      endtask
    endclass
    uvm_event_pool e_pool;
    `include "components.sv"
    
    class base_test extends uvm_test;
      `uvm_component_utils(base_test)
    
      componentA comp_a;
      componentB comp_b;
      componentC comp_c;
    
      function new(string name = "base_test",uvm_component parent=null);
        super.new(name,parent);
        e_pool = new("e_pool");
      endfunction : new
    
      function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        comp_a = componentA::type_id::create("comp_a", this);
        comp_b = componentB::type_id::create("comp_b", this);
        comp_c = componentC::type_id::create("comp_c", this);
      endfunction : build_phase
      
      function void end_of_elaboration();
        uvm_top.print_topology();
      endfunction
      
      task run_phase(uvm_phase phase);
        super.run_phase(phase);
        phase.raise_objection(this);
        #20;
        phase.drop_objection(this);
      endtask
    endclass
    
    module event_pool_example;
      initial begin
        run_test("base_test");
      end
    endmodule

    Output:

    UVM testbench topology:
    -------------------------------------
    Name          Type        Size  Value
    -------------------------------------
    uvm_test_top  base_test   -     @336 
      comp_a      componentA  -     @350 
      comp_b      componentB  -     @359 
      comp_c      componentC  -     @368 
    -------------------------------------
    
    UVM_INFO components.sv(13) @ 0: uvm_test_top.comp_a [componentA] 0: Before triggering the event
    UVM_INFO components.sv(32) @ 0: uvm_test_top.comp_b [componentB] 0: waiting for the event
    UVM_INFO components.sv(50) @ 0: uvm_test_top.comp_c [componentC] 0: waiting for the event
    UVM_INFO components.sv(16) @ 5: uvm_test_top.comp_a [componentA] 5: After triggering the event
    UVM_INFO components.sv(34) @ 5: uvm_test_top.comp_b [componentB] 5: event is triggered
    UVM_INFO components.sv(52) @ 5: uvm_test_top.comp_c [componentC] 5: event is triggered