uvm barrier examples

uvm_barrier examples

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

Click to execute on   

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

Click to execute on   

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

Click to execute on   

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

Click to execute on   

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

Click to execute on   

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

Click to execute on   

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

Click to execute on   

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

❮ Previous Next ❯