|
发表于 2016-3-27 19:26:15
|
显示全部楼层
本帖最后由 lazioprocn 于 2016-3-27 21:37 编辑
我发现一个uvm1.2的似疑的bug,想讨论下。简单的说,如果lock_list里面有两个不同的sequence,则一定会卡死掉。
例如如果三个sequence fork join 同时发到一个sequencer,其中第2第3个为lock的. 那么当第一个sequence 发完,而 driver 继续第二次 get_next_item() 由于所有的sequence 都得不到裁决一直等 会导致整个验证平台死掉。
具体为sequence1没有lock().那么等sequence1发送完毕,grant_queued_lockes()将sequence2,sequence3,lock()的sequence2,sequence3添加到lock_list中去。当driver调用m_choose_next_request时,判断is_blocked(arb_sequence_q.sequence_ptr ==0) 后才能return arb_sequence_q三个中间的一个index.而在 uvm_sequencer_base.svh 里面的 is_blocked()函数是这样写的:
// is_blocked
// ----------
function bit uvm_sequencer_base::is_blocked(uvm_sequence_base sequence_ptr);
if (sequence_ptr == null)
uvm_report_fatal("uvm_sequence_controller",
"is_blocked passed null sequence_ptr", UVM_NONE);
foreach (lock_list) begin
if ((lock_list.get_inst_id() !=
sequence_ptr.get_inst_id()) &&
(is_child(lock_list, sequence_ptr) == 0)) begin
return 1;
end
end
return 0;
endfunction
很显然,这时 lock_list 里面有 sequence2,sequence3, 而三个sequence 进去均会返回1,因为它判断两个 lock_list 只要有一个不等返回1,每个sequence要与所有的两个不同的 lock_list 相等才返回0,显然是不可能为0的。我认为可以这么改:
function bit uvm_sequencer_base::is_blocked(uvm_sequence_base sequence_ptr);
if (sequence_ptr == null)
uvm_report_fatal("uvm_sequence_controller",
"is_blocked passed null sequence_ptr", UVM_NONE);
foreach (lock_list) begin
if ((lock_list.get_inst_id() !=
sequence_ptr.get_inst_id()) &&
(is_child(lock_list, sequence_ptr) == 0)) begin
end
else
return 0;
end
if(lock_list.size())
return 1;
else
return 0;
endfunction
也就是说当有 lock_list 有东西时,当 sequence 在 lock_list 里面,返回0,当判断完均不在 lock_list 里面才返回1. |
|