UVM Barrier
Similar to the UVM event, UVM provides another way to achieve synchronization with the UVM Barrier.
The UVM barrier provides multi-process synchronization that blocks a set of processes until the desired number of processes reaches a particular synchronizing point at which all the processes are released.
UVM Barrier Class Declaration:
class uvm_barrier extends uvm_object
UVM Barrier class hierarchy
UVM Barrier Usage
UVM Barrier is used to synchronize the number of processes based on the threshold value set by the set_threshold method. Once the threshold is reached, the processes are unblocked by the wait_for method.
UVM Barrier Methods
Type |
Methods |
Description |
function |
new |
Creates a new object for barrier |
function |
set_threshold |
Sets a process threshold that waits till the mentioned number of processes reaches the barrier. Once the threshold is reached, all waiting processes are activated. |
function |
get_threshold |
Gets current threshold value for the barrier. |
task |
wait_for |
Waits for the number of processes being set by the set_threshold method before continuing from the barrier. |
function |
get_num_waiters |
Returns the number of processes currently waiting at the barrier. |
function |
reset |
Resets the barrier and sets the waiter process count to zero. After reset, the barrier will force processes to wait for the same threshold value again. The reset function does not change the threshold value which was set by the set_threshold method last time. |
function |
set_auto_reset |
Once the threshold is reached, the barrier should reset itself. This is the default configuration that makes sure blocking of new processes until the threshold reaches again. If set_auto_reset is turned off, once the threshold is reached, new processes will not be blocked until the barrier is reset. |
function |
cancel |
Decrements the waiter count by one that is used when a process is being killed or activated while waiting on the barrier. |
UVM Barrier Examples
A basic uvm_barrier example with set_threshold method
In the below examples, the process task has two arguments string name and p_delay.
The name argument denotes process name and p_delay indicates delay time taken by the process to complete. Total 10 processes are forked with different execution delay time.
The processes will wait till the threshold being reached which is set by the set_threshold method to proceed further as demonstrated below.
module barrier_example();
uvm_barrier br;
task automatic process(string name, int p_delay);
$display("@%0t: Process %s started", $time, name);
#p_delay;
$display("@%0t: Process %s completed", $time, name);
br.wait_for();
$display("@%0t: Process %s wait_for is unblocked", $time, name);
endtask
initial begin
br = new("br");
br.set_threshold(4);
fork
process("A", 5);
process("B", 10);
process("C", 20);
process("D", 25);
process("E", 30);
process("F", 40);
process("G", 50);
process("H", 55);
process("I", 60);
process("J", 70);
join
end
endmodule
Output:
@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process G started
@0: Process H started
@0: Process I started
@0: Process J started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@40: Process F completed
@50: Process G completed
@55: Process H completed
@55: Process E wait_for is unblocked
@55: Process F wait_for is unblocked
@55: Process G wait_for is unblocked
@55: Process H wait_for is unblocked
@60: Process I completed
@70: Process J completed
reset, get_threshold, and get_num_waiters methods example
The set_threshold sets value as 4.
The get_threshold and get_num_waiters methods are called when
- The threshold is not reached.
- After reset method call
- After the threshold has reached.
The get_threshold returns threshold value irrespective of reset and threshold reached or not. The get_num_waiters show the number of processes currently waiting at the barrier. In the first case, three processes are waiting at the barrier. In the second case (after reset is applied), waiting at barrier processes count is reset to zero. In the third case, since the threshold has reached, waiting at barrier processes count is reset to zero as set_auto_reset is turned on by default.
module barrier_example();
uvm_barrier br;
task automatic process(string name, int p_delay);
$display("@%0t: Process %s started", $time, name);
#p_delay;
$display("@%0t: Process %s completed", $time, name);
br.wait_for();
$display("@%0t: Process %s wait_for is unblocked", $time, name);
endtask
task print(int delay);
#delay;
$display("@%0t: threshold value for the barrier = %0d and number of waiters = %0d", $time, br.get_threshold(), br.get_num_waiters());
endtask
initial begin
br = new("br");
br.set_threshold(4);
fork
process("A", 5);
process("B", 10);
process("C", 20);
print(22);
process("D", 25);
process("E", 30);
process("F", 40);
begin
#40;
br.reset();
$display("After reset");
end
print(40);
process("G", 50);
process("H", 55);
process("I", 60);
process("J", 70);
begin
#70;
$display("After threshold is reached");
end
print(73);
process("K", 75);
process("L", 80);
join
end
endmodule
Output:
@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process G started
@0: Process H started
@0: Process I started
@0: Process J started
@0: Process K started
@0: Process L started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@22: threshold value for the barrier = 4 and number of waiters = 3
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@40: Process F completed
After reset
@40: threshold value for the barrier = 4 and number of waiters = 0
@40: Process E wait_for is unblocked
@40: Process F wait_for is unblocked
@50: Process G completed
@55: Process H completed
@60: Process I completed
@70: Process J completed
After threshold is reached
@70: Process G wait_for is unblocked
@70: Process H wait_for is unblocked
@70: Process I wait_for is unblocked
@70: Process J wait_for is unblocked
@73: threshold value for the barrier = 4 and number of waiters = 0
@75: Process K completed
@80: Process L completed
cancel method example
The cancel method decrements the waiter count by one as shown in the below example. Before calling the cancel method, the number of waiters count = 3, and after calling the cancel method, the number of waiters count = 2.
module barrier_example();
uvm_barrier br;
task automatic process(string name, int p_delay);
$display("@%0t: Process %s started", $time, name);
#p_delay;
$display("@%0t: Process %s completed", $time, name);
br.wait_for();
$display("@%0t: Process %s wait_for is unblocked", $time, name);
endtask
initial begin
br = new("br");
br.set_threshold(4);
fork
process("A", 5);
process("B", 10);
process("C", 20);
begin
#20;
$display("@%0t: Before cancel: number of waiters = %0d", $time, br.get_num_waiters());
br.cancel();
$display("@%0t: After cancel: number of waiters = %0d", $time, br.get_num_waiters());
end
process("D", 25);
process("E", 30);
begin
#30;
$display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
end
join
end
endmodule
Output:
@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@20: Before cancel: number of waiters = 3
@20: After cancel: number of waiters = 2
@25: Process D completed
@30: Process E completed
@30: number of waiters = 0
@30: Process A wait_for is unblocked
@30: Process B wait_for is unblocked
@30: Process C wait_for is unblocked
@30: Process D wait_for is unblocked
@30: Process E wait_for is unblocked
set_auto_reset method example
The set_auto_reset method is turned off by passing the value argument as 0. Once the threshold is reached, the number of waiters is 0 and no further processes are blocked until it is reset at 50-time units.
module barrier_example();
uvm_barrier br;
task automatic process(string name, int p_delay);
$display("@%0t: Process %s started", $time, name);
#p_delay;
$display("@%0t: Process %s completed", $time, name);
br.wait_for();
$display("@%0t: Process %s wait_for is unblocked", $time, name);
endtask
initial begin
br = new("br");
br.set_threshold(4);
br.set_auto_reset(0);
fork
process("A", 5);
process("B", 10);
process("C", 20);
process("D", 25);
process("E", 30);
process("F", 35);
begin
#40;
$display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
end
begin
#50;
br.reset();
$display("@%0t: After reset", $time);
end
process("F", 50);
begin
#50;
$display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
end
join
end
endmodule
Output:
@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process F started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@30: Process E wait_for is unblocked
@35: Process F completed
@35: Process F wait_for is unblocked
@40: number of waiters = 0
@50: After reset
@50: Process F completed
@50: number of waiters = 1
UVM Tutorials