Jump to content

what is the intend of uvm_wait_for_nba_region?

Recommended Posts

Hi, All


there is a task as follow in uvm_globals.sv file.



// Task: uvm_wait_for_nba_region
// Callers of this task will not return until the NBA region, thus allowing
// other processes any number of delta cycles (#0) to settle out before
// continuing. See <uvm_sequencer_base::wait_for_sequences> for example usage.

task uvm_wait_for_nba_region;

  string s;

  int nba;
  int next_nba;

  //If `included directly in a program block, can't use a non-blocking assign,
  //but it isn't needed since program blocks are in a seperate region.
  nba <= next_nba;
  repeat(`UVM_POUND_ZERO_COUNT) #0;


For example, it is used in the task wait_for_sequences in uvm_sequencer_base.sv file


Who would like to explain the function of the uvm_wait_for_nba_region in details?


Best Regards






Link to comment
Share on other sites

This is really a workaround for the fact that earlier versions of SystemVerilog did not support non-blocking assignments to class variables. When you have many different processes simultaneously writing and reading the same variable, you need a way to prevent races between the indeterminate ordering between the reads and the writes. In the case of the UVM sequencer, you want all the sequences to have a chance to write their requests to the sequencer before arbitration kicks in to select a sequence. Without some kind of blocking mechanism, its possible that a single sequence can "hog" the sequencer, not giving the other sequences a change to put in their requests. In the past, this was done by adding #0 delays, a highly discouraged practice. A #0 simply means go to the end of the queue of things currently executing. A single #0 is sometime unavoidable, but once you start adding more #0's you are simply postponing race conditions for later in the queue. The UVM originally tried to solve this by adding a repeat (some_large_enough_number) #0; hoping that that number was larger than anyone else would have used. The NBA region solves this by creating a separate queue of updates to execute after all the activity at the current time has settled out. If the sequences had used NBAs to write their requests, this wait functionality would not be needed.


And the comment about if the UVM library was `included in a program block instead of a package is false in so many ways

  1. Scheduling semantics of program blocks has nothing to do with where the code is declared, only where the process is initiated when calling run_test().
  2. You certainly are allowed to have nonblocking assignments in a program block.
  3. You certainly do need this functionality because you can have the same races within a program block between reads and writes as you can within a module.
Link to comment
Share on other sites

  • 9 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...