14 Arbitration in sequencer(仲裁)

uvm_sequencer 有一个内置机制,可以在sequencer上同时运行的sequence中进行仲裁。基于仲裁算法,sequencer将得到仲裁权的sequence的sequence_item发送到driver。

14 Arbitration in sequencer(仲裁)_第1张图片

每个sequence发送的sequence_items也有自己的id来区别于其他sequence。

要设置特定的仲裁机制,请使用 set_ arbitration 函数,该函数在 uvm_sequencer_base 类中定义。

1. set_arbitration

它用于指定sequencer的仲裁模式或机制。

function void set_arbitration( UVM_SEQ_ARB_TYPE val )

 可以选择以下任意一种仲裁模式或算法。

例如:

.set_arbitration(UVM_SEQ_ARB_RANDOM);

2. Arbitration algorithms in uvm_sequencer

14 Arbitration in sequencer(仲裁)_第2张图片

3. get_arbitration

get_arbitration函数返回sequencer的当前仲裁模式或算法集。

function UVM_SEQ_ARB_TYPE get_arbitration()

4. user_priority_arbitration

当使用 set_ arbitration 函数将仲裁模式设置为 UVM_SEQ_ARB_USER 时,定序器将调用 user_priority_ arbtion 函数。用户定义的sequencr可以重写 user_priority_ arbitration 方法来实现自定义的仲裁策略。

virtual function integer user_priority_arbitration(integer avail_sequences[$])

5. Arbitration algorithms in uvm_sequencer examples

在以下示例中,sequence_item 使用 myseq 与driver通信。编写 base_test 是为了具有公共声明并创建一个对象(例如:env 类)。cfg_arb_mode 任务回调方法可用于派生测试来更新仲裁模式。定序器的每种仲裁模式都有一个单独的测试,要在 EDA 平台上执行,用户必须在运行选项中传递正确的测试名称 +UVM_TESTNAME =

class myseq extends uvm_sequence #(seq_item);
  seq_item req;
  `uvm_object_utils(myseq)
  
  function new (string name = "myseq");
    super.new(name);
  endfunction

  task body();
    `uvm_info(get_type_name(), "Inside body task", UVM_LOW);
    req = seq_item::type_id::create("req");
    wait_for_grant();
    assert(req.randomize());
    send_request(req);
    wait_for_item_done();
    `uvm_info(get_type_name(), "Completed body task", UVM_LOW);
  endtask
endclass

5.1 The base_test without any priority to the sequencer

class base_test extends uvm_test;
  env env_o;
  myseq seq[5];

  `uvm_component_utils(base_test)
  
  function new(string name = "base_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env_o = env::type_id::create("env_o", this);
  endfunction
  
  virtual task cfg_arb_mode;
  endtask
  
  task run_phase(uvm_phase phase);
    string s_name;
    super.run_phase(phase);
    phase.raise_objection(this);
    cfg_arb_mode();
    `uvm_info(get_name, $sformatf("Arbitration mode = %s", env_o.agt.seqr.get_arbitration()), UVM_LOW);
    foreach(seq[i]) begin
      automatic int j = i;
      fork
      begin
        s_name = $sformatf("seq[%0d]", j);
        seq[j] = myseq::type_id::create(s_name);    
        seq[j].start(env_o.agt.seqr);
      end
      join_none
    end
    wait fork;
    
    phase.drop_objection(this);
  endtask
endclass

5.2 The base_test with priority to the sequencer

class base_test extends uvm_test;
  env env_o;
  myseq seq[5];

  `uvm_component_utils(base_test)
  
  function new(string name = "base_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env_o = env::type_id::create("env_o", this);
  endfunction
  
  virtual task cfg_arb_mode;
  endtask
  
  task run_phase(uvm_phase phase);
    string s_name;
    super.run_phase(phase);
    phase.raise_objection(this);
    cfg_arb_mode();
    `uvm_info(get_name, $sformatf("Arbitration mode = %s", env_o.agt.seqr.get_arbitration()), UVM_LOW);
    foreach(seq[i]) begin
      automatic int j = i;
      fork
      begin
        s_name = $sformatf("seq[%0d]", j);
        seq[j] = myseq::type_id::create(s_name);    
        seq[j].start(env_o.agt.seqr, .this_priority((j+1)*100)); // priority is mentioned as 100, 200, 300, 400, 500 for j = 0,1,2,3,4
      end
      join_none
    end
    wait fork;
    
    phase.drop_objection(this);
  endtask
endclass

5.3 Output for different arbitration modes

5.3.1 Test = seq_arb_fifo_test.sv and arbitration mode = UVM_SEQ_ARB_FIFO

14 Arbitration in sequencer(仲裁)_第3张图片

5.3.2 Test = seq_arb_weighted_test.sv and arbitration mode = UVM_SEQ_ARB_WEIGHTED

14 Arbitration in sequencer(仲裁)_第4张图片

5.3.3 Test = seq_arb_random_test.sv and arbitration mode = UVM_SEQ_ARB_RANDOM

14 Arbitration in sequencer(仲裁)_第5张图片

5.3.4 Test = seq_arb_strict_fifo_test.sv and arbitration mode = UVM_SEQ_ARB_STRICT_FIFO

14 Arbitration in sequencer(仲裁)_第6张图片

5.3.5 Test = seq_arb_strict_random_test.sv and arbitration mode = UVM_SEQ_ARB_STRICT_RANDOM

14 Arbitration in sequencer(仲裁)_第7张图片

在上述log中可以注意到并观察到以下几点:

  1. 即使指定了优先级,UVM_SEQ_ARB_FIFO和UVM_SEAQ_ARB_RANDOM仲裁模式也不会修改sequence执行。
  2. 没有任何优先级的UVM_SEQ_ARB_STRICT_FIFO和UVM_SEAQ_ARB_FIFO模式提供相同的结果。
  3. UVM_SEQ_ARB_STRICT_FIFO模式结果根据优先级更改。
  4. 如果没有优先级,则UVM_SEQ_ARB_RANDOM和UVM_SEQ_ARB_STRICT_RANDOM提供相同的结果。

 

你可能感兴趣的:(UVM,vlsiverify_uvm)