How to use uvm_barrier and uvm_barrier_pool
uvm_barrier
is added alongside uvm_event
for synchronization. This class allow us to block the specific processes until an expected number of processes reach a defined point. After that, all the pending processes will be resumed at the same time, similar to lifting the barrier.
How to use uvm_barrier and uvm_barrier_pool
uvm_barrier class basic functions
The uvm_barrier
class supports several basic methods as below:
new()
: Creates a new barrier object.set_threshold(int threshold)
: Set the number of waiting processes threshold. If the number of waiting processes is greater or equal to this number, the barrier will be liftedget_threshold()
: Return the current threshold of the barrier.wait_for()
: Blocking the current process, increase the number of waiting processes of the current uvm_barrier object.reset(bit wakeup=1)
: Reset the counter back to zero. Ifwakeup
argument is 1’b1, all the waiting processes will resume. Ifwakeup
is 1’b0, all the waiting processes will be kept waiting.set_auto_reset(bit value=1)
: Allow the barrier to autoreset after the threshold is reach.get_num_waiters()
: Return the number of waiting processes.cancel()
: Decrease the number of waiting processes by one.
Let’s take an example below:
uvm_barrier_pool
Similar to uvm_event , we has this uvm_barrier_pool
, which is a uvm_pool
for uvm_barrier
object. And we use it exactly like the uvm_event_pool
.
Let’s think of this pool as a global associative array where the keys are strings of barrier names, and the values are the uvm_barrier
objects.
Also, uvm_pool
is a singleton class , that explains why it has global access.
uvm_barrier_pool
support several methods, but the most commonly used is get_global()
.
get_global(<string key>)
: Return the uvm barrier object that stored inuvm_barrier_pool
with<string key>
. If no item exist by the given input string, a newuvm_barrier
object will be created for that key.
So to create/get an uvm_barrier
object which is shared globally, we just need to call:
Example
Using uvm_barrier to wait for a number of signal pulse
- In above example code, each time the
op_done_signal_a
asserts, we create a process which has await_for()
statement. This statement will increase the counter of the barrierwait_done_count
by one. Also, since this process is put infork
-join_none
, the forever loop will continue immediately and wait for the next rise edge of theop_done_signal_a
. - After 5 pulses of
op_done_signal_a
, there will be 5 processes blocked bywait_for()
statement. Since the threshold is 5, the barrier will be lifted, all 5 processes will be resumed and execute the next statement, trigger the eventm_done_count_ev
. - So using
uvm_barrier
and an event, we can detect when the signal has asserted 5 times.
Finding more information
[Tags
uvm
]