方法一: 当前Case下发运行比对完,在下发下一次的Case,以此往复:
ic_tv_dir_trans cfg_dir_q[$];
virtual task body();
super.body();
vif.cfg_que_size_tmp=0; //等待Case运行完的标注
$value$plusargs("TB_PATH=%s",tb_path);
for(int j=0; j<`TB_NUM; j++) begin
wait(vif.cfg_que_size_tmp !=1);//wait case begin
if(!(std::randomize(case_id) with {case_id inside {[0:9999]};})) //从9999中随机挑选TB_NUM个Case
`uvm_error(get_type_name(),$sformatf("case_id rand fail"))
tv_true_path = {tb_path,$sformatf("/tv/Case%04d",case_id)}; //从tv目录中挑选名为case_id的Case
tv_proc.reset_for_std_alone(); //切换Case
void'(tv_proc.set_case_path(tv_true_path));
cfg_dir_q.delete();
void'(tv_proc.scan_directory_for_file('{get_trans.cfgfile0})); //加载配置文件
cfg_dir_q = tv_proc.get_dir_q(get_trans.cfgfile0);
for (int i=0; i<cfg_dir_q.size();i++) begin
***此处为下发配置和输入代码**
end
vif.cfg_que_size_tmp ++ ;//此处加1是为了等待rtl运行完当前下发的Case
@(posedge vif.clk iff (vif.输出中断));//等待输出中断做后续处理
***此处为输出中断处理代码***
vif.wait_clk(200);
vif.cfg_que_size_tmp -- ; //等到输出中断说明此Case运行结束,可以下发下一个Case的输入和配置
end
endtask : body
如上代码所述,该方式易于实现,比较符合常规的思路。但缺点也显而易见,在对应的scoreboard需要同步信号,实际验证过程中无法获得正确的同步信号,在case切换比对中可能会存在相应的问题,该方式只能实现单Case或者单模式Case的比对,无法实现多模式切换的Case比对。
方法二:
在平台运行的起始时刻将所有需要测试的Case准备好,Case准备与Case下发分开运行:
ic_tv_trans cfg_dir_q[$];
virtual task body();
super.body();
cfg_dir_q.delete();
$value$plusargs("TB_PATH=%s",tb_path);
//将所有要运行的Case放在out/Case0000中作为slot****运行
$system("rm ./out/Case0000 -rf");
$system("mkdir -p ./out/Case0000");
slot_num=0;
for(int j=0; j<`TB_NUM;j++) begin
tv_proc.reset_for_std_alone();//切换Case
if(!(std::randomize(case_id) with {case_id inside {[0000:9999]};}))
`uvm_error(get_type_name(),$sformatf("case_id rand fail"))
tv_true_path = {tb_path, $sformatf("/tv/Case%04d",case_id)};
void'(tv_proc.scan_directory_for_file('{get_trans.cfgfile0}));//获取Case配置路径
temp_dir_cfg_q = tv_proc.get_dir_q(get_trans.cfgfile0);
for (int slot_cnt = 0; slot_cnt < temp_dir_cfg_q.size(); slot_cnt++)begin
$system($sformatf("ln -s %s/cc0_frm0000_slot%04d ./out/Case0000/cc0_frm0000_slot%04d",tv_proc.get_case_path(),slot_cnt,slot_num));//将Case链接为out/Case0000中的slot****
slot_num++;
end
end
****以下代码为下发配置和输入****
endtask : body
从上述代码中可以看出,该方式的优势是不需要新增同步信号,可以将对输出中断的处理放入scoreboard中,便于多种模式切换的比对。