UVM Tutorial for Candy Lovers – 26. Sequence Arbitration

Our jelly-bean business has been doing so well that we started to receive multiple jelly-bean orders at the same time. Some customers requested expedited shipping, too. But how to prioritize the requests? It’s time to learn about sequence arbitration.

Today’s Jelly-Bean Orders

Let’s assume we received the following jelly-bean orders today:

  • Standard order — four APPLE jelly-beans
  • Priority order — four BLUEBERRY jelly-beans
  • Priority order — four BUBBLE_GUM jelly-beans
  • Overnight order — four CHOCOLATE jelly-beans

In our jelly_bean_test, we created four jelly_bean_order_sequence, one per a jelly-bean order (lines 39 to 42). Then, we set the priorities of the sequence and started them at the same time to let the sequencer arbitrate them. Note that the default priority is 100 and higher numbers indicate higher priority. In our case, we set the standard order to be 100, the priority order to be 200, and the overnight order to be 300 (lines 62 to 65).

The UVM sequencer has six arbitration modes:

The set_arbitration function of the uvm_sequencer_base class specifies which mode to use (lines 54 to 59). Let’s look at each mode one by one.

class jelly_bean_test extends uvm_test;
  `uvm_component_utils( jelly_bean_test )
 
  jelly_bean_env jb_env;
 
  //----------------------------------------------------------------------------
  // Function: new
  //----------------------------------------------------------------------------
 
  function new( string name, uvm_component parent );
    super.new( name, parent );
  endfunction: new
 
  //----------------------------------------------------------------------------
  // Function: build_phase
  //----------------------------------------------------------------------------
 
  function void build_phase( uvm_phase phase );
    super.build_phase( phase );
 
    jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
  endfunction: build_phase
 
  //----------------------------------------------------------------------------
  // task: main_phase
  //----------------------------------------------------------------------------
 
  task main_phase( uvm_phase phase );
    jelly_bean_order_sequence standard_order_seq;
    jelly_bean_order_sequence priority_order_seq1;
    jelly_bean_order_sequence priority_order_seq2;
    jelly_bean_order_sequence overnight_order_seq;
 
    standard_order_seq  = jelly_bean_order_sequence::type_id::create( "standard_order_seq" );
    priority_order_seq1 = jelly_bean_order_sequence::type_id::create( "priority_order_seq1" );
    priority_order_seq2 = jelly_bean_order_sequence::type_id::create( "priority_order_seq2" );
    overnight_order_seq = jelly_bean_order_sequence::type_id::create( "overnight_order_seq" );
 
    assert( standard_order_seq .randomize() with { num_jelly_beans == 4; jb_flavor == APPLE;      } );
    assert( priority_order_seq1.randomize() with { num_jelly_beans == 4; jb_flavor == BLUEBERRY;  } );
    assert( priority_order_seq2.randomize() with { num_jelly_beans == 4; jb_flavor == BUBBLE_GUM; } );
    assert( overnight_order_seq.randomize() with { num_jelly_beans == 4; jb_flavor == CHOCOLATE;  } );
 
    standard_order_seq .set_starting_phase( phase );
    priority_order_seq1.set_starting_phase( phase );
    priority_order_seq2.set_starting_phase( phase );
    overnight_order_seq.set_starting_phase( phase );
 
    standard_order_seq .set_automatic_phase_objection( .value( 1 ) );
    priority_order_seq1.set_automatic_phase_objection( .value( 1 ) );
    priority_order_seq2.set_automatic_phase_objection( .value( 1 ) );
    overnight_order_seq.set_automatic_phase_objection( .value( 1 ) );
 
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_FIFO ); // default
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_RANDOM );
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_STRICT_FIFO );
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_STRICT_RANDOM );
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_WEIGHTED );
    //jb_env.jb_agent.jb_seqr.set_arbitration( UVM_SEQ_ARB_USER );
 
    fork
      standard_order_seq .start( jb_env.jb_agent.jb_seqr, .this_priority( 100 ) ); // default priority
      priority_order_seq1.start( jb_env.jb_agent.jb_seqr, .this_priority( 200 ) );
      priority_order_seq2.start( jb_env.jb_agent.jb_seqr, .this_priority( 200 ) );
      overnight_order_seq.start( jb_env.jb_agent.jb_seqr, .this_priority( 300 ) );
    join
  endtask: main_phase
 
endclass: jelly_bean_test

UVM_SEQ_ARB_FIFO

This is the default arbitration mode and probably the easiest to understand. UVM sequencer grants sequences in FIFO order regardless of their priorities. When we run the test with this mode, we should see the sequences like this:

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE

We illustrated the request FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. At step 1, the UVM sequencer selected APPLE because it was located at the front of the FIFO.
    • When the APPLE was processed, it went out of the FIFO, but since we ordered four APPLE jelly-beans, another APPLE was put into the FIFO.
    • The UVM sequencer selected BLUEBERRY at step 2 because it was located at the front of the FIFO.
    • When the BLUEBERRY was processed, it went out of the FIFO. Since we ordered four BLUEBERRY jelly-beans, another BLUEBERRY was put into the FIFO.
    • The UVM sequencer selected BUBBLE_GUM at step 3 because it was located at the front of the FIFO.
  2. Similar arbitration continued until there was no more requests to process (steps 4 to 16).

Because of round robin nature of this mode, it won’t satisfy the customers who placed a priority order or an overnight order.

                                                                  How UVM_SEQ_ARB_FIFO works

UVM_SEQ_ARB_RANDOM

This mode should be also easy to understand. It randomly grants sequences in the FIFO regardless of their priorities. When we run the test with this mode, we should see the sequences like this:

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq BLUEBERRY
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 CHOCOLATE
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BUBBLE_GUM
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq BUBBLE_GUM
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq BUBBLE_GUM
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BUBBLE_GUM
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq BLUEBERRY
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq APPLE
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq BLUEBERRY
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 APPLE
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 CHOCOLATE
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 APPLE
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 CHOCOLATE
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE

We illustrated the request FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. At step 1, the UVM sequencer randomly selected BLUEBERRY.
    • When the BLUEBERRY was processed, it went out of the FIFO, but since we ordered four BLUEBERRY jelly-beans, another BLUEBERRY was put into the FIFO.
    • The UVM sequencer happened to select this BLUEBERRY at step 2, too.
    • When the second BLUEBERRY was processed, it went out of the FIFO. Since there were two more BLUEBERRY jelly-beans to process, another BLUEBERRY was put into the FIFO.
    • The UVM sequencer selected CHOCOLATE at step 3.
  2. Similar arbitration continued until there was no more requests to process (steps 4 to 16).

Because of random nature of this mode, it won’t satisfy the customers who placed a priority order or an overnight order, either.

How UVM_SEQ_ARB_RANDOM works

UVM_SEQ_ARB_STRICT_FIFO

This mode always grants the highest priority sequence. If more than one sequence has the same priority, the sequencer grants the one closest to the front of the FIFO. When we run the test with this mode, we should see the sequences like this:

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE

We illustrated the request FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. At step 1, the UVM sequencer selected CHOCOLATE because it was the highest priority request.
    • When the CHOCOLATE was processed, it went out of the FIFO, but since we ordered four CHOCOLATE jelly-beans, another CHOCOLATE was put into the FIFO.
    • The UVM sequencer selected this CHOCOLATE again at step 2 because it was the highest priority request.
    • When the second CHOCOLATE was processed, it went out of the FIFO. Since there were two more CHOCOLATE jelly-beans to process, another CHOCOLATE was put into the FIFO.
    • The UVM sequencer selected this CHOCOLATE again at step 3 because it was the highest priority request.
  2. After all CHOCOLATE requests (overnight order) were processed, the UVM sequencer went to the BLUEBERRY and BUBBLE_GUM requests (priority orders). Because both of them had the same priority, the UVM_SEQ_ARB_STRICT_FIFO mode selected the sequence closest to the front of the FIFO (steps 5 to 12).
  3. APPLE requests (standard order) were the lowest priority, so the UVM sequencer granted them last (steps 13 to 16).

This mode will satisfy the customers who placed a priority order or an overnight order.

                                                               How UVM_SEQ_ARB_STRICT_FIFO works

UVM_SEQ_ARB_STRICT_RANDOM

Similar to the UVM_SEQ_ARB_STRICT_FIFO mode, this mode grants the highest priority sequence. The difference is that when more than one sequence has the same priority, the sequencer selects a sequence randomly from the sequences that have the same priority. When we run the test with this mode, we should see the sequences like this:

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE

We illustrated the request FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. At step 1, the UVM sequencer selected CHOCOLATE because it was the highest priority request.
    • When the CHOCOLATE was processed, it went out of the FIFO, but since we ordered four CHOCOLATE jelly-beans, another CHOCOLATE was put into the FIFO.
    • The UVM sequencer selected this CHOCOLATE again at step 2 because it was the highest priority request.
    • When the second CHOCOLATE was processed, it went out of the FIFO. Since there were two more CHOCOLATE jelly-beans to process, another CHOCOLATE was put into the FIFO.
    • The UVM sequencer selected this CHOCOLATE again at step 3 because it was the highest priority request.
  2. After all CHOCOLATE requests (overnight order) were processed, the sequencer went to the BLUEBERRY and BUBBLE_GUM requests (priority orders). Because both of them had the same priority, the UVM_SEQ_ARB_STRICT_RANDOM mode selected the sequence randomly from the two. This is the only difference between the UVM_SEQ_ARB_STRICT_FIFO and UVM_SEQ_ARB_STRICT_RANDOM modes (steps 5 to 12).
  3. APPLE requests (standard order) were the lowest priority, so the UVM sequencer granted them last (steps 13 to 16).

This mode will satisfy the customers who placed a priority order or an overnight order.

                                                           How UVM_SEQ_ARB_STRICT_RANDOM works

UVM_SEQ_ARB_WEIGHTED

This is the most complicated and misleading mode in my opinion. The idea of this mode is that the higher priority sequences will get more chance to be granted. Here is how it works under the hood: This mode totals up the priority numbers in the request FIFO. Let’s say, the sum is 800. Then, it picks a random number between 0 and 799 (800 minus 1). Then, from the front of the FIFO, it accumulates the priority number each sequence has. When the accumulated number becomes more than the randomly selected number (threshold), that sequence is selected. OK, I know you are confused. Let’s see an example.

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE

We illustrated the request FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. Firstly, the UVM sequencer totalled up the priority numbers in the FIFO. In our case it was 800 (=100+200+200+300). Then, the sequencer picked a random number between 0 and 799 (=800-1). Let’s assume the random number was 219. We call this number a threshold. The sequencer looked at the front of the FIFO, which was APPLE and its priority number was 100. Since 100 was less than the threshold (219), the sequencer continued to look at the second entry of the FIFO. The second entry was BLUEBERRY and its priority number was 200. The accumulated priority number became 300, which was greater than the threshold, so the sequencer selected the BLUEBERRY at step 1.
    • When the BLUEBERRY was processed, it went out of the FIFO, but since we ordered four BLUEBERRY jelly-beans, another BLUEBERRY was put into the FIFO.
    • The UVM sequencer repeated the same procedure as the step 1. Firstly, it totalled up the priority numbers in the FIFO, which was 800. Let’s assume the random number the sequencer picked was 37 this time. Since the priority number of the first entry of the FIFO (100) was greater than 37, the sequencer selected APPLE at step 2.
    • When the APPLE was processed, it went out of the FIFO. Since there are three more APPLE jelly-beans to process, another APPLE was put into the FIFO.
    • The UVM sequencer used the same procedure and selected BUBBLE_GUM at step 3.
  2. Similar arbitration continued until there was no more orders to process (steps 4 to 16).

This mode will give more chance to be granted to the higher priority sequencers, but not as strict as UVM_SEQ_ARB_STRICT_FIFO or UVM_SEQ_ARB_STRICT_RANDOM.

                                                          How UVM_SEQ_ARB_WEIGHTED works

UVM_SEQ_ARB_USER

If none of the above modes satisfies your need, you can create your own arbitration scheme. To do that, you need to extend the uvm_sequencer class and define its user_priority_arbitration function. As an example, we created the arbitration scheme that always selects the second entry of the FIFO if it is available. This might be quite artificial, but I hope you get the idea.

class jelly_bean_sequencer extends uvm_sequencer#( jelly_bean_transaction );
  `uvm_component_utils( jelly_bean_sequencer )
 
  //----------------------------------------------------------------------------
  // Function: new
  //----------------------------------------------------------------------------
 
  function new( string name, uvm_component parent );
    super.new( name, parent );
  endfunction: new
 
  //----------------------------------------------------------------------------
  // Function: user_priority_arbitration
  //----------------------------------------------------------------------------
 
  virtual function integer user_priority_arbitration( integer avail_sequences[$] );
    if ( avail_sequences.size() >= 2 ) return avail_sequences[1]; // second entry of the request FIFO
    else                               return avail_sequences[0];
  endfunction: user_priority_arbitration
 
endclass: jelly_bean_sequencer

When we run the test with this mode, you should see the sequences like this:

# KERNEL: UVM_INFO @   0: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  15: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @  35: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @  55: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @  75: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @  95: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 115: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 135: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 155: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 175: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq1 BLUEBERRY
# KERNEL: UVM_INFO @ 195: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] priority_order_seq2 BUBBLE_GUM
# KERNEL: UVM_INFO @ 215: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr] overnight_order_seq CHOCOLATE
# KERNEL: UVM_INFO @ 235: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 255: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 275: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE
# KERNEL: UVM_INFO @ 295: uvm_test_top.jb_env.jb_agent.jb_drvr [jb_drvr]  standard_order_seq APPLE

We illustrated the arbitration FIFO in the UVM sequencer below. The numbers in parentheses are the priority numbers we specified when we started the sequences.

  1. The top-left shows the initial FIFO state just after we started the sequences. At step 1, the UVM sequencer selected BLUEBERRY because it was in the second entry of the FIFO.
    • When the BLUEBERRY was processed, it went out of the FIFO, but since we ordered four BLUEBERRY jelly-beans, another BLUEBERRY was put into the FIFO.
    • The UVM sequencer selected BUBBLE_GUM at step 2 because it was in the second entry of the FIFO.
    • When the BUBBLE_GUM was processed, it went out of the FIFO. Since we ordered four BUBBLE_GUM jelly-beans, another BUBBLE_GUM was put into the FIFO.
    • The UVM sequencer selected CHOCOLATE at step 3 because it was in the second entry of the FIFO.
  2. Similar arbitration continued until there was no more orders to process (steps 4 to 16).

                                                                 How UVM_SEQ_ARB_USER works

This was a long article, but I hope you understand the difference between the arbitration modes.

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页