Tutorials

Learn More

Similar to the UVM event, UVM provides another way to achieve synchronization with the UVM Barrier.

The UVM barrier provides multi-process synchronization that blocks a set of processes until the desired number of processes reaches a particular synchronizing point at which all the processes are released.

UVM Barrier Class Declaration:

class uvm_barrier extends uvm_object

UVM Barrier class hierarchy

uvm_barrier hierarchy

UVM Barrier Usage

UVM Barrier is used to synchronize the number of processes based on the threshold value set by the set_threshold method. Once the threshold is reached, the processes are unblocked by the wait_for method.

UVM Barrier Methods

Type

Methods

Description

function

new

Creates a new object for barrier

function

set_threshold

Sets a process threshold that waits till the mentioned number of processes reaches the barrier. Once the threshold is reached, all waiting processes are activated.

function

get_threshold

Gets current threshold value for the barrier.

task

wait_for

Waits for the number of processes being set by the set_threshold method before continuing from the barrier.

function

get_num_waiters

Returns the number of processes currently waiting at the barrier.

function

reset

Resets the barrier and sets the waiter process count to zero. After reset, the barrier will force processes to wait for the same threshold value again. The reset function does not change the threshold value which was set by the set_threshold method last time.

function

set_auto_reset

Once the threshold is reached, the barrier should reset itself. This is the default configuration that makes sure blocking of new processes until the threshold reaches again.

If set_auto_reset is turned off, once the threshold is reached, new processes will not be blocked until the barrier is reset.

function

cancel

Decrements the waiter count by one that is used when a process is being killed or activated while waiting on the barrier.

UVM Barrier Examples

A basic uvm_barrier example with set_threshold method

In the below examples, the process task has two arguments string name and p_delay.

The name argument denotes process name and p_delay indicates delay time taken by the process to complete. Total 10 processes are forked with different execution delay time.

The processes will wait till the threshold being reached which is set by the set_threshold method to proceed further as demonstrated below.

module barrier_example();
  uvm_barrier br;
  
  task automatic process(string name, int p_delay);
    $display("@%0t: Process %s started", $time, name);
    #p_delay;
    $display("@%0t: Process %s completed", $time, name);
    br.wait_for();
    $display("@%0t: Process %s wait_for is unblocked", $time, name);    
  endtask
  
  initial begin
    br = new("br");
    br.set_threshold(4);
    fork
      process("A", 5);
      process("B", 10);
      process("C", 20);
      process("D", 25);
      
      process("E", 30);
      process("F", 40);
      process("G", 50);
      process("H", 55);
      
      process("I", 60);
      process("J", 70);
    join
  end
endmodule

Output:

@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process G started
@0: Process H started
@0: Process I started
@0: Process J started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@40: Process F completed
@50: Process G completed
@55: Process H completed
@55: Process E wait_for is unblocked
@55: Process F wait_for is unblocked
@55: Process G wait_for is unblocked
@55: Process H wait_for is unblocked
@60: Process I completed
@70: Process J completed

reset, get_threshold, and get_num_waiters methods example

The set_threshold sets value as 4.

The get_threshold and get_num_waiters methods are called when 

  1. The threshold is not reached.
  2. After reset method call
  3. After the threshold has reached.

The get_threshold returns threshold value irrespective of reset and threshold reached or not. The get_num_waiters show the number of processes currently waiting at the barrier. In the first case, three processes are waiting at the barrier. In the second case (after reset is applied), waiting at barrier processes count is reset to zero. In the third case, since the threshold has reached, waiting at barrier processes count is reset to zero as set_auto_reset is turned on by default.

module barrier_example();
  uvm_barrier br;
  
  task automatic process(string name, int p_delay);
    $display("@%0t: Process %s started", $time, name);
    #p_delay;
    $display("@%0t: Process %s completed", $time, name);
    br.wait_for();
    $display("@%0t: Process %s wait_for is unblocked", $time, name);    
  endtask

  task print(int delay);
    #delay;
    $display("@%0t: threshold value for the barrier = %0d and number of waiters = %0d", $time, br.get_threshold(), br.get_num_waiters());
  endtask
  
  initial begin
    br = new("br");
    br.set_threshold(4);
    fork
      process("A", 5);
      process("B", 10);
      process("C", 20);
      print(22);
      process("D", 25);
      
      process("E", 30);
      process("F", 40);
      begin 
        #40;
        br.reset();
        $display("After reset");
      end
      print(40);
      
      process("G", 50);
      process("H", 55);
      process("I", 60);
      process("J", 70);
      begin 
        #70;
        $display("After threshold is reached");
      end
      print(73);
      
      process("K", 75);
      process("L", 80);
    join
  end
endmodule

Output:

@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process G started
@0: Process H started
@0: Process I started
@0: Process J started
@0: Process K started
@0: Process L started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@22: threshold value for the barrier = 4 and number of waiters = 3
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@40: Process F completed
After reset
@40: threshold value for the barrier = 4 and number of waiters = 0
@40: Process E wait_for is unblocked
@40: Process F wait_for is unblocked
@50: Process G completed
@55: Process H completed
@60: Process I completed
@70: Process J completed
After threshold is reached
@70: Process G wait_for is unblocked
@70: Process H wait_for is unblocked
@70: Process I wait_for is unblocked
@70: Process J wait_for is unblocked
@73: threshold value for the barrier = 4 and number of waiters = 0
@75: Process K completed
@80: Process L completed

cancel method example

The cancel method decrements the waiter count by one as shown in the below example. Before calling the cancel method, the number of waiters count = 3, and after calling the cancel method, the number of waiters count = 2.

module barrier_example();
  uvm_barrier br;
  
  task automatic process(string name, int p_delay);
    $display("@%0t: Process %s started", $time, name);
    #p_delay;
    $display("@%0t: Process %s completed", $time, name);
    br.wait_for();
    $display("@%0t: Process %s wait_for is unblocked", $time, name);    
  endtask

  initial begin
    br = new("br");
    br.set_threshold(4);
    fork
      process("A", 5);
      process("B", 10);
      process("C", 20);
      begin 
        #20;
        $display("@%0t: Before cancel: number of waiters = %0d", $time, br.get_num_waiters());
        br.cancel();
        $display("@%0t: After cancel: number of waiters = %0d", $time, br.get_num_waiters());
      end
      
      process("D", 25);
      process("E", 30);
      begin 
        #30;
        $display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
      end
    join
  end
endmodule

Output:

@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@20: Before cancel: number of waiters = 3
@20: After cancel: number of waiters = 2
@25: Process D completed
@30: Process E completed
@30: number of waiters = 0
@30: Process A wait_for is unblocked
@30: Process B wait_for is unblocked
@30: Process C wait_for is unblocked
@30: Process D wait_for is unblocked
@30: Process E wait_for is unblocked

set_auto_reset method example

The set_auto_reset method is turned off by passing the value argument as 0. Once the threshold is reached, the number of waiters is 0 and no further processes are blocked until it is reset at 50-time units.

module barrier_example();
  uvm_barrier br;
  
  task automatic process(string name, int p_delay);
    $display("@%0t: Process %s started", $time, name);
    #p_delay;
    $display("@%0t: Process %s completed", $time, name);
    br.wait_for();
    $display("@%0t: Process %s wait_for is unblocked", $time, name);    
  endtask

  initial begin
    br = new("br");
    br.set_threshold(4);
    br.set_auto_reset(0);
    fork
      process("A", 5);
      process("B", 10);
      process("C", 20);
      process("D", 25);
      process("E", 30);
      process("F", 35);
      begin 
        #40;
        $display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
      end
      begin 
        #50;
        br.reset();
        $display("@%0t: After reset", $time);
      end
      process("F", 50);
      begin 
        #50;
        $display("@%0t: number of waiters = %0d", $time, br.get_num_waiters());
      end
      
    join
  end
endmodule

Output:

@0: Process A started
@0: Process B started
@0: Process C started
@0: Process D started
@0: Process E started
@0: Process F started
@0: Process F started
@5: Process A completed
@10: Process B completed
@20: Process C completed
@25: Process D completed
@25: Process A wait_for is unblocked
@25: Process B wait_for is unblocked
@25: Process C wait_for is unblocked
@25: Process D wait_for is unblocked
@30: Process E completed
@30: Process E wait_for is unblocked
@35: Process F completed
@35: Process F wait_for is unblocked
@40: number of waiters = 0
@50: After reset
@50: Process F completed
@50: number of waiters = 1