(数字ic验证)从零开始的apb_watchdog验证模块搭建(五、功能覆盖率定义与覆盖率收集)文章目录
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
本章我们完成watchdog验证的最后一部分:覆盖率的定义与收集。
一、覆盖率的定义
1.covergroup的定义
覆盖率模块代码如下:
cov代码
`ifndef RKV_WATCHDOG_COV_SV
`define RKV_WATCHDOG_COV_SV
class rkv_watchdog_cov extends rkv_watchdog_subscriber;
bit [31:0] reg_control_val;
bit [31:0] reg_load_val;
event reg_control_acc_sv_e;
event reg_load_acc_sv_e;
`uvm_component_utils(rkv_watchdog_cov)
covergroup t1_watchdog_control_cg (ref bit[31:0] val) @(reg_control_acc_sv_e);
option.name = "T1 watchdog control coverage";
INTEN: coverpoint val[0] {
bins enable = {'b1};
bins dis = {'b0};
bins interrupt_enable = ('b0 => 'b1);
bins interrupt_disable = ('b1 => 'b0);
}
RESEN: coverpoint val[1] {
bins enable = {'b1};
bins dis = {'b0};
bins reset_enable = ('b0 => 'b1);
bins reset_disable = ('b1 => 'b0);
}
endgroup
covergroup t2_watchdog_load_cg (ref bit[31:0] val) @(reg_load_acc_sv_e);
option.name = "T2 watchdog load coverage";
LOAD: coverpoint val {
bins min = {'b1};
bins max = {'hffffffff};
bins mid = {[2:'hfffffffe]};
bins intialload = ('hffffffff => 'h????????);
bins reload = ([1:'hffffffff] => [1:'hffffffff]);
}
endgroup
covergroup t3_watchdog_int_clr_cg with function sample(bit[31:0] val, string feild);
option.name = "T3 watchdog interrupt clear coverage";
INTCLR: coverpoint val iff(feild == "INTCLR"){
bins clear_int = {'b1};
}
endgroup
covergroup t4_watchdog_lock_cg with function sample(bit[31:0] val, string feild);
option.name = "T4 watchdog lock coverage";
LOCK: coverpoint val iff(feild == "LOCK"){
bins lock_enable = {'b0};
bins lock_disble = {'b1};
bins lock_acc = {'h1acce551};
}
endgroup
function new (string name = "rkv_watchdog_cov", uvm_component parent);
super.new(name, parent);
t1_watchdog_control_cg = new(this.reg_control_val);
t2_watchdog_load_cg = new(this.reg_load_val);
t3_watchdog_int_clr_cg = new();
t4_watchdog_lock_cg = new();
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
vif = cfg.vif;
enable = cfg.enable_cov;
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
do_cover_events_check();
endtask
task do_cover_events_check();
uvm_object tmp;
uvm_reg r;
fork
begin
forever begin
fork
wdg_reg_fd_e.wait_trigger_data(tmp);
wdg_reg_fd_e.wait_trigger_data(tmp);
join_any
disable fork;
void'($cast(r, tmp));
#1ps; // get the updated value from predictor
if(r.get_name() == "WDOGCONTROL") begin
reg_control_val = rgm.WDOGCONTROL.get();
->reg_control_acc_sv_e;
end
else if(r.get_name() == "WDOGLOAD" ) begin
reg_load_val = rgm.WDOGLOAD.get();
->reg_load_acc_sv_e;
end
else if(r.get_name() == "WDOGINTCLR") begin
t3_watchdog_int_clr_cg.sample(rgm.WDOGINTCLR.get(), "INTCLR");
end
else if(r.get_name() == "WDOGLOCK") begin
t4_watchdog_lock_cg.sample(rgm.WDOGLOCK.get(), "LOCK");
end
end
end
join_none
endtask
endclass
`endif
这里对watchdog的功能划分为中断与复位使能,加载,中断清楚与上锁,并对这四种功能定义了各自的covergroup。对于覆盖率收集的触发,与之前scoreboard的方法类似,沿用subscriber中定义的事件,在事件触发后进行覆盖率的收集。一些covergroup采用事件触发收集,一些也采用function sample进行收集。
2.Makefile变化
Makefile代码
#############################
# User variables
#############################
TB = rkv_watchdog_tb
SEED = 1
GUI ?= 0
COV ?= 0
OUT ?= out
DOTCL ?= 1
TESTNAME ?= rkv_watchdog_integration_test
DFILES = ../../verilog/{cmsdk_apb_watchdog_frc.v,cmsdk_apb_watchdog.v}
VFILES += ../vip_lib/apb_pkg/apb_pkg.sv \
../vip_lib/apb_pkg/apb_if.sv \
../env/rkv_watchdog_pkg.sv \
../tb/rkv_watchdog_if.sv \
../tb/rkv_watchdog_tb.sv
#############################
# Environment variables
#############################
VCOMP_INC = +incdir+../../verilog \
+incdir+../vip_lib/apb_pkg \
+incdir+../{cfg,cov,reg,env,seq_lib,seq_lib/elem_seq_lib,test}
VCOMP = vlogan -full64 -ntb_opts uvm-1.2 -sverilog -timescale=1ps/1ps -nc -l $(OUT)/log/comp.log $(VCOMP_INC)
ELAB = vcs -full64 -ntb_opts uvm-1.2 -debug_acc+all -l $(OUT)/log/elab.log -sim_res=1ps
RUN = $(OUT)/obj/$(TB).simv -l run.log -sml +ntb_random_seed=$(SEED) +UVM_TESTNAME=$(TESTNAME) +UVM_NO_RELNOTES +UVM_VERBOSITY=$(VERB)
SIMRUNFILE = rkv_watchdog_sim_run.do
COV_OPTS = -full64 -dir $(CM_DIR)
CM_DIR ?= $(OUT)/cov.vdb
CM_NAME ?= $(TESTNAME)_$(SEED)
ifeq ($(GUI),1)
RUN += -gui
endif
ifeq ($(DOTCL),1)
RUN += -ucli -do $(SIMRUNFILE)
endif
ifeq ($(COV),1)
ELAB += -cm line+cond+fsm+tgl+branch+assert -cm_dir $(CM_DIR)
RUN += -cm line+cond+fsm+tgl+branch+assert -covg_cont_on_error
endif
prepare:
mkdir -p $(OUT)/work
mkdir -p $(OUT)/log
mkdir -p $(OUT)/sim
mkdir -p $(OUT)/obj
comp: prepare
$(VCOMP)
$(VCOMP) $(DFILES) $(VFILES)
elab: comp
$(ELAB) -top $(TB) -o $(OUT)/obj/$(TB).simv
run:
$(RUN)
mergecov:
urg -format both $(COV_OPTS)
dvecov:
dve $(COV_OPTS)
verdicov:
verdi -cov -covdir $(CM_DIR)
htmlcov:
firefox urgReport/dashboard.html
clean:
rm -rf $(OUT) 64 AN.DB DVEfiles csrc *.simv *.simv.daidir *.simv.vdb ucli.key
rm -rf *.log* *.vpd *.h urgReport
Makefile中增加了覆盖率收集模块,方便后期覆盖率收集操作。
二、覆盖率收集结果
运行不同test并对其进行覆盖率收集可得到如下结果:
在Verdi中查看对应的代码覆盖率与功能覆盖率结果,可知watchdog中功能覆盖率已经充分满足。
代码覆盖率并没有达到100%,对此也可以创建新的testcase来完善代码覆盖率。
总结
覆盖率收集完成之后,watchdog的验证也基本完成了。watchdog验证框图如下: