文章目录
1. 覆盖率的类型
覆盖率是衡量设计验证完备性的一个通用词语
1.代码覆盖率
衡量设计实现的情况,工具自动帮你执行覆盖率收集。
主要包括一下几方面:
* 行覆盖率:多少行代码被执行过
* 路径覆盖率:在穿过代码和表达式的路径中有哪些已经被执行过
* 翻转覆盖率:哪些单位比特变量的值为0或1
* 状态机覆盖率:状态机哪些状态和状态转换已经被访问过
主要关注设计的覆盖率,测试代码不是主要;未经测试的代码里可能隐藏硬件漏洞,也可能是冗余的代码
2.断言覆盖率
断言是用于一次性的或者在一段时间对一个或多个设计信号在逻辑或者时序上的声明代码
可以使用cover property来测量这些关系的信号值或者状态是否发生变化
【漏洞率曲线】
每次漏洞率下降时,就应该寻找各种不同的方法去测量可能的边界情况
3.功能覆盖率
功能覆盖率是和设计意图紧密相连,衡量哪些设计特证已经被测试程序测试过的一个指标。
通过将每次仿真收集的覆盖率信息合并(前提是测试通过),分析覆盖率数据就可以决定如何修改递归测试集,
- 如果覆盖率稳步增长,那么就添加新种子或者加长测试时间;
- 如果覆盖率增速放缓,那么添加额外的约束来产生更多激励;
- 如果覆盖率停止增长,然而设计某些测试点没有被覆盖到(覆盖率不足100%),那么就创建新的测试;
- 如果覆盖率为100%但依然有新的设计漏洞,那么覆盖率可能没有覆盖到设计中某些设计功能区域;
2. 功能覆盖策略
1.收集信息而非数据
关注感兴趣的状态,而不是具体数值
2.只测量需要的内容
收集功能覆盖率数据的开销很大,所以只测量你会用来分析并且改进测试的那部分数据;
3.验证的完备性
目标:同时驱动高的代码覆盖率和高的功能覆盖率
- 如果代码覆盖率低但功能覆盖率高,说明验证计划不完整,测试没有执行设计的所有代码;
- 如果代码覆盖率高但功能覆盖率低,说明测试没有把设计定位到所有感兴趣的状态上,或者可能设计没有实现某功能;
3.覆盖组
- 覆盖组(covegroup)与类相似,可以多次例化;
- covegroup至少要有一个coverpoint,且全都在同一时间采集;
- covergroup可以定义在类中,也可以定义在接口或者module中;
- covergroup 必须要被例化才能采样数据
//采样方式一
covergroup Covport;
coverpoint port;
endgroup
Covport = new();
Covport cg1 = new();//推荐使用这种例化方式
cg1.sample();//采样
//采样方式二: 事件触发
event trans_ready;//定义事件
covergroup Covport@(trans_ready);//也可以用wait
coverpoint port;
endgroup
4.数据采样
-
coverpoint指定采样一个变量或者表达式,SV会创建很多“仓(bin)”来记录每个数值被捕捉到的次数;
-
bin是衡量功能覆盖率的基本单位;
-
计算coverpoint上的覆盖率,首先需要确定可能数值的个数,即域
覆盖率= 采样值的数据 / bin的数目
例如:一个3bit变量的域是7:0,正常情况下会自动分配8个bin。如果仿真过程中有7个值被采样到,那么最终的coverpoint的覆盖率就是7/8
-
所有coverpoint的覆盖率最终构成covergroup的覆盖率,所有covergroup的覆盖率最终构成整体的功能覆盖率;
1.bin的创建和应用
SV会默认为某个coverpoint创建bin,用户也可以自己定义bin的采样域(推荐自己定义)
如果采样变量的域范围过大而又没有指定bin,那么系统会默认分配一个64个bin,将值域范围平均分配给这64个bin
用户可以使用covergroup的选项auto_bin_max来指定自动创建bin的最大数目
covergroup Covport;
options.auto_bin_max = 8;//covergroup中的option
coverpoint tr.port{
//这个option会覆盖covergroup的设置
options.auto_bin_max = 2;//coverpoint中的option
}
endgroup
2.命名coverpoint和bin
covergroup Covport;
coverpoint port{
bins t1 = default;
}
endgroup
3.条件覆盖率
使用关键字 iff 给covergroup添加条件
使用start() 和stop()函数来控制covergroup各个实例
4.翻转覆盖率
covergroup Covport;
coverpoint port{
bins t1 = (0 => 1),(0 => 2) , (0 => 3) ;//满足其中任何一个,就会记录一次
}
endgroup
5.wildcard覆盖率
使用wildcard来创建多个状态或者翻转,在表达式中,任何x z 或者?都会被当成0或1 的通配符
wildcard bins even = {3'b??0};//偶数
wildcard bins odd = {3'b??1};//奇数
6.忽略的bin
有些coverpoint可能始终无法得到全部的域值,可以用 ignore_bins来排除不计算功能的域,最终这些值不会计入coverpoint的覆盖率
coverpoint port{
ignore_bins hi = {[6,7]};//忽略数值6~7
}
7.非法的bin
有些采样值不仅想要忽略,并且出现还应该报错,可以用 illegal_bins
coverpoint port{
illegal_bins hi = {[6,7]};//出现6~7就停止仿真,报错
}
8.交叉覆盖率
coverpoint是记录单个变量或者表达式的观测值
要想记录在某一时刻,多个变量之间值的组合情况,需要使用交叉(cross)覆盖率
class Transaction;
rand bit [3:0] kind;
rand bit [2:0] port;
endclass
transaction tr;
covergroup Covport;
kind : coverpoint tr.kind;
port : coverpoint tr.port;
cross kind,port;//交叉覆盖
endgroup
9.排除部分cross bin
通过使用ignore——bins、binsof 和 intersect分别指定coverpoint和值域,这样可以清楚很多不关心的cross bin
binsof指定覆盖点,intersect指定数值集
class Transaction;
rand bit [3:0] kind;
rand bit [2:0] port;
endclass
transaction tr;
covergroup Covport;
port : coverpoint tr.port {
bins port [] = {[0:$]};
}//注意没有分号
kind : coverpoint tr.kind{
bins zero ={0};
bins lo = {[1:3]};
bins hi[] = {[8:$]} ;//8个独立的仓,8,...,15
bins misc = default;
}
//交叉覆盖
cross kind,port{
//忽略port=7的情况
ignore_bins hi = binsof(port) intersect(7);
ignore_bins lo = binsof(kind.lo);
}
endgroup
【注意】如果cross a和b,假定a中有4个bin,b中有5个bin,cross之后一定有20个bin吗?
不一定。如果a中的bin没有将所有可能的值涵盖完,那么cross时,会自动添加这些值的bin。
5.覆盖选项
单个实例的覆盖率
如果一个covergroup被例化多次,默认情况下SV会将所有的实例的覆盖率合并到一起吗,如果需要单独列出每个covergroup实例的覆盖率,需要设置覆盖选项(option.per_instance)。
covergroup CoverLegth;
coverpoint tr.length;
option.per_instance = 1;//设置覆盖选项
endgroup
覆盖组注释
当有多个covergroup的实例时,可以通过设置option.cemment选项,来对每一个实例传入单独的注释,这些注释会显示在覆盖率的报告中。
covergroup CoverLegth(int hi,lo, string cemment);//传入cemment
option.cemment = cemment;//设置注释
option.per_instance = 1;
coverpoint port{
{bins range {[lo:hi]};
}
endgroup
...
Coverlength cp_lo = new(0,3,"Low port numbers");
Coverlength cp_lo = new(2,3,"Hign port numbers");
次数限定
默认情况下,数值采样次数1次就可以计入有效的bin
可以通过修改at_least来修改每个bin的数值最少采样的次数,如果低于at_least数值,则不会被计入bin;
-
at_least在covergroup中声明可以影响所有的coverpoint
-
at_least在coverpoint中声明仅仅影响所有的coverpoint中的bin
覆盖率目标
一般一个covergroup或者coverpoint的目标是100%覆盖率,比如通过option.goal = 90,设置一个新的目标
覆盖率权重
weight来设置覆盖率权重
type_option.weight = 0定义在coverpoint中,表示不关心这各coverpoint的覆盖率
6. covergroup常用的方法
-
sample() 采样
-
get_coverage() / get_inst_coverage() 获取该covergroup或者其某个实例的覆盖率,返回0-100的 real 数值
$get-coverage()是全局的,即将所有的covergroup加权后的覆盖率,返回值是实数(real)
-
set_inst_name(string) 设置covergroup的名称
-
start() / stop() 使能或者关闭覆盖率收集