UVM糖果爱好者教程 - 26.sequence仲裁

我们的jelly-bean业务表现良好,因此我们同时开始接受多份jelly-bean订单。有些客户也要求加急运输。但如何优先处理请求?现在是了解序列仲裁的时候了。

今天的jelly-bean订单

假设我们今天收到了以下jelly-bean订单:

  • 标准订单 - 四颗APPLE果冻豆
  • 优先顺序 - 四个蓝莓果冻豆
  • 优先顺序 - 四个BUBBLE_GUM果冻豆
  • 隔夜订单 - 四颗巧克力果冻豆

在我们的jelly_bean_test中,我们创建了四个jelly_bean_order_sequence,每个对应一个jelly-bean订单(第39至42行)。然后,我们设置序列的优先级并同时启动它们以让序列发生器(sequencer)对它们进行仲裁。请注意,默认优先级为100,较高的数字表示优先级较高。在我们的例子中,我们将标准订单设置为100,优先顺序为200,隔夜订单为300(第62至65行)。

UVM定序器有六种仲裁模式:

  • UVM_SEQ_ARB_FIFO(默认)
  • UVM_SEQ_ARB_RANDOM
  • UVM_SEQ_ARB_STRICT_FIFO
  • UVM_SEQ_ARB_STRICT_RANDOM
  • UVM_SEQ_ARB_WEIGHTED
  • UVM_SEQ_ARB_USER

uvm_sequencer_base类的set_arbitration函数指定使用哪种模式(第54至59行)。让我们一个一个地看看每种模式。

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

这是默认的仲裁模式,可能是最容易理解的。 UVM序列器按先进先出顺序授予序列,而不管其优先级如何。当我们用这种模式运行测试时,我们应该看到这样的序列:

# 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

我们在下面的UVM sequencer说明了请求FIFO。括号中的数字是我们在启动序列时指定的优先级数字。

  1. 左上角显示刚开始序列后的初始FIFO状态。在步骤1中,UVM定序器选择了APPLE,因为它位于FIFO的前面。
  2. 当APPLE处理完毕后,它就离开了FIFO,但由于我们订购了四个APPLE jelly-bean,另一个APPLE被放入了FIFO。UVM sequencer在步骤2中选择了BLUEBERRY,因为它位于FIFO的前面。
  3. 当BLUEBERRY被处理时,它就离开了FIFO。由于我们订购了四款蓝莓jelly-bean,另一款蓝莓则被放入FIFO。UVM sequencer在步骤3选择了BUBBLE_GUM,因为它位于FIFO的前面。
  4. 类似的仲裁一直持续到没有更多的处理请求(步骤4到16)。

由于这种模式的循环性质,它不会满足放置优先订单或隔夜订单的客户。


                                                                       UVM_SEQ_ARB_FIFO是如何工作的

UVM_SEQ_ARB_RANDOM

这种模式应该也很容易理解。 它随机授予FIFO中的序列,而不管它们的优先级如何。 当我们用这种仿真运行测试时,我们应该看到这样的序列:

# 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

我们在下面的UVM定序器中说明了请求FIFO。括号中的数字是我们在启动序列时指定的优先级数字。

  1. 左上角显示刚开始序列后的初始FIFO状态。在步骤1中,UVM sequencer随机选择BLUEBERRY。
  2. 当BLUEBERRY被处理后,它就退出了FIFO,但是由于我们订购了四个BLUEBERRY果冻豆,另一个BLUEBERRY被放入了FIFO。在步骤2中,UVM sequencer恰巧也选择了这个BLUEBERRY。
  3. 当第二个蓝莓被处理时,它就离开了FIFO。由于还有两块蓝莓果冻豆要加工,另一块蓝莓放入FIFO。在步骤3中,UVM sequencer选择CHOCOLATE。
  4. 类似的仲裁一直持续到没有更多的处理请求(步骤4到16)。

由于这种模式的随机性,它不会满足放置优先顺序或隔夜订单的客户。


                                                                            UVM_SEQ_ARB_RANDOM是如何工作的

UVM_SEQ_ARB_STRICT_FIFO

该模式始终授予最高优先级的序列。如果多个序列具有相同的优先级,则sequencer授予距离FIFO前端最近的序列。当我们用这种模式运行测试时,我们应该看到这样的序列:

# 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

我们在下面的UVM sequencer中说明了请求FIFO。括号中的数字是我们在启动序列时指定的优先级数字。

  1. 左上角显示刚开始序列后的初始FIFO状态。在步骤1中,UVM sequencer选择了CHOCOLATE,因为它是最高优先级的请求。
  2. 当巧克力被加工后,它就离开了fifo,但由于我们订购了四颗巧克力果冻豆,另一颗巧克力被放入了先进先出法。UVM序列器在步骤2中再次选择了此巧克力,因为它是最高优先级的请求。
  3. 当第二个CHOCOLATE被处理时,它就离开了FIFO。由于有两颗巧克力果冻豆需要加工,另一颗巧克力被放入FIFO中。UVM sequencer在步骤3再次选择了该巧克力,因为它是最高优先级的请求。
  4. 在处理完所有CHOCOLATE请求(隔夜订单)后,UVM sequencer进入BLUEBERRY和BUBBLE_GUM请求(优先顺序)。因为它们都具有相同的优先级,所以UVM_SEQ_ARB_STRICT_FIFO模式选择最接近FIFO前面的序列(步骤5到12)。
  5. APPLE请求(标准顺序)是最低优先级,所以UVM sequencer将它们授予最后(步骤13到16)。
这种模式将满足优先订单或隔夜订单的客户。

                                                                    UVM_SEQ_ARB_STRICT_FIFO 是如何工作的

UVM_SEQ_ARB_STRICT_RANDOM

类似于UVM_SEQ_ARB_STRICT_FIFO模式,该模式授予最高优先级序列。不同的是,当多个序列具有相同的优先级时,序列发生器从具有相同优先级的序列中随机选择一个序列。当我们用这种模式运行测试时,我们应该看到这样的序列:

# 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

我们在下面的UVM sequencer中说明了请求FIFO。括号中的数字是我们在启动序列时指定的优先级数字。

  1. 左上角显示刚开始序列后的初始FIFO状态。在步骤1中,UVM sequencer选择了CHOCOLATE,因为它是最高优先级的请求。
  2. 当巧克力被加工后,它就离开了FIFO,但由于我们订购了四颗巧克力果冻豆,另一颗巧克力被放入了FIFO。UVM sequencer在步骤2中再次选择了此巧克力,因为它是最高优先级的请求。
  3. 当第二个CHOCOLATE被处理时,它就离开了FIFO。由于有两颗巧克力果冻豆需要加工,另一颗巧克力被放入先进先出物中。UVM sequencer在步骤3再次选择了该巧克力,因为它是最高优先级的请求。
  4. 在处理完所有CHOCOLATE请求(隔夜订单)后, sequencer进入BLUEBERRY和BUBBLE_GUM请求(优先顺序)。因为它们都具有相同的优先级,所以UVM_SEQ_ARB_STRICT_RANDOM模式从这两个模式中随机选择序列。这是UVM_SEQ_ARB_STRICT_FIFO和UVM_SEQ_ARB_STRICT_RANDOM模式(步骤5至12)之间的唯一区别。
  5. APPLE请求(标准顺序)是最低优先级,所以UVM sequencer将它们授予最后(步骤13到16)。

这种模式将满足优先订单或隔夜订单的客户。


                                                        UVM_SEQ_ARB_STRICT_RANDOM 是如何工作的

UVM_SEQ_ARB_WEIGHTED

在我看来,这是最复杂和最令人费解的模式。这种模式的想法是,更高优先级的序列将有更多机会被授予。下面是它如何工作的原因:这种模式总结了请求FIFO中的优先级数字。比方说,总和是800.然后,它会选取0到799之间的一个随机数(800减1)。然后,从FIFO的前面,它累积每个序列具有的优先级编号。当累计数量大于随机选择的数量(阈值)时,选择该序列。好的,我知道你很困惑。我们来看一个例子。

# 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
我们在下面的UVM定序器中说明了请求FIFO。括号中的数字是我们在启动序列时指定的优先级数字。
  1. 左上角显示刚开始序列后的初始FIFO状态。首先,UVM sequencer将FIFO中的优先级数字累加起来。在我们的例子中,它是800(= 100 + 200 + 200 + 300)。然后,sequencer选取0到799之间的一个随机数(= 800-1)。我们假设随机数是219.我们称这个数字为一个阈值。sequencer查看FIFO的前端,它是APPLE,其优先级数字是100.由于100小于阈值(219),sequencer继续查看FIFO的第二个入口。第二项是BLUEBERRY,其优先级编号为200.累计优先级编号为300,大于阈值,因此sequencer在步骤1中选择了BLUEBERRY。
  2. 当BLUEBERRY被处理后,它就退出了FIFO,但是由于我们订购了四个BLUEBERRY果冻豆,另一个BLUEBERRY被放入了FIFO。UVM sequencer重复与步骤1相同的过程。首先,它将FIFO中的优先级数字合计为800.假设这次选择的sequencer的随机数为37。由于FIFO(100)的第一个条目的优先级数大于37,因此sequencer在步骤2选择APPLE。
  3. 当APPLE被处理时,它就离开了FIFO。由于还有三个APPLE果冻豆要处理,另一个APPLE被放入FIFO。UVM sequencer在步骤3中使用相同的步骤并选择BUBBLE_GUM。
  4. 类似的仲裁一直持续到没有更多的订单要处理(步骤4到16)。

该模式将给予更高优先级的sequence更多的机会,但不会像UVM_SEQ_ARB_STRICT_FIFO或UVM_SEQ_ARB_STRICT_RANDOM那样严格。


                                                            UVM_SEQ_ARB_WEIGHTED 是如何工作的

UVM_SEQ_ARB_USER

如果上述模式都不能满足您的需要,您可以创建自己的仲裁方案。为此,您需要扩展uvm_sequencer类并定义其user_priority_arbitration函数。作为一个例子,我们创建了仲裁方案,如果可用,它总是选择FIFO的第二个条目。这可能很人造,但我希望你明白。

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

当我们用这种模式运行测试时,您应该看到如下所示的序列:

# 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
我们在下面的UVM sequencer中说明了仲裁FIFO。括号中的数字是我们在启动序列时指定的优先级数字。

  1. 左上角显示刚开始序列后的初始FIFO状态。在步骤1中,UVM sequencer选择了BLUEBERRY,因为它位于FIFO的第二个条目中。
  2. 当BLUEBERRY被处理后,它就退出了FIFO,但是由于我们订购了四个BLUEBERRY果冻豆,另一个BLUEBERRY被放入了FIFO。UVM sequencer在步骤2中选择了BUBBLE_GUM,因为它位于FIFO的第二个条目中。
  3. 当BUBBLE_GUM被处理后,它就离开了FIFO。由于我们订购了四个BUBBLE_GUM果冻豆,另一个BUBBLE_GUM被放入FIFO。UVM sequencer在步骤3选择了CHOCOLATE,因为它位于FIFO的第二个条目中。
  4. 类似的仲裁一直持续到没有更多的订单要处理(步骤4到16)。

                                                                        UVM_SEQ_ARB_USER 是如何工作的

这是一篇很长的文章,但我希望你了解仲裁模式之间的差异。


您可以在EDA Playground上查看并运行代码。

猜你喜欢

转载自blog.csdn.net/zhajio/article/details/80799213