1.覆盖率
覆盖率是衡量设计验证完备性的一个通用词语。覆盖率是伴随着仿真来收集的。
- 代码覆盖率
在编译时添加一些选项以监测代码的执行情况。包括行覆盖率、路径覆盖率、翻转覆盖率和状态机覆盖率。 - 断言覆盖率
– 使用SV的程序性代码可以实现等效性检查,但使用SVA(SV断言)进行表达更容易。
– 可以使用cover property
来测量所关心的信号值或者状态是否发生。 - 功能覆盖率
– 如果覆盖率稳定增长,则只需修改种子或者增加测试时间。
– 如果覆盖率增长放缓,则需要修改约束。
– 如果覆盖率停止增长且不足100%,则需考虑添加新的测试用例。
※ 注意关注的地方应该着眼于感兴趣的状态,而不是具体的数值;如果信号数量范围太大,则应该拆分为多个小范围再加上边界情况。
2.覆盖组 covergroup
- covergroup可以包含一个或多个coverpoint,且全都在同一时间采集。covergroup可以定义在类中,也可以定义在interface或者module中。一次定义后便可多次例化。
- 一个类里可以包含多个独立的covergroup,每个covergroup可以根据需要使能或者禁止。此外,covergroup可以定义单独的触发采样事件。
covergroup cover_ex;
coverpoint ex;
endgroup
cover_ex = new(); //例化方式一
//cover_ex ce = new(); //例化方式二
cover_ex.sample(); //触发方式一
// covergroup cover_ex @(xx); ... //触发方式二
3.数据采样
- coverpoint指定采样一个变量或表达式(也可以是跳转)时,sv会创建很多
bin
来记录每个数值被捕捉到的次数。bin的个数被称为域,覆盖率就是采样值的数目除以bin的数目。 - 如果采样变量的域范围过大,系统会默认分配64个bin,可通过covergroup中
option.auto_bin_max
选项指定自动创建bin的最大数目。
covergroup cover_ex;
coverpoint ex{
bins zero = {0};
bins med = {[1:3], 5};
bins hig[] = {[8:$]}; //8个bin代表8:15
bins misc = default; //1个bin代表剩余的所有值
} //注意没有分号
endgroup
- 可使用关键词
iff
给coverpoint添加条件,也可通过covergroup的start()
和stop()
函数来控制各个独立实例。
covergroup cover_ex;
coverpoint ex iff (!resnet);
endgroup
wildcard
关键字可以创建多个状态或者翻转,在表达式中任何?
,x
或者z
都会被视为0或1的通配符。
wildcard bins ex = {3'b??0};
ignore_bins
可排除不计算功能的域值;illegal_bins
出现还会报错。
4.交叉覆盖率
covergroup cover_ex;
t1: coverpoint test1;
t2: coverpoint test2;
cross t1, t2;
endgroup
- 同样可以在cross后添加
{}
排除部分cross bin或者进行更精细的指定
cross t1, t2 {
ignore_bins i1 = binsof(t1) intersect{0}; //排除
//bins = binsof(t1.a) && binsof(t2.a); //更精细的指定
//bins = binsof(t1) intersect{0} && binsof(t2) intersect{1};
}
5.覆盖选项
- 若需单独列出每个covergroup实例的覆盖率,则需设置覆盖选项
option.per_instance
,否则直接合并在一起了。 - 通过
option.comment
可以添加注释,这些注释最终会显示在覆盖率数据的总结报告中。 option.at_least
可以修改每个bin的数值最少的采样次数,如果低于at_least数值则不会被计入bin中。option.goal
可以设置低于100%的覆盖率目标。
※covergroup方法
sample()
采样。get_coverage()/get_inst_coverage()
获取覆盖率,返回0-100的real数值。set_inst_name(string)
设置covergroup的名称。start()/stop()
使能或者关闭覆盖率的收集。- 系统函数
$fet_coverage()
可以得到总体覆盖率。