动态复位测试是必须要做的,至少在IP level是必须的,但是这个也是比较麻烦的,稍微一不小心就会引入若干问题:tb hang,design hang,checker误报,golden transaction 没有及时清掉导致SCB报错等等问题,本篇文章来介绍一套支持动态reset的uvm环境。
一. 先来看vseq部分,这部分比较单纯:
class my_dynamic_reset_vseq extends uvm_sequence;
//register
//new
task body();
for(int i=i;i<reset_cnt;i++) begin
fork
begin
my_seq.start();//业务vseq
end
begin
repeat($urandom_range(1000,10000)) @vif.cb;//正常跑业务的时间
force dut.reset_n=0;
#10ns;
release dut.reset_n;//reset done
p_sequencer.mst_sqr.stop_sequences();
p_sequencer.slv_sqr.stop_sequences();
my_seq.kill();
end
join_any
end
endtask
endclass
触发硬件复位之后,同时需要把所有seq停下来,然后再重启。本身这个vseq通过seq.kill来杀掉。
其他seq通过调用对应的sequencer.stop_sequences来实现:
二. agent部分,主要是driver和monitor,这部分之前的文章有提到:
driver:【UVM 参数化的VIP】- Driver_Bug_Killer_Master的博客-CSDN博客
monitor:【UVM 参数化的VIP】- Monitor & Sequencer_Bug_Killer_Master的博客-CSDN博客
三. refmodel和SCB部分
class my_ref extends uvm_component;
//register
//new
//build phase
task run_phase(uvm_phase phase);
forever begin
fork
begin
wait_for_reset();
reset_action();
end
begin
main_task();//forever run
end
disable fork;
join_any
end
endtask
task reset_action();
//disable checker
//clear golden item queue
//wait reset done
//open checker
endtask
endclass
四.其他注意事项
Q:reset的时候可能会遇到以下报错:
“Get_next_item called twice without item_done or get in between"
报错来自于sequencer,报错的原因是reset的时间点刚好在drive的get_next_item和item_done之间,导致get_next_item和item_done的个数不匹配,reset完driver启动起来再调get_next_item的时候就会报错
A:解决办法就是调用sqr.stop_sequences.
Q : reset状态机跳转不起来
A:需要在reset完成后统一把各个agent的状态跳回pre_reset。