admin管理员组

文章数量:1648544

今日调试reset test时,出现了如下UVM_ERROR:

[SEQREQZMB] The task responsible for requesting a wait_for_grant on
sequencer ‘uvm_test_top.m_env.m_xxx_agent.m_sequencer’ for sequence
‘case_rstn_rand_vseq’ has been killed, to avoid a deadlock the
sequence will be removed from the arbitration queues.

在网上搜索了该ERROR的信息,发现均与将sequence强行停止有关,但并没有特别契合我的案例,总之依旧未能够找到合适的解决方法。经过自己的摸索后,解决了这个问题,因此将该过程记录下来,以便之后再遇能够快速解决。如果恰好能帮上你的忙,那将是意外收获!

出现的原因

  1. 出现error首先应当查看原代码,因此我读了一下UVM源码中该error的出处:
function int uvm_sequencer_base::m_choose_next_request();
  int i, temp;
  int avail_sequence_count;
  int sum_priority_val;
  integer avail_sequences[$];
  integer highest_sequences[$];
  int highest_pri;
  string  s;
 
  avail_sequence_count = 0;
 
  grant_queued_locks();
 
  for (i = 0; i < arb_sequence_q.size(); i++) begin
 
    if((arb_sequence_q[i].process_id.status == process::KILLED)||
       (arb_sequence_q[i].process_id.status == process::FINISHED))begin
      `uvm_error("SEQREQZMB",$sformatf("The task reponsible for requesting a wait_for_grant on sequencer '%s' for sequence '%s' has been killed,to avoid a deadlock the sequence will be removed from the arbitration queues",this,get_full_name(),arb_sequence_q[i].sequence_ptr.get_full_name))
     
      remove_sequence_from_queues(arb_sequence_q[i].sequence_ptr);
      continue;
    end
    
    //the rest content is omitted
    ...
    
endfunction

该function后续代码由于与本文讨论的问题无关,因此省略。从代码中可见,这个UVM_ERROR是由于arb_sequence_q的成员status为KILLED或FINISHED,为了避免死锁deadlock的产生,强行将该成员从queue中移除。

继续往前追溯,m_choose_next_request()这个函数在task m_select_sequence中被调用,而这个task又被task get_next_item所调用。

看到这里,问题的原因已经比较清晰:

  1. 我的case所定义的item,会进入sequencer的一个仲裁队列中。sequencer在driver要求get_next_item时,对队列中的request进行仲裁,再将request item发送给driver。
  2. 仲裁队列中的item,在reset生效时被kill掉,从而满足了该ERROR的条件。当reset释放时,driver重新要求get_next_item就会引发该UVM_ERROR。

解决的方法

sequencer在发现该ERROR后,采取了remove_sequence_from_queues的做法,将KILLED状态的item从队列中清除掉。

那么,我是否可以在reset生效后,就将队列中的item人为清除掉,从而避免该UVM_ERROR的产生呢?

于是,查看UVM sequencer的源码,其提供了如下的方法:

// Function- stop_sequences
//
// Tells the sequencer to kill all sequences and child sequences currently
// operating on the sequencer, and remove all requests, locks and responses
// that are currently queued.  This essentially resets the sequencer to an
// idle state.
//
function void uvm_sequencer::stop_sequences();
  REQ t;
  super.stop_sequences();
  sequence_item_requested  = 0;
  get_next_item_called     = 0;
  // Empty the request fifo
  if (m_req_fifo.used()) begin
    uvm_report_info(get_full_name(), "Sequences stopped.  Removing request from sequencer fifo");
    while (m_req_fifo.try_get(t));
  end
endfunction

这个方法可以同时完成将sequences kill掉并从队列中remove的行为。

的确,这样做之后这个UVM_ERROR不再出现了。

本文标签: 解决方法原因ResetSEQREQZMBUVMERROR