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 endendmodule |
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 endendmodule |
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 endendmodule |
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 endendmodule |
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 endendmodule |
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 endendmodule |
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 endendmodule |
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
