uvm_barrier examples
Table of Contents
using new and wait_for methods
The below example shows using the uvm_barrier,
- uvm_barrier is declared with the name ba
- the barrier is created by calling ba.new() method, threshold or number of process to wait is an argument for the new method
- This example has 4 processes with delay in it, and the wati_for method is called after the delay
- The statements after the wait_for will get executed only after the 3 process reaches to wait_for (3 is threshold have been set during creating the barrier)
module uvm_barrier_ex; uvm_barrier ba; initial begin ba = new ( "ba" , 3 ); fork begin //process-1 $ display ( $ time , " Inside the process-a" ); #20; $ display ( $ time , " process-a completed" ); $ display ( $ time , " process-a Waiting for barrier" ); ba.wait_for ( ); $ display ( $ time , " process-a after wait_for" ); end begin //process-2 $ display ( $ time , " Inside the process-b" ); #10; $ display ( $ time , " process-b completed" ); $ display ( $ time , " process-b Waiting for barrier" ); ba.wait_for ( ); $ display ( $ time , " process-b after wait_for" ); end begin //process-3 $ display ( $ time , " Inside the process-c" ); #30; $ display ( $ time , " process-c completed" ); $ display ( $ time , " process-c Waiting for barrier" ); ba.wait_for ( ); $ display ( $ time , " process-c after wait_for" ); end begin //process-4 $ display ( $ time , " Inside the process-d" ); #5; $ display ( $ time , " process-d completed" ); $ display ( $ time , " process-d Waiting for barrier" ); ba.wait_for ( ); $ display ( $ time , " process-d after wait_for" ); end join end endmodule |
Simulator Output
0 Inside the process-a 0 Inside the process-b 0 Inside the process-c 0 Inside the process-d 5 process-d completed 5 process-d Waiting for barrier 10 process-b completed 10 process-b Waiting for barrier 20 process-a completed 20 process-a Waiting for barrier 20 process-d after wait_for 20 process-b after wait_for 20 process-a after wait_for 30 process-c completed 30 process-c Waiting for barrier
Output Analysis:
The “after wait_for” display is getting executed only after the 3 processes reaching the ba.wait_for(). this is because the threshold is set is 3.
uvm_barrier in function
This example is similar to the above example. In this example, multiple processes are of the same task.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask initial begin ba = new ( "ba" , 3 ); fork process ( "A" , 30 ); process ( "B" , 10 ); process ( "C" , 20 ); process ( "D" , 5 ); join end endmodule |
Simulator Output
0 [A] Strating the process 0 [A] Injecting the delay of 30 0 [B] Strating the process 0 [B] Injecting the delay of 10 0 [C] Strating the process 0 [C] Injecting the delay of 20 0 [D] Strating the process 0 [D] Injecting the delay of 5 5 [D] Before the wait_for 10 [B] Before the wait_for 20 [C] Before the wait_for 20 [D] After the wait_for 20 [B] After the wait_for 20 [C] After the wait_for 30 [A] Before the wait_for
using set_threshold method
In the previous examples, we have seen setting the threshold using the new() method. This example shows setting the threshold by using the set_threshold() method.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask initial begin ba = new ( "ba" , 3 ); ba.set_threshold ( 3 ); fork process ( "A" , 30 ); process ( "B" , 10 ); process ( "C" , 20 ); process ( "D" , 5 ); join end endmodule |
Simulator Output
0 [A] Strating the process 0 [A] Injecting the delay of 30 0 [B] Strating the process 0 [B] Injecting the delay of 10 0 [C] Strating the process 0 [C] Injecting the delay of 20 0 [D] Strating the process 0 [D] Injecting the delay of 5 5 [D] Before the wait_for 10 [B] Before the wait_for 20 [C] Before the wait_for 20 [D] After the wait_for 20 [B] After the wait_for 20 [C] After the wait_for 30 [A] Before the wait_for
using get_threshold and get_num_waiters
get_threshold() and get_num_waiters() methods return the threshold value and number of waiters at that instant of time.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask task monitor_process ( ); #15; $ display ( $ time , " [Monitor] threshold value of barrie ba is %0d" , ba.get_threshold ( ) ); $ display ( $ time , " [Monitor] Number of process waiting are %0d" , ba.get_num_waiters ( ) ); endtask initial begin ba = new ( "ba" ); ba.set_threshold ( 3 ); fork process ( "A" , 30 ); process ( "B" , 10 ); process ( "C" , 20 ); process ( "D" , 5 ); monitor_process ( ); join end endmodule |
Simulator Output
0 [A] Strating the process 0 [A] Injecting the delay of 30 0 [B] Strating the process 0 [B] Injecting the delay of 10 0 [C] Strating the process 0 [C] Injecting the delay of 20 0 [D] Strating the process 0 [D] Injecting the delay of 5 5 [D] Before the wait_for 10 [B] Before the wait_for 15 [Monitor] threshold value of barrie ba is 3 15 [Monitor] Number of process waiting are 2 20 [C] Before the wait_for 20 [D] After the wait_for 20 [B] After the wait_for 20 [C] After the wait_for 30 [A] Before the wait_for
using the reset method
In the previous examples, we can observe that “After the wait_for” of process A is not getting executed. this is because the number of waiters resets after the third process wait_for and the number of process waiting will be one for process A.
Calling reset() method will lead to releasing the process at wait_for() and the statements after the wait_for(0 will get executed.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask task reset_process ( ); #32; ba.reset ( 1 ); endtask initial begin ba = new ( "ba" ); ba.set_threshold ( 3 ); fork process ( "A" , 30 ); process ( "B" , 10 ); process ( "C" , 20 ); process ( "D" , 5 ); reset_process ( ); join end endmodule |
Simulator Output
0 [A] Strating the process 0 [A] Injecting the delay of 30 0 [B] Strating the process 0 [B] Injecting the delay of 10 0 [C] Strating the process 0 [C] Injecting the delay of 20 0 [D] Strating the process 0 [D] Injecting the delay of 5 5 [D] Before the wait_for 10 [B] Before the wait_for 20 [C] Before the wait_for 20 [D] After the wait_for 20 [B] After the wait_for 20 [C] After the wait_for 30 [A] Before the wait_for 32 [A] After the wait_for
using the set_auto_reset method
This is similar to the above example, in this example auto_reset is set during the initial time. with auto_reset, once the threshold is achieved, new processes pass through without being blocked until the barrier is reset.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask initial begin ba = new ( "ba" ); ba.set_threshold ( 3 ); ba.set_auto_reset ( 0 ); fork process ( "A" , 30 ); process ( "B" , 10 ); process ( "C" , 20 ); process ( "D" , 5 ); join end endmodule |
Simulator Output
0 [A] Strating the process 0 [A] Injecting the delay of 30 0 [B] Strating the process 0 [B] Injecting the delay of 10 0 [C] Strating the process 0 [C] Injecting the delay of 20 0 [D] Strating the process 0 [D] Injecting the delay of 5 5 [D] Before the wait_for 10 [B] Before the wait_for 20 [C] Before the wait_for 20 [D] After the wait_for 20 [B] After the wait_for 20 [C] After the wait_for 30 [A] Before the wait_for 30 [A] After the wait_for
Output Analysis:
In process A, though the process wait_for count is ‘1’. the wait_for will becomes non_blocking and “After the wait_for” statement gets executed.
Using the cancel method
Calling cancel() method will decrement the number of process waiting.
module uvm_barrier_ex; uvm_barrier ba; task automatic process ( input string p_name , int delay ); $ display ( $ time , " [%s] Strating the process" , p_name ); $ display ( $ time , " [%s] Injecting the delay of %0d" , p_name , delay ); #delay; $ display ( $ time , " [%s] Before the wait_for" , p_name ); ba.wait_for ( ); $ display ( $ time , " [%s] After the wait_for" , p_name ); endtask task cancel_process ( ); #20; $ display ( $ time , " Number of process waiting before cancel is %0d" , ba.get_num_waiters ( ) ); ba.cancel ( ); $ display ( $ time , " Number of process waiting after cancel is %0d" , ba.get_num_waiters ( ) ); endtask initial begin ba = new ( "ba" ); ba.set_threshold ( 2 ); fork process ( "A" , 30 ); process ( "B" , 10 ); cancel_process ( ); join end endmodule |
Simulator Output
0 [A] Starting the process 0 [A] Injecting the delay of 30 0 [B] Starting the process 0 [B] Injecting the delay of 10 10 [B] Before the wait_for 20 Number of process waiting before cancel is 1 20 Number of process waiting after cancel is 0 30 [A] Before the wait_for
Output Analysis:
- The threshold is set as ‘2’
- cancel method will get executed after the process B wait_for execution. So the number of processes waiting before the cancel is 1 and after the cancel becomes 0.
- On execution of wait_for of process A, the count becomes 1, and it remains 1 as there is no other process, which leads to the wait_for method to keep blocked
- Statement after wait_for will not get executed