UVM Barrier
一、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