[UVM]UVM進程同步之UVM Barrier(二)

                                       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
发布了185 篇原创文章 · 获赞 118 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/gsjthxy/article/details/105253681