UVM Pool
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 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:
- uvm_pool #(string, T) class having key as a string is a specialized class of generic uvm_pool #(KEY, T) class.
- 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
UVM Tutorials